[OnWorldSave(Order = int.MaxValue)] // has to be last, obviously private static void SaveData() { if (!MyAPIGateway.Multiplayer.IsServer) { return; } try { // fetching data needs to happen on game thread as not every script has locks Builder_ArmsData data = new Builder_ArmsData(); data.SaveTime = Globals.ElapsedTimeTicks; data.ArmsVersion = Settings.ServerSettings.CurrentVersion; // network data Dictionary <long, RelayStorage.Builder_NetworkStorage> storages = new Dictionary <long, RelayStorage.Builder_NetworkStorage>(); Registrar.ForEach <RelayNode>(node => { if (node.Block != null && node.Storage != null && !storages.ContainsKey(node.Storage.PrimaryNode.EntityId)) { RelayStorage.Builder_NetworkStorage bns = node.Storage.GetBuilder(); if (bns != null) { storages.Add(bns.PrimaryNode, bns); } } }); data.AntennaStorage = storages.Values.ToArray(); // disruption List <Disruption.Builder_Disruption> systemDisrupt = new List <Disruption.Builder_Disruption>(); foreach (Disruption disrupt in Disruption.AllDisruptions) { systemDisrupt.Add(disrupt.GetBuilder()); } data.SystemDisruption = systemDisrupt.ToArray(); // autopilot List <ShipAutopilot.Builder_Autopilot> buildAuto = new List <ShipAutopilot.Builder_Autopilot>(); Registrar.ForEach <ShipAutopilot>(autopilot => { ShipAutopilot.Builder_Autopilot builder = autopilot.GetBuilder(); if (builder != null) { buildAuto.Add(builder); } }); data.Autopilot = buildAuto.ToArray(); // Sync data.Sync = ASync.GetBuilder(); MyAPIGateway.Utilities.SetVariable(SaveXml, MyAPIGateway.Utilities.SerializeToXML(data)); if (Instance.m_fileMaster != null) { string identifier = Instance.LegacyIdentifier(false); if (identifier != null) { if (Instance.m_fileMaster.Delete(identifier)) { Rynchodon.Logger.DebugLog("file deleted: " + identifier); } } } } catch (Exception ex) { Rynchodon.Logger.AlwaysLog("Exception: " + ex, Rynchodon.Logger.severity.ERROR); Rynchodon.Logger.Notify("ARMS: failed to save data", 60000, Rynchodon.Logger.severity.ERROR); } }