Arma Reforger Explorer  1.1.0.42
Arma Reforger Code Explorer by Zeroy - Thanks to MisterOutofTime
SCR_SaveManagerCore.c
Go to the documentation of this file.
3 typedef ScriptInvokerBase<ScriptInvoker_SaveManagerCoreMethod> ScriptInvoker_SaveManagerCore;
4 
8 [BaseContainerProps(configRoot: true)]
9 class SCR_SaveManagerCore: SCR_GameCoreBase
10 {
11  protected const string GAME_SESSION_STORAGE_FILE_NAME_TO_LOAD = "SCR_SaveFileManager_FileNameToLoad";
12  protected const string GAME_SESSION_STORAGE_USED_CLI = "SCR_SaveFileManager_UsedCLI";
13  protected const string CLI_PARAM = "loadSessionSave";
14 
15  [Attribute()]
16  protected ref array<ref SCR_DSSessionCallback> m_aCallbacks;
17 
18  [Attribute()]
19  protected ref SCR_LatestSaveDSSessionCallback m_LatestSaveCallback;
20 
21  protected ref SCR_DSSessionCallbackSessionStorage m_SessionStorageCallback;
22 
23  protected string m_sMissionSaveFileName;
24  protected ref SCR_MissionHeader m_WorkbenchMissionHeader;
25 
26  protected ref ScriptInvoker_SaveManagerCore m_OnSaved = new ScriptInvoker_SaveManagerCore();
27  protected ref ScriptInvoker_SaveManagerCore m_OnLoaded = new ScriptInvoker_SaveManagerCore();
28  protected ref ScriptInvoker_SaveManagerCore m_OnDeleted = new ScriptInvoker_SaveManagerCore();
29  protected ref ScriptInvokerString m_OnLatestSave = new ScriptInvokerString();
30 
31  protected bool m_bLoadedOnInit;
32  protected bool m_bDebugDelete;
33  protected ref SCR_ServerSaveRequestCallback m_UploadCallback;
34  protected ref SCR_SaveManager_BackendCallback m_DownloadCallback;
35  protected ref SCR_SaveManager_PageParams m_DownloadPageParams;
36 
41 
48  bool Save(ESaveType type, string customName = string.Empty)
49  {
50  SCR_DSSessionCallback callback = FindCallback(type);
51  if (!callback)
52  {
53  Print(string.Format("SCR_SaveManagerCore: Cannot save, no rules found for save type %1! Check configuration of SCR_SaveLoadComponent on game mode.", typename.EnumToString(ESaveType, type)), LogLevel.WARNING);
54  return false;
55  }
56 
57  return callback.SaveSession(m_sMissionSaveFileName, customName);
58  }
59 
60  //----------------------------------------------------------------------------------------
66  bool OverrideCurrentSave(ESaveType type)
67  {
68  SCR_DSSessionCallback callback = FindCallback(type);
69  if (!callback)
70  {
71  Print(string.Format("SCR_SaveManagerCore: Cannot override current save, no rules found for save type %1! Check configuration of SCR_SaveLoadComponent on game mode.", typename.EnumToString(ESaveType, type)), LogLevel.WARNING);
72  return false;
73  }
74 
75  string customName = callback.GetCurrentCustomName();
76  return customName && callback.SaveSession(m_sMissionSaveFileName, customName);
77  }
78 
79  //----------------------------------------------------------------------------------------
87  bool Load(string fileName)
88  {
89  SCR_DSSessionCallback callback = FindCallback(fileName);
90  if (!callback)
91  {
92  Print(string.Format("SCR_SaveManagerCore: Cannot load save file '%1', no rules found for it!", fileName), LogLevel.WARNING);
93  return false;
94  }
95 
96  return callback.LoadSession(fileName);
97  }
98 
99  //----------------------------------------------------------------------------------------
104  bool RestartAndLoad()
105  {
106  string latestSaveFileName;
107  return FindLatestSave(m_sMissionSaveFileName, latestSaveFileName) && RestartAndLoad(latestSaveFileName);
108  }
109 
110  //----------------------------------------------------------------------------------------
117  bool RestartAndLoad(ESaveType type, string customName = string.Empty)
118  {
119  SCR_DSSessionCallback callback = FindCallback(type);
120  if (!callback)
121  {
122  Print(string.Format("SCR_SaveManagerCore: Cannot restart and load, no rules found for save type %1! Check configuration of SCR_SaveLoadComponent on game mode.", typename.EnumToString(ESaveType, type)), LogLevel.WARNING);
123  return false;
124  }
125 
126  string fileName = callback.GetFileName(m_sMissionSaveFileName, customName);
127  return RestartAndLoad(fileName);
128  }
129 
130  //----------------------------------------------------------------------------------------
136  bool RestartAndLoad(string fileName)
137  {
138  if (Replication.IsClient())
139  {
140  UploadToWorkshop(fileName);
141  return true;
142  }
143  else
144  {
145  //--- Server / SP
146  if (!SetFileNameToLoad(fileName))
147  return false;
148 
149  GameStateTransitions.RequestScenarioRestart();
150  return true;
151  }
152  }
153 
154  //----------------------------------------------------------------------------------------
161  bool Delete(ESaveType type, string customName = string.Empty)
162  {
163  SCR_DSSessionCallback callback = FindCallback(type);
164  if (!callback)
165  {
166  Print(string.Format("SCR_SaveManagerCore: Cannot delete, no rules found for save type %1! Check configuration of SCR_SaveLoadComponent on game mode.", typename.EnumToString(ESaveType, type)), LogLevel.WARNING);
167  return false;
168  }
169 
170  return callback.Delete(m_sMissionSaveFileName, customName);
171  }
172 
173  //----------------------------------------------------------------------------------------
179  bool Delete(string fileName)
180  {
181  SCR_DSSessionCallback callback = FindCallback(fileName);
182  if (!callback)
183  {
184  Print(string.Format("SCR_SaveManagerCore: Cannot delete save file '%1', no rules found for it!", fileName), LogLevel.WARNING);
185  return false;
186  }
187 
188  return callback.Delete(fileName);
189  }
190 
191  //----------------------------------------------------------------------------------------
198  bool FileExists(ESaveType type, string customName = string.Empty)
199  {
200  SCR_DSSessionCallback callback = FindCallback(type);
201  if (!callback)
202  {
203  Print(string.Format("SCR_SaveManagerCore: Cannot check if file exists, no rules found for save type %1! Check configuration of SCR_SaveLoadComponent on game mode.", typename.EnumToString(ESaveType, type)), LogLevel.WARNING);
204  return false;
205  }
206 
207  return callback.FileExists(m_sMissionSaveFileName, customName);
208  }
209 
210  //----------------------------------------------------------------------------------------
216  bool FileExists(string fileName)
217  {
218  return GetGame().GetBackendApi().GetStorage().CheckFileID(fileName);
219  }
220 
221  //----------------------------------------------------------------------------------------
225  bool CanSaveToCloud()
226  {
227  return RplSession.Mode() == RplMode.Dedicated && GetGame().GetBackendApi().GetStorage().GetOnlineWritePrivilege();
228  }
229 
230  //----------------------------------------------------------------------------------------
236  SCR_MetaStruct GetMeta(string fileName)
237  {
238  SCR_DSSessionCallback callback = FindCallback(fileName);
239  if (!callback)
240  {
241  Print(string.Format("SCR_SaveManagerCore: Cannot load meta of save file '%1', no rules found for it!", fileName), LogLevel.WARNING);
242  return null;
243  }
244 
245  return callback.GetMeta(fileName);
246  }
247 
252 
260  int GetLocalSaveFiles(out notnull array<string> outLocalSaves, ESaveType saveTypes, bool currentMissionOnly)
261  {
262  string missionFileName;
263  if (currentMissionOnly)
264  missionFileName = m_sMissionSaveFileName;
265 
266  return GetLocalSaveFiles(outLocalSaves, saveTypes, missionFileName);
267  }
275  int GetLocalSaveFiles(out notnull array<string> outLocalSaves, ESaveType saveTypes, string missionFileName = string.Empty)
276  {
277  for (int i = GetGame().GetBackendApi().GetStorage().AvailableSaves(outLocalSaves) - 1; i >= 0; i--)
278  {
279  //--- Filter out downloaded files
280  if (IsDownloaded(outLocalSaves[i]))
281  {
282  outLocalSaves.Remove(i);
283  continue;
284  }
285 
286  SCR_DSSessionCallback callback = FindCallback(outLocalSaves[i]);
287  if (!callback || !(saveTypes & callback.GetSaveType()) || (missionFileName && callback.GetMissionFileName(outLocalSaves[i]) != missionFileName))
288  outLocalSaves.Remove(i);
289  }
290  return outLocalSaves.Count();
291  }
293 
294  protected bool IsDownloaded(string fileName)
295  {
296  string ext;
297  FilePath.StripExtension(fileName, ext);
298  return ext.Contains("_"); //--- Downloaded files have GUID added at the end, e.g., "MissionName-CustomName.save_5D82C234B9132BBC"
299  }
300 
305 
311  bool CanSave(ESaveType type)
312  {
313  if (!m_sMissionSaveFileName || !FindCallback(type))
314  return false;
315 
317  return !gameMode || gameMode.GetState() == SCR_EGameModeState.GAME;
318  }
319 
320  //----------------------------------------------------------------------------------------
327  void SetStruct(ESaveType type, SCR_MissionStruct struct)
328  {
329  foreach (SCR_DSSessionCallback callback: m_aCallbacks)
330  {
331  if (callback.GetSaveType() == type)
332  {
333  callback.SetStruct(struct);
334  return;
335  }
336  }
337  }
338 
339  //----------------------------------------------------------------------------------------
344  void Log(ESaveType type)
345  {
346  SCR_DSSessionCallback callback = FindCallback(type);
347  if (callback)
348  callback.Log();
349  }
350 
351  //----------------------------------------------------------------------------------------
357  string GetMissionFileName(string fileName)
358  {
359  SCR_DSSessionCallback callback = FindCallback(fileName);
360  if (callback)
361  return callback.GetMissionFileName(fileName);
362  else
363  return string.Empty;
364  }
365 
366  //----------------------------------------------------------------------------------------
372  string GetCustomName(string fileName)
373  {
374  SCR_DSSessionCallback callback = FindCallback(fileName);
375  if (callback)
376  return callback.GetCustomName(fileName);
377  else
378  return string.Empty;
379  }
380 
381  //----------------------------------------------------------------------------------------
387  SCR_UIInfo GetSaveTypeInfo(string fileName)
388  {
389  SCR_DSSessionCallback callback = FindCallback(fileName);
390  if (callback)
391  return callback.GetInfo();
392  else
393  return null;
394  }
396 
397  //----------------------------------------------------------------------------------------
398  protected SCR_DSSessionCallback FindCallback(ESaveType type)
399  {
400  foreach (SCR_DSSessionCallback callback: m_aCallbacks)
401  {
402  if (callback.GetSaveType() == type && callback.IsConfigured())
403  return callback;
404  }
405  return null;
406  }
407 
408  //----------------------------------------------------------------------------------------
409  protected SCR_DSSessionCallback FindCallback(string fileName)
410  {
411  foreach (SCR_DSSessionCallback callback: m_aCallbacks)
412  {
413  if (callback.IsCompatible(fileName))
414  return callback;
415  }
416  return null;
417  }
418 
420  // Workshop WIP
422  void UploadToWorkshop(string fileName)
423  {
424  SCR_DSSessionCallback callback = FindCallback(fileName);
425  if (!callback)
426  return;
427 
428  m_UploadCallback = new SCR_ServerSaveRequestCallback(fileName);//, callback.GetStruct());
429  }
430 
431  //----------------------------------------------------------------------------------------
432  void DownloadFromWorkshop()
433  {
434  m_DownloadCallback = new SCR_SaveManager_BackendCallback();
435 
436  m_DownloadPageParams = new SCR_SaveManager_PageParams();
437  m_DownloadPageParams.limit = 50;
438 
439  GetGame().GetBackendApi().GetWorldSaveApi().RequestPage(m_DownloadCallback, m_DownloadPageParams, true);
440  }
441 
442  //----------------------------------------------------------------------------------------
443  void OnDownloadFromWorkshop()
444  {
445  m_DownloadCallback = null;
446  m_DownloadPageParams = null;
447 
448  Print("GetPageCount() = " + GetGame().GetBackendApi().GetWorldSaveApi().GetPageCount());
449  array<WorldSaveItem> items = {};
450  int count = GetGame().GetBackendApi().GetWorldSaveApi().GetPageItems(items);
451  foreach (int i, WorldSaveItem item: items)
452  {
453  PrintFormat("%1: Id=%2, Name='%3', Description='%4'", i, item.Id(), item.Name(), item.Description());
454 
455  if (m_bDebugDelete)
456  item.DeleteOnline(null);
457  }
458  }
459 
464 
470  bool SetFileNameToLoad(SCR_MissionHeader missionHeader)
471  {
472  if (!missionHeader)
473  return false;
474 
475  //--- Find latest save for the mission
476  string latestSaveFileName;
477  if (!FindLatestSave(missionHeader.GetSaveFileName(), latestSaveFileName))
478  return false;
479 
480  return SetFileNameToLoad(latestSaveFileName);
481  }
482 
483  //----------------------------------------------------------------------------------------
489  bool SetFileNameToLoad(string fileName)
490  {
491  if (!GetGame().GetBackendApi().GetStorage().CheckFileID(fileName))
492  return false;
493 
494  GameSessionStorage.s_Data.Insert(GAME_SESSION_STORAGE_FILE_NAME_TO_LOAD, fileName);
495  Print(string.Format("'%1' set as a save file name to load after world start.", fileName), LogLevel.VERBOSE);
496  return true;
497  }
498 
499  //----------------------------------------------------------------------------------------
504  void ResetFileNameToLoad()
505  {
506  if (GameSessionStorage.s_Data.Contains(GAME_SESSION_STORAGE_FILE_NAME_TO_LOAD))
507  {
508  GameSessionStorage.s_Data.Remove(GAME_SESSION_STORAGE_FILE_NAME_TO_LOAD);
509  Print("Save file name to load after world start removed.", LogLevel.VERBOSE);
510  }
511  }
512 
513  //----------------------------------------------------------------------------------------
519  bool FindFileNameToLoad(out string fileNameToLoad)
520  {
521  return GameSessionStorage.s_Data.Find(GAME_SESSION_STORAGE_FILE_NAME_TO_LOAD, fileNameToLoad);
522  }
524 
529 
534  void SetCurrentMissionLatestSave(string saveFileName)
535  {
536  SetLatestSave(m_sMissionSaveFileName, saveFileName);
537  }
538 
539  //----------------------------------------------------------------------------------------
544  void RemoveCurrentMissionLatestSave()
545  {
546  RemoveLatestSave(m_sMissionSaveFileName);
547  }
548 
549  //----------------------------------------------------------------------------------------
554  bool FindCurrentMissionLatestSave(out string outSaveFileName)
555  {
556  return FindLatestSave(m_sMissionSaveFileName, outSaveFileName);
557  }
558 
559  //----------------------------------------------------------------------------------------
565  void SetLatestSave(string missionFileName, string saveFileName)
566  {
567  m_LatestSaveCallback.SetFileName(missionFileName, saveFileName);
568  }
569 
570  //----------------------------------------------------------------------------------------
576  void RemoveLatestSave(string missionFileName)
577  {
578  m_LatestSaveCallback.RemoveFileName(missionFileName);
579  }
580 
581  //----------------------------------------------------------------------------------------
587  bool FindLatestSave(string missionFileName, out string outSaveFileName)
588  {
589  return m_LatestSaveCallback.FindFileName(missionFileName, outSaveFileName);
590  }
591 
592  //----------------------------------------------------------------------------------------
598  bool FindLatestSave(SCR_MissionHeader missionHeader, out string outSaveFileName)
599  {
600  return missionHeader && FindLatestSave(missionHeader.GetSaveFileName(), outSaveFileName);
601  }
602 
603  //----------------------------------------------------------------------------------------
608  bool HasLatestSave(string missionFileName)
609  {
610  string saveFileName;
611  return FindLatestSave(missionFileName, saveFileName);
612  }
613 
614  //----------------------------------------------------------------------------------------
619  bool HasLatestSave(SCR_MissionHeader missionHeader)
620  {
621  string saveFileName;
622  return missionHeader && FindLatestSave(missionHeader, saveFileName);
623  }
625 
630 
631  //----------------------------------------------------------------------------------------
635  ScriptInvoker_SaveManagerCore GetOnSaved()
636  {
637  return m_OnSaved;
638  }
639 
640  //----------------------------------------------------------------------------------------
644  ScriptInvoker_SaveManagerCore GetOnLoaded()
645  {
646  return m_OnLoaded;
647  }
648 
649  //----------------------------------------------------------------------------------------
653  ScriptInvoker_SaveManagerCore GetOnDeleted()
654  {
655  return m_OnDeleted;
656  }
657 
658  //----------------------------------------------------------------------------------------
662  ScriptInvokerString GetOnLatestSave()
663  {
664  return m_OnLatestSave;
665  }
666 
667  //----------------------------------------------------------------------------------------
668  SCR_ServerSaveRequestCallback GetUploadCallback()
669  {
670  return m_UploadCallback;
671  }
672 
674 
676  // Init
678 
681  void LoadOnInit()
682  {
683  //--- Stop if mission save file is not defined (e.g., when mission header is missing) or when on client
684  if (m_bLoadedOnInit || !m_sMissionSaveFileName || !Replication.IsServer())
685  return;
686 
687  //--- Mark as initialized, so nothing will happen in case somebody is crazy/brave/naive enough to call LoadOnInit() again
688  m_bLoadedOnInit = true;
689 
690  //--- Find save file to be loaded on start
691  string fileNameToLoad;
692  if (System.IsConsoleApp())
693  {
694  //--- DEDICATED SERVER
695 
696  //--- Check if some file was marked for load, e.g, using client's editor interface. If not, continue with evaluating CLI param.
697  if (!FindFileNameToLoad(fileNameToLoad))
698  {
699  //--- Terminate when the file marked by the CLI param was loaded before (happens e.g., after calling the #restart command)
700  if (GameSessionStorage.s_Data.Contains(GAME_SESSION_STORAGE_USED_CLI))
701  return;
702 
703  //--- Terminate when the CLI param is not used
704  if (!System.GetCLIParam(CLI_PARAM, fileNameToLoad))
705  {
706  Print(string.Format("SCR_SaveManagerCore: -%1 CLI param not used, no save file is loaded.", CLI_PARAM), LogLevel.VERBOSE);
707  return;
708  }
709 
710  //--- Terminate when the CLI param is marked to load the latest save, but there is none defined
711  if (fileNameToLoad.IsEmpty() && !FindLatestSave(m_sMissionSaveFileName, fileNameToLoad))
712  {
713  Print(string.Format("SCR_SaveManagerCore: -%1 CLI param set to load the latest save, but none was defined for the mission '%2'!", CLI_PARAM, m_sMissionSaveFileName), LogLevel.WARNING);
714  return;
715  }
716 
717  GameSessionStorage.s_Data.Insert(GAME_SESSION_STORAGE_USED_CLI, fileNameToLoad);
718  }
719  }
720  else
721  {
722  //--- STANDARD GAME
723 
724  //--- Show a warning when the CLI param is used incorrectly (otherwise harmless)
725  if (System.IsCLIParam(CLI_PARAM))
726  Print(string.Format("SCR_SaveManagerCore: -%1 CLI is intended for dedicated server only!", CLI_PARAM), LogLevel.WARNING);
727 
728  //--- Terminate if requested save file does not exist
729  if (!FindFileNameToLoad(fileNameToLoad))
730  return;
731  }
732 
733  //--- Load the file and unmark it, so restarting from pause menu won't load it again
734  Load(fileNameToLoad);
735  ResetFileNameToLoad();
736  }
737 
738  //----------------------------------------------------------------------------------------
739  protected void InitDebugMissionHeader(out SCR_MissionHeader missionHeader)
740  {
741  //--- Mission header not found, create a debug one (play mode in World Editor never has a mission header, even when one for the world exists)
742  if (!missionHeader && SCR_SaveLoadComponent.GetInstance())
743  {
744  m_WorkbenchMissionHeader = new SCR_MissionHeader();
745  m_WorkbenchMissionHeader.m_sSaveFileName = FilePath.StripPath(FilePath.StripExtension(GetGame().GetWorldFile()));
746  m_WorkbenchMissionHeader.m_bIsSavingEnabled = true;
747  missionHeader = m_WorkbenchMissionHeader;
748  }
749  }
750 
752  // Default functions
754  override void OnUpdate(float timeSlice)
755  {
756  if (m_sMissionSaveFileName && !System.IsConsoleApp() && GetGame().IsDev())
757  {
758  if (DiagMenu.GetBool(SCR_DebugMenuID.DEBUGUI_SAVING_SAVE))
759  {
760  DiagMenu.SetValue(SCR_DebugMenuID.DEBUGUI_SAVING_SAVE, false);
761 
762  ESaveType saveType = 1 << DiagMenu.GetValue(SCR_DebugMenuID.DEBUGUI_SAVING_TYPE);
763 
764  array<string> customNames = {"Alpha", "Kilo", "Zulu"};
765  string customName = customNames.GetRandomElement();
766  Save(saveType, customName);
767  }
768  if (DiagMenu.GetBool(SCR_DebugMenuID.DEBUGUI_SAVING_LOG))
769  {
770  DiagMenu.SetValue(SCR_DebugMenuID.DEBUGUI_SAVING_LOG, false);
771 
772  ESaveType saveType = 1 << DiagMenu.GetValue(SCR_DebugMenuID.DEBUGUI_SAVING_TYPE);
773  Log(saveType);
774  }
775  if (DiagMenu.GetBool(SCR_DebugMenuID.DEBUGUI_SAVING_LOAD_LATEST))
776  {
777  DiagMenu.SetValue(SCR_DebugMenuID.DEBUGUI_SAVING_LOAD_LATEST, false);
778 
779  string fileName;
780  if (FindLatestSave(m_sMissionSaveFileName, fileName))
781  Load(fileName);
782  }
783  if (DiagMenu.GetBool(SCR_DebugMenuID.DEBUGUI_SAVING_RESTART_AND_LOAD_LATEST))
784  {
785  DiagMenu.SetValue(SCR_DebugMenuID.DEBUGUI_SAVING_RESTART_AND_LOAD_LATEST, false);
786  RestartAndLoad();
787  }
788  if (DiagMenu.GetBool(SCR_DebugMenuID.DEBUGUI_SAVING_LOG_LATEST))
789  {
790  DiagMenu.SetValue(SCR_DebugMenuID.DEBUGUI_SAVING_LOG_LATEST, false);
791 
792  string latestSaveFileName;
793  if (FindLatestSave(m_sMissionSaveFileName, latestSaveFileName))
794  PrintFormat("The latest save file name for mission '%1' is '%2'", m_sMissionSaveFileName, latestSaveFileName);
795  else
796  PrintFormat("There is no latest save file name for mission '%1'", latestSaveFileName);
797  }
798  if (DiagMenu.GetBool(SCR_DebugMenuID.DEBUGUI_SAVING_UPLOAD_LATEST))
799  {
800  DiagMenu.SetValue(SCR_DebugMenuID.DEBUGUI_SAVING_UPLOAD_LATEST, false);
801 
802  string fileName;
803  if (FindLatestSave(m_sMissionSaveFileName, fileName))
804  UploadToWorkshop(fileName);
805  else
806  Print("SCR_SaveManagerCore: Cannot upload, latest save not found!", LogLevel.WARNING);
807  }
808  if (DiagMenu.GetBool(SCR_DebugMenuID.DEBUGUI_SAVING_DOWNLOAD))
809  {
810  DiagMenu.SetValue(SCR_DebugMenuID.DEBUGUI_SAVING_DOWNLOAD, false);
811 
812  m_bDebugDelete = false;
813  DownloadFromWorkshop();
814  }
815  if (DiagMenu.GetBool(SCR_DebugMenuID.DEBUGUI_SAVING_DELETE))
816  {
817  DiagMenu.SetValue(SCR_DebugMenuID.DEBUGUI_SAVING_DELETE, false);
818 
819  m_bDebugDelete = true;
820  DownloadFromWorkshop();
821  }
822  }
823  }
824 
825  //----------------------------------------------------------------------------------------
826  override void OnGameStart()
827  {
828  //--- Saving is not configured for the current world
829  if (!SCR_SaveLoadComponent.GetInstance())
830  {
831  // Load save immidiatelly - works only when getting back to main menu, not when starting game
832  OnGameStorageInitialize();
833 
834  if (m_LatestSaveCallback.IsLoaded())
835  return;
836 
837  // Wait for init - happens on game start
838  m_SessionStorageCallback = new SCR_DSSessionCallbackSessionStorage();
839  m_SessionStorageCallback.GetOnInitialize().Insert(OnGameStorageInitialize);
840  GetGame().GetBackendApi().SetSessionCallback(m_SessionStorageCallback);
841 
842  return;
843  }
844 
845  //--- Init mission header (use debug one in special conditions)
846  SCR_MissionHeader missionHeader = SCR_MissionHeader.Cast(GetGame().GetMissionHeader());
847 
848 #ifdef WORKBENCH
849  InitDebugMissionHeader(missionHeader);
850 #endif
851 
852 #ifdef SAVE_MANAGER_DEBUG_HEADER
853  InitDebugMissionHeader(missionHeader);
854 #endif
855 
856  //--- Set mission save file name, but only if saving is enabled
857  if (missionHeader && missionHeader.m_bIsSavingEnabled)
858  m_sMissionSaveFileName = missionHeader.GetSaveFileName();
859 
860  //--- Initialize callbacks
861  foreach (SCR_DSSessionCallback callback: m_aCallbacks)
862  {
863  callback.OnGameStart(m_sMissionSaveFileName);
864  }
865 
866  //--- Initialize save manager and load marked save file
867  m_LatestSaveCallback.ReadFromFile();
868 
869  //--- Diag menu init
870  if (GetGame().IsDev() && Replication.IsServer() && !System.IsConsoleApp())
871  {
872  typename enumType = ESaveType;
873  string categoryName = "Save Manager";
874  DiagMenu.RegisterMenu(SCR_DebugMenuID.DEBUGUI_SAVING, categoryName, "Game");
875  DiagMenu.RegisterRange(SCR_DebugMenuID.DEBUGUI_SAVING_TYPE, "", "Type", categoryName, string.Format("0,%1,0,1", enumType.GetVariableCount() - 1));
876  DiagMenu.RegisterBool(SCR_DebugMenuID.DEBUGUI_SAVING_LOG, "", "Log Struct By Type", categoryName);
877  DiagMenu.RegisterBool(SCR_DebugMenuID.DEBUGUI_SAVING_SAVE, "", "Save By Type", categoryName);
878 
879  DiagMenu.RegisterBool(SCR_DebugMenuID.DEBUGUI_SAVING_LOAD_LATEST, "", "Load Latest Save", categoryName);
880  DiagMenu.RegisterBool(SCR_DebugMenuID.DEBUGUI_SAVING_RESTART_AND_LOAD_LATEST, "", "Restart and Load Latest Save", categoryName);
881  DiagMenu.RegisterBool(SCR_DebugMenuID.DEBUGUI_SAVING_LOG_LATEST, "", "Log Latest Save File Name", categoryName);
882  DiagMenu.RegisterBool(SCR_DebugMenuID.DEBUGUI_SAVING_UPLOAD_LATEST, "", "Upload Latest Save", categoryName);
883 
884  DiagMenu.RegisterBool(SCR_DebugMenuID.DEBUGUI_SAVING_DOWNLOAD, "", "Download Workshop Saves", categoryName);
885  DiagMenu.RegisterBool(SCR_DebugMenuID.DEBUGUI_SAVING_DELETE, "", "Delete Workshop Saves", categoryName);
886  }
887  }
888 
889  //----------------------------------------------------------------------------------------
890  protected void OnGameStorageInitialize()
891  {
892  if (SCR_MainMenuEntity.GetInstance())
893  m_LatestSaveCallback.ReadFromFile();
894 
895  if (m_SessionStorageCallback)
896  m_SessionStorageCallback.GetOnInitialize().Remove(OnGameStorageInitialize);
897  }
898 
899  //----------------------------------------------------------------------------------------
900  override void OnGameEnd()
901  {
902  foreach (SCR_DSSessionCallback callback: m_aCallbacks)
903  {
904  callback.OnGameEnd(m_sMissionSaveFileName);
905  }
906 
907  m_bLoadedOnInit = false;
908  m_sMissionSaveFileName = string.Empty;
909  m_WorkbenchMissionHeader = null;
910 
911  //--- Clear invokers are the world end
912  m_OnSaved.Clear();
913  m_OnLoaded.Clear();
914  m_OnDeleted.Clear();
915 
916  if (GetGame().IsDev() && Replication.IsServer() && !System.IsConsoleApp())
917  {
918  DiagMenu.Unregister(SCR_DebugMenuID.DEBUGUI_SAVING);
919  DiagMenu.Unregister(SCR_DebugMenuID.DEBUGUI_SAVING_TYPE);
920  DiagMenu.Unregister(SCR_DebugMenuID.DEBUGUI_SAVING_SAVE);
921  DiagMenu.Unregister(SCR_DebugMenuID.DEBUGUI_SAVING_LOG);
922  DiagMenu.Unregister(SCR_DebugMenuID.DEBUGUI_SAVING_LOAD_LATEST);
923  DiagMenu.Unregister(SCR_DebugMenuID.DEBUGUI_SAVING_RESTART_AND_LOAD_LATEST);
924  DiagMenu.Unregister(SCR_DebugMenuID.DEBUGUI_SAVING_LOG_LATEST);
925  DiagMenu.Unregister(SCR_DebugMenuID.DEBUGUI_SAVING_UPLOAD_LATEST);
926  DiagMenu.Unregister(SCR_DebugMenuID.DEBUGUI_SAVING_DOWNLOAD);
927  DiagMenu.Unregister(SCR_DebugMenuID.DEBUGUI_SAVING_DELETE);
928  }
929  }
930 };
931 
933 {
934  protected ref SCR_SaveManager_PageParams m_DownloadPageParams;
935 
936  override void OnError( int code, int restCode, int apiCode )
937  {
938  PrintFormat("[BackendCallback] OnError: code=%1 ('%4'), restCode=%2, apiCode=%3", code, restCode, apiCode, GetGame().GetBackendApi().GetErrorCode(code));
939  }
940  override void OnSuccess( int code )
941  {
942  PrintFormat("[BackendCallback] OnSuccess(): code=%1", code);
943  GetGame().GetSaveManager().OnDownloadFromWorkshop();
944  }
945  override void OnTimeout()
946  {
947  Print("[BackendCallback] OnTimeout");
948  }
949 };
950 class SCR_SaveManager_PageParams: PageParams
951 {
952  override void OnPack()
953  {
954  StoreBoolean("owned", true);
955  }
956 };
957 
958 //----------------------------------------------------------------------------------------
959 class SCR_DSSessionCallbackSessionStorage: DSSessionCallback
960 {
961  protected ref ScriptInvokerVoid m_OnInitialize;
962 
963  //----------------------------------------------------------------------------------------
964  ScriptInvokerVoid GetOnInitialize()
965  {
966  if (!m_OnInitialize)
967  m_OnInitialize = new ScriptInvokerVoid();
968 
969  return m_OnInitialize;
970  }
971 
972  //----------------------------------------------------------------------------------------
973  override void OnInitialize()
974  {
975  super.OnInitialize();
976  m_OnInitialize.Invoke();
977  }
978 };
SCR_BaseGameMode
Definition: SCR_BaseGameMode.c:137
SCR_LatestSaveDSSessionCallback
Definition: SCR_LatestSaveDSSessionCallback.c:2
SCR_SaveManager_PageParams
Definition: SCR_SaveManagerCore.c:950
GetGame
ArmaReforgerScripted GetGame()
Definition: game.c:1424
SCR_ServerSaveRequestCallback
Definition: SCR_UploadSaveCallback.c:1
func
func
Definition: SCR_AIThreatSystem.c:5
SCR_SaveManager_BackendCallback
Definition: SCR_SaveManagerCore.c:932
GetGameMode
SCR_BaseGameMode GetGameMode()
Definition: SCR_BaseGameModeComponent.c:15
GameStateTransitions
Definition: GameStateTransitions.c:12
SCR_MetaStruct
Definition: SCR_MetaStruct.c:2
ScriptInvoker_SaveManagerCoreMethod
func ScriptInvoker_SaveManagerCoreMethod
Definition: SCR_SaveManagerCore.c:2
ESaveType
ESaveType
Definition: ESaveType.c:1
Attribute
SCR_SaveManagerCore Attribute
Post-process effect of scripted camera.
ScriptInvoker_SaveManagerCore
ScriptInvokerBase< ScriptInvoker_SaveManagerCoreMethod > ScriptInvoker_SaveManagerCore
Definition: SCR_SaveManagerCore.c:3
ScriptInvokerString
ScriptInvokerBase< ScriptInvokerStringMethod > ScriptInvokerString
Definition: SCR_ScriptInvokerHelper.c:75
SCR_SaveManagerCore
Definition: SCR_SaveManagerCore.c:9
SCR_MissionStruct
Definition: SCR_MissionStruct.c:7
BackendCallback
Base server browser callback.
Definition: SCR_ServerListComponent.c:4
SCR_UIInfo
Definition: SCR_UIInfo.c:7
ScriptInvokerVoid
ScriptInvokerBase< ScriptInvokerVoidMethod > ScriptInvokerVoid
Definition: SCR_ScriptInvokerHelper.c:9
type
EDamageType type
Definition: SCR_DestructibleTreeV2.c:32
SCR_MainMenuEntity
Definition: ScriptedMainMenuEntity.c:11
SCR_DSSessionCallbackSessionStorage
Definition: SCR_SaveManagerCore.c:959
SCR_DSSessionCallback
Definition: SCR_DSSessionCallback.c:6
callback
DownloadConfigCallback callback
SCR_DebugMenuID
SCR_DebugMenuID
This enum contains all IDs for DiagMenu entries added in script.
Definition: DebugMenuID.c:3
SCR_EGameModeState
SCR_EGameModeState
Definition: SCR_EGameModeState.c:4
SCR_MissionHeader
Definition: SCR_MissionHeader.c:1
GetPageCount
protected int GetPageCount()
Returns page count, might depend on current mode.
Definition: SCR_ContentBrowser_AddonsSubMenu.c:987
BaseContainerProps
SCR_AIGoalReaction_Follow BaseContainerProps
Handles insects that are supposed to be spawned around selected prefabs defined in prefab names array...
Definition: SCR_AIGoalReaction.c:468