Arma Reforger Explorer  1.1.0.42
Arma Reforger Code Explorer by Zeroy - Thanks to MisterOutofTime
SCR_ServerConfigListComponent.c
Go to the documentation of this file.
1 
6 {
7  [Attribute("{7E4D962E3084CD77}Configs/ServerBrowser/ServerHosting/Dialogs/ServerConfigDialogs.conf", UIWidgets.ResourceAssignArray)]
8  protected ResourceName m_sDialogs;
9 
10  protected const string NAME_ENTRY = "name";
11  protected const string FILE_NAME_ENTRY = "fileName";
12  protected const string SCENARIO_SELECTION_ENTRY = "scenarioId";
13  protected const string SCENARIO_MOD_SELECTION_ENTRY = "scenarioModId";
14  protected const string PLAYER_LIMIT_ENTRY = "maxPlayers";
15  protected const string BATTLEYE = "battlEye";
16  protected const string CROSSPLAY = "crossPlatform";
17  protected const string SIMPLE_PORT = "publicPortSimple";
18 
19  // Properties content
20  protected const string SERVER_NAME_BASE = "%1 %2";
21  protected const string FILE_NAME_BASE = "Config_%1";
22  protected const string DEFAULT_SCENARIO = "{ECC61978EDCC2B5A}Missions/23_Campaign.conf";
23 
24  protected SCR_WidgetListEntryEditBox m_NameEdit;
25  protected SCR_WidgetListEntryEditBox m_SimplePortEdit;
26  protected SCR_WidgetListEntrySelection m_ScenarioSelect;
27  protected SCR_WidgetListEntrySelection m_ScenarioModSelect;
28  protected SCR_WidgetListEntrySelection m_BattleyeSelect;
29  protected SCR_WidgetListEntrySelection m_CrossplaySelect;
30 
31  protected SCR_WidgetListEntrySlider m_PlayerListSlider;
32 
33  protected bool m_bNameEdited;
34  protected bool m_bFileNameEdited;
35 
36  // Mod + scenarios that mod is overriding
37  protected ref array<ref SCR_ScenarioSources> m_aScenarioSources = {};
38 
39  // Invokers
40  protected ref ScriptInvoker<string> m_OnScenarioSelected;
41  protected ref ScriptInvoker<string> m_OnPortChanged;
42 
43  //------------------------------------------------------------------------------------------------
44  protected void InvokeOnScenarioSelected(string itemId)
45  {
46  if (m_OnScenarioSelected)
47  m_OnScenarioSelected.Invoke(itemId);
48  }
49 
50  //------------------------------------------------------------------------------------------------
51  ScriptInvoker GetOnScenarioSelected()
52  {
53  if (!m_OnScenarioSelected)
54  m_OnScenarioSelected = new ScriptInvoker();
55 
56  return m_OnScenarioSelected;
57  }
58 
59  //------------------------------------------------------------------------------------------------
60  ScriptInvoker GetOnPortChanged()
61  {
62  if (!m_OnPortChanged)
63  m_OnPortChanged = new ScriptInvoker();
64 
65  return m_OnPortChanged;
66  }
67 
68  //-------------------------------------------------------------------------------------------
69  // Overridden widget API
70  //-------------------------------------------------------------------------------------------
71 
72  //-------------------------------------------------------------------------------------------
73  override void HandlerAttached(Widget w)
74  {
75  super.HandlerAttached(w);
76 
77  if (GetGame().InPlayMode())
78  FillScenarios();
79 
80  m_wScrollWidget = ScrollLayoutWidget.Cast(w);
81  }
82 
83  //-------------------------------------------------------------------------------------------
84  // Protected
85  //-------------------------------------------------------------------------------------------
86 
87  //-------------------------------------------------------------------------------------------
89  protected void FillScenarios()
90  {
91  // Find widgets
92  m_NameEdit = SCR_WidgetListEntryEditBox.Cast(FindEntry(NAME_ENTRY));
93 
94  m_SimplePortEdit = SCR_WidgetListEntryEditBox.Cast(FindEntry(SIMPLE_PORT));
95 
96  m_ScenarioSelect = SCR_WidgetListEntrySelection.Cast(FindEntry(SCENARIO_SELECTION_ENTRY));
97 
98  m_ScenarioModSelect = SCR_WidgetListEntrySelection.Cast(FindEntry(SCENARIO_MOD_SELECTION_ENTRY));
99 
100  m_PlayerListSlider = SCR_WidgetListEntrySlider.Cast(FindEntry(PLAYER_LIMIT_ENTRY));
101 
102  m_BattleyeSelect = SCR_WidgetListEntrySelection.Cast(FindEntry(BATTLEYE));
103 
104  m_CrossplaySelect = SCR_WidgetListEntrySelection.Cast(FindEntry(CROSSPLAY));
105 
106  // Setup names
107  if (m_NameEdit)
108  m_NameEdit.GetEditBoxComponent().m_OnChanged.Insert(OnNameChanged);
109 
110  // Simple port
111  if (m_SimplePortEdit)
112  m_SimplePortEdit.GetEditBoxComponent().m_OnChanged.Insert(OnSimplePortChanged);
113 
114  // Scenarios
115  if (!m_ScenarioSelect)
116  return;
117 
118  // Fill scenario sources
119  FillScenarioSources();
120 
121  // Fill scenario options
122  array<ref SCR_LocalizedProperty> options = {};
123 
124  for (int i = 0, count = m_aScenarioSources.Count(); i < count; i++)
125  {
126  MissionWorkshopItem scenario = m_aScenarioSources[i].m_Scenario;
127  if (!scenario)
128  return;
129 
130  SCR_LocalizedProperty scenarioOption = new SCR_LocalizedProperty(scenario.Name(), scenario.Id());
131  options.Insert(scenarioOption);
132  }
133 
134  m_ScenarioSelect.SetOptions(options);
135 
136  // Callback
137  m_ScenarioSelect.GetSelectionComponent().m_OnChanged.Insert(OnSelectScenario);
138 
139  // Select default scenario
140  int defaultId = SetSelectedScenarioById(DEFAULT_SCENARIO);
141  m_ScenarioSelect.SelectOption(defaultId);
142  OnSelectScenario(null, defaultId);
143 
144  // Platform specific setup
145  ConsoleSetup();
146  }
147 
148  //-------------------------------------------------------------------------------------------
149  protected void FillScenarioSources()
150  {
151  // Get all scenarios
152  array<MissionWorkshopItem> allMissions = {};
153  GetGame().GetBackendApi().GetWorkshop().GetPageScenarios(allMissions, 0, 4096);
154 
155  // Filter scenarios
156  array<MissionWorkshopItem> missions = {};
157 
158  for (int i = 0, count = allMissions.Count(); i < count; i++)
159  {
160  // Exclude single player
161  if (allMissions[i].GetPlayerCount() == 1)
162  continue;
163 
164  // Check scenario from mod and modded scenario
165  WorkshopItem scenarioAddon = allMissions[i].GetOwner();
166  if (scenarioAddon)
167  {
168  // Exclude scenarios comming from incompatible addon
169  if (SCR_AddonManager.ItemAvailability(scenarioAddon) != SCR_ERevisionAvailability.ERA_AVAILABLE)
170  continue;
171  }
172 
173  // Exclude broken mod scenarios
174  if (allMissions[i].GetOwner())
175  {
176  SCR_WorkshopItem item = SCR_AddonManager.GetInstance().Register(allMissions[i].GetOwner());
177 
178  if (item && item.GetAnyDependencyMissing() || item.GetCorrupted())
179  continue;
180  }
181 
182  missions.Insert(allMissions[i]);
183  }
184 
185  // Order scenarios
186  SCR_Sorting<MissionWorkshopItem, SCR_CompareMissionName>.HeapSort(missions);
187 
188  // Add scenarios and sorces to map
189  for (int i = 0, count = missions.Count(); i < count; i++)
190  {
191  InsertScenarioToMap(missions[i], missions[i].GetOwner());
192  }
193  }
194 
195  //------------------------------------------------------------------------------------------------
198  protected void InsertScenarioToMap(MissionWorkshopItem scenario, WorkshopItem modOwner)
199  {
200  // Scenario map structure - key: scenario (SCR_LocalizedProperty), value: sources (array SCR_LocalizedProperty)
201 
202  // Scenario id is in map - there stil could be repeating names
203  int scenarioIndex = -1;
204 
205  for (int i = 0, count = m_aScenarioSources.Count(); i < count; i++)
206  {
207  MissionWorkshopItem mission = m_aScenarioSources[i].m_Scenario;
208 
209  // Scenario structure - label: name, propertyName: id
210  if (mission && scenario.Id() == mission.Id())
211  {
212  //scenario = m_aScenarioSources[i].m_Scenario;
213  scenarioIndex = i;
214  break;
215  }
216  }
217 
218  // Scenario is in map
219  if (scenarioIndex != -1)
220  {
221  // Add source to existing scenario
222  m_aScenarioSources[scenarioIndex].m_aMods.Insert(modOwner);
223  }
224  else
225  {
226  // Add new
227  m_aScenarioSources.Insert(new SCR_ScenarioSources(scenario, {modOwner}));
228  }
229  }
230 
231  //-------------------------------------------------------------------------------------------
233  protected int SetSelectedScenarioById(string scenarioId)
234  {
235  array<ref SCR_LocalizedProperty> scenarios = {};
236  m_ScenarioSelect.GetOptions(scenarios);
237 
238  for (int i = 0, count = m_aScenarioSources.Count(); i < count; i++)
239  {
240  // Property name = scenario id
241  if (scenarios[i].m_sPropertyName == scenarioId)
242  {
243  return i;
244  }
245  }
246 
247  // Fallback
248  return 0;
249  }
250 
251  //-------------------------------------------------------------------------------------------
253  protected void ConsoleSetup()
254  {
255  // Check platform
257  return;
258 
259  // Default values
260  m_BattleyeSelect.SetValue("0");
261  m_CrossplaySelect.SetValue("1");
262 
263  // Hide limited on consoles
264  m_BattleyeSelect.GetEntryRoot().SetVisible(false);
265  m_CrossplaySelect.GetEntryRoot().SetVisible(false);
266  }
267 
268  //-------------------------------------------------------------------------------------------
269  // Public
270  //-------------------------------------------------------------------------------------------
271 
272  //-------------------------------------------------------------------------------------------
273  void SelectScenario(notnull MissionWorkshopItem scenario)
274  {
275  array<MissionWorkshopItem> missionItemsAll = new array<MissionWorkshopItem>;
276  GetGame().GetBackendApi().GetWorkshop().GetPageScenarios(missionItemsAll, 0, 4096);
277 
278  if (m_ScenarioSelect)
279  {
280  int selected = SetSelectedScenarioById(scenario.Id());
281 
282  m_ScenarioSelect.SelectOption(selected);
283  OnSelectScenario(SCR_ComboBoxComponent.Cast(m_ScenarioSelect.GetSelectionComponent()), selected);
284  }
285  }
286 
287  //-------------------------------------------------------------------------------------------
288  MissionWorkshopItem GetSelectedScenario()
289  {
290  if (!m_ScenarioSelect)
291  return null;
292 
293  array<MissionWorkshopItem> missionItemsAll = new array<MissionWorkshopItem>;
294  GetGame().GetBackendApi().GetWorkshop().GetPageScenarios(missionItemsAll, 0, 4096);
295 
296  for (int i = 0, count = missionItemsAll.Count(); i < count; i++)
297  {
298  SCR_LocalizedProperty selected = m_ScenarioSelect.GetSelectedOption();
299  string name = selected.m_sPropertyName;
300 
301  if (missionItemsAll[i].Id() == name)
302  {
303  return missionItemsAll[i];
304  }
305  }
306 
307  return null;
308  }
309 
310  //-------------------------------------------------------------------------------------------
312  WorkshopItem GetScenarioOwnerMod()
313  {
314  if (!m_ScenarioSelect)
315  return null;
316 
317  array<MissionWorkshopItem> missionItemsAll = new array<MissionWorkshopItem>;
318  GetGame().GetBackendApi().GetWorkshop().GetPageScenarios(missionItemsAll, 0, 4096);
319 
320  // Check current selection
321  SCR_LocalizedProperty property = m_ScenarioModSelect.GetSelectedOption();
322 
323  if (!property)
324  return null;
325 
326  // Select owner mod
327  for (int i = 0, count = missionItemsAll.Count(); i < count; i++)
328  {
329  WorkshopItem ownerItem = missionItemsAll[i].GetOwner();
330  if (!ownerItem)
331  continue;
332 
333  if (ownerItem.Id() == property.m_sPropertyName)
334  {
335  return ownerItem;
336  }
337  }
338 
339  return null;
340  }
341 
342  //-------------------------------------------------------------------------------------------
344  void FillFromDSConfig(notnull SCR_DSConfig config)
345  {
346  // Game
347  FindEntry("name").SetValue(config.game.name);
348  FindEntry("maxPlayers").SetValue(config.game.maxPlayers.ToString());
349  FindEntry("password").SetValue(config.game.password);
350  FindEntry("passwordAdmin").SetValue(config.game.passwordAdmin);
351  FindEntry("visible").SetValue(SCR_JsonApiStructHandler.BoolToString(config.game.visible));
352  FindEntry("crossPlatform").SetValue(SCR_JsonApiStructHandler.BoolToString(config.game.crossPlatform));
353 
354  // Game properties
355  SCR_DSGameProperties gamePropertiesSCr = SCR_DSGameProperties.Cast(config.game.gameProperties);
356 
357  if (gamePropertiesSCr)
358  {
359  FindEntry("battlEye").SetValue(SCR_JsonApiStructHandler.BoolToString(gamePropertiesSCr.battlEye));
360  FindEntry("disableThirdPerson").SetValue(SCR_JsonApiStructHandler.BoolToString(gamePropertiesSCr.disableThirdPerson));
361  FindEntry("VONDisableUI").SetValue(SCR_JsonApiStructHandler.BoolToString(gamePropertiesSCr.VONDisableUI));
362  FindEntry("VONDisableDirectSpeechUI").SetValue(SCR_JsonApiStructHandler.BoolToString(gamePropertiesSCr.VONDisableDirectSpeechUI));
363  FindEntry("VONCanTransmitCrossFaction").SetValue(SCR_JsonApiStructHandler.BoolToString(gamePropertiesSCr.VONCanTransmitCrossFaction));
364  FindEntry("serverMaxViewDistance").SetValue(gamePropertiesSCr.serverMaxViewDistance.ToString());
365  FindEntry("networkViewDistance").SetValue(gamePropertiesSCr.networkViewDistance.ToString());
366  FindEntry("serverMinGrassDistance").SetValue(gamePropertiesSCr.serverMinGrassDistance.ToString());
367  }
368 
369  // Scenario
370  m_ScenarioSelect.SelectOption(SetSelectedScenarioById(config.game.scenarioId));
371  }
372 
373  //-------------------------------------------------------------------------------------------
375  void ScrollToTheEntry(notnull Widget w)
376  {
377  // Entry position
378  float entryX, entryY;
379  w.GetScreenPos(entryX, entryY);
380 
381  // Vertical list size
382  float listW, listH;
383  m_wList.GetScreenSize(listW, listH);
384 
385  // Vertical list size
386  float listX, listY;
387  m_wList.GetScreenPos(listX, listY);
388 
389  // Scroll (view) size
390  float scrollW, scrollH;
391  m_wScrollWidget.GetScreenSize(scrollW, scrollH);
392 
393  // Scroll to entry
394  float outView = listH - scrollH; // What size can't be seen
395  float relPos = entryY - listY;
396 
397  float pos = 1 - (outView - relPos) / outView;
398  m_wScrollWidget.SetSliderPos(0, pos);
399  }
400 
401  //------------------------------------------------------------------------------------------------
402  void SetPort(string port)
403  {
404  m_SimplePortEdit.SetValue(port);
405  }
406 
407  //-------------------------------------------------------------------------------------------
408  // Callbacks
409  //-------------------------------------------------------------------------------------------
410 
411  //-------------------------------------------------------------------------------------------
412  protected void OnNameChanged(SCR_EditBoxComponent edit, string text)
413  {
414  m_bNameEdited = !text.IsEmpty();
415  }
416 
417  //-------------------------------------------------------------------------------------------
418  protected void OnSimplePortChanged(SCR_EditBoxComponent edit, string text)
419  {
420  if (m_OnPortChanged)
421  m_OnPortChanged.Invoke(text);
422  }
423 
424  //-------------------------------------------------------------------------------------------
425  protected void OnFileNameChanged(SCR_EditBoxComponent edit, string text)
426  {
427  m_bFileNameEdited = !text.IsEmpty();
428  }
429 
430  //-------------------------------------------------------------------------------------------
431  protected void OnSelectScenario(SCR_ComboBoxComponent comboBox, int selected)
432  {
433  if (!m_ScenarioSelect || !m_ScenarioModSelect)
434  return;
435 
436  int selecteScenario = m_ScenarioSelect.GetSelectedOption();
437  array<ref SCR_LocalizedProperty> ownerMods = {};
438 
439  int count = 0;
440 
441  if (m_aScenarioSources[selected].m_aMods)
442  count = m_aScenarioSources[selected].m_aMods.Count();
443 
444  for (int i = 0; i < count; i++)
445  {
446  WorkshopItem mod = m_aScenarioSources[selected].m_aMods[i];
447  if (!mod)
448  continue;
449 
450  string name = m_aScenarioSources[selected].m_aMods[i].Name();
451  string id = m_aScenarioSources[selected].m_aMods[i].Id();
452 
453  ownerMods.Insert(new SCR_LocalizedProperty(name, id));
454  }
455 
456  // Is vanilla?
457  if (!ownerMods || ownerMods.IsEmpty() || ownerMods[0] == null)
458  {
459  // Display source mod as Arma Reforger
460  ownerMods.Clear();
461  ownerMods.Insert(new SCR_LocalizedProperty("#AR-Editor_Attribute_OverlayLogo_Reforger", ""));
462  }
463 
464  m_ScenarioModSelect.SetOptions(ownerMods);
465  m_ScenarioModSelect.SelectOption(0);
466 
467  // Enable selection interactivity only if scenario has multiple sources
468  m_ScenarioModSelect.SetInteractive(ownerMods.Count() > 1);
469 
470  // Update properties
471  MissionWorkshopItem scenario = GetSelectedScenario();
472 
473  if (!m_bNameEdited)
474  GenerateName(scenario);
475 
476  if (!m_bFileNameEdited)
477  GenerateFileName(scenario);
478 
479  SetupPlayerLimit(scenario.GetPlayerCount());
480 
481  InvokeOnScenarioSelected(scenario.Id());
482  }
483 
484  //-------------------------------------------------------------------------------------------
486  protected void GenerateName(notnull MissionWorkshopItem scenario)
487  {
488  if (!m_NameEdit)
489  return;
490 
491  string name = string.Format(SERVER_NAME_BASE, SCR_Global.GetProfileName(), scenario.Name());
492 
493  m_NameEdit.SetValue(name);
494  m_NameEdit.ClearInvalidInput();
495  }
496 
497  protected const string CHAR_BLACK_LIST = "<>:\/\|?*.";
498 
499  //-------------------------------------------------------------------------------------------
501  string GenerateFileName(notnull MissionWorkshopItem scenario)
502  {
503  string scenarioTranslation = WidgetManager.Translate(scenario.Name());
504  string fileName = string.Format(FILE_NAME_BASE, scenarioTranslation);
505  fileName.Replace(" ", "");
506 
507  // Remove special characters
508  for (int i = 0, count = CHAR_BLACK_LIST.Length(); i < count; i++)
509  {
510  fileName.Replace(CHAR_BLACK_LIST[i], "");
511  }
512 
513  return fileName;
514  }
515 
516  //-------------------------------------------------------------------------------------------
517  protected void SetupPlayerLimit(int limit)
518  {
519  if (!m_PlayerListSlider)
520  return;
521 
522  m_PlayerListSlider.SetRange(1, limit);
523 
524  // Set value
525  int value = m_PlayerListSlider.ValueAsString().ToInt();
526 
527  if (value > limit)
528  m_PlayerListSlider.SetValue(limit.ToString());
529  }
530 
531  //-------------------------------------------------------------------------------------------
532  // API
533  //-------------------------------------------------------------------------------------------
534 
535  //-------------------------------------------------------------------------------------------
536  ResourceName GetDialogs()
537  {
538  return m_sDialogs;
539  }
540 };
541 
543 //-------------------------------------------------------------------------------------------
545 {
546  MissionWorkshopItem m_Scenario;
547 
548  ref array<WorkshopItem> m_aMods;
549 
550  void SCR_ScenarioSources(MissionWorkshopItem scenario, array<WorkshopItem> mods)
551  {
552  m_Scenario = scenario;
553  m_aMods = mods;
554  }
555 }
556 
SCR_ERevisionAvailability
SCR_ERevisionAvailability
Definition: SCR_AddonManager.c:1090
SCR_DSGameProperties
void SCR_DSGameProperties()
Definition: SCR_DSConfig.c:168
SCR_ConfigListComponent
Definition: SCR_ConfigListComponent.c:5
SCR_ComboBoxComponent
Definition: SCR_ComboBoxComponent.c:1
SCR_WidgetListEntryEditBox
Configurable widget list entry for various value that can be typed - numbers, strings,...
Definition: SCR_WidgetListEntry.c:333
GetGame
ArmaReforgerScripted GetGame()
Definition: game.c:1424
IsPlatformGameConsole
bool IsPlatformGameConsole()
Definition: game.c:1393
m_wList
protected Widget m_wList
Definition: SCR_DownloadManagerListComponent.c:12
SCR_WorkshopItem
Definition: SCR_WorkshopItem.c:21
SCR_JsonApiStructHandler
Handler for json api struct values.
Definition: SCR_JsonApiStructHandler.c:8
SCR_ServerConfigListComponent
Definition: SCR_ServerConfigListComponent.c:5
Attribute
typedef Attribute
Post-process effect of scripted camera.
SCR_DSConfig
Definition: SCR_DSConfig.c:5
GetOwner
IEntity GetOwner()
Owner entity of the fuel tank.
Definition: SCR_FuelNode.c:128
SCR_LocalizedProperty
Variable that is using localized label.
Definition: SCR_WidgetListEntry.c:74
SCR_Global
Definition: Functions.c:6
SCR_AddonManager
Definition: SCR_AddonManager.c:72
SCR_EditBoxComponent
Definition: SCR_EditBoxComponent.c:8
m_sPropertyName
BaseContainerCustomCheckIntWithFlagTitleField m_sPropertyName
Attribute for setting UIInfo's name property as (Localized) custom title.
SCR_ScenarioSources
Stores scenario with scenario source.
Definition: SCR_ServerConfigListComponent.c:544
GetPlayerCount
int GetPlayerCount()
Definition: SCR_Faction.c:365
m_Scenario
SCR_ExitGameWhileDownloadingDialog m_Scenario
SCR_WidgetListEntrySelection
Configurable widget list entry list selection.
Definition: SCR_WidgetListEntry.c:651