Exemplo n.º 1
0
    private static void WriteRawSaveDataToFile(SaveInformation saveInfo, string saveContent, Image screenshot,
                                               string saveName)
    {
        FileHelpers.MakeSureDirectoryExists(Constants.SAVE_FOLDER);
        var target = SaveFileInfo.SaveNameToPath(saveName);

        var justInfo = ThriveJsonConverter.Instance.SerializeObject(saveInfo);

        string tempScreenshot = null;

        if (screenshot != null)
        {
            // TODO: if in the future Godot allows converting images to in-memory PNGs that should be used here
            tempScreenshot = PathUtils.Join(Constants.SAVE_FOLDER, "tmp.png");
            if (screenshot.SavePng(tempScreenshot) != Error.Ok)
            {
                GD.PrintErr("Failed to save screenshot for inclusion in save");
                tempScreenshot = null;
            }
        }

        try
        {
            WriteDataToSaveFile(target, justInfo, saveContent, tempScreenshot);
        }
        finally
        {
            // Remove the temp file
            if (tempScreenshot != null)
            {
                FileHelpers.DeleteFile(tempScreenshot);
            }
        }
    }
    public void Save(SaveFileInfo file)
    {
        CreateSaveFileCache();
        string json = JsonUtility.ToJson(saveFileCache);

        Debug.Log(json);
    }
Exemplo n.º 3
0
    public static (SaveInformation Info, JObject SaveObject, Image Screenshot) LoadJSONStructureFromFile(
        string saveName)
    {
        var target = SaveFileInfo.SaveNameToPath(saveName);

        var(infoStr, saveStr, screenshotData) = LoadDataFromFile(target, true, true, true);

        if (string.IsNullOrEmpty(infoStr))
        {
            throw new IOException("couldn't find info content in save");
        }

        if (string.IsNullOrEmpty(saveStr))
        {
            throw new IOException("couldn't find save content in save file");
        }

        var infoResult = ThriveJsonConverter.Instance.DeserializeObject <SaveInformation>(infoStr);

        // Don't use the normal deserialization as we don't want to actually create the game state, instead we want
        // a JSON structure
        var saveResult = JObject.Parse(saveStr);

        var imageResult = new Image();

        if (screenshotData?.Length > 0)
        {
            imageResult.LoadPngFromBuffer(screenshotData);
        }

        return(infoResult, saveResult, imageResult);
    }
Exemplo n.º 4
0
        public bool TryLoadNewestWorld()
        {
            FileInfo fileInfo = (from wf in SavedWorldsDatabase.AllWorldFiles
                                 orderby wf.LastWriteTime descending
                                 select wf).FirstOrDefault <FileInfo>();

            if (fileInfo == null)
            {
                return(false);
            }

            SaveFileInfo saveFileInfo = new SaveFileInfo(fileInfo);

            if (VersionControl.BuildFromVersionString(saveFileInfo.GameVersion)
                != VersionControl.BuildFromVersionString(VersionControl.CurrentVersionFull))
            {
                return(false);
            }

            string fullName = fileInfo.FullName;

            WorldLoader.LoadWorldFromFile(fullName);

            if (!ModListsMatch(ScribeHeaderUtility.loadedModsList, (from mod in LoadedModManager.LoadedMods
                                                                    select mod.name).ToList()))
            {
                return(false);
            }

            return(true);
        }
Exemplo n.º 5
0
 public void SaveFile(SaveFileInfo fileInfo)
 {
     SaveFiles(new List <SaveFileInfo>()
     {
         fileInfo
     });
 }
Exemplo n.º 6
0
        private void FileWalker_DoWork(object sender, DoWorkEventArgs e)
        {
            SearchOption         o     = (RecursiveSearch) ? SearchOption.AllDirectories : SearchOption.TopDirectoryOnly;
            IEnumerable <string> files = Directory.EnumerateFiles(SelectedDirectory, "*.*", o);

            string currDir;
            string lastDir = null;

            foreach (string path in files)
            {
                if (SearchWorker.CancellationPending)
                {
                    e.Cancel = true;
                    break;
                }

                currDir = Path.GetDirectoryName(path);
                if (currDir != lastDir)
                {
                    lastDir = currDir;
                    TheWindow.SetStatusText(@$ "Searching {currDir}\...");   // TODO: path shortening func
                }

                if (SaveFileInfo.TryGetInfo(path, out SaveFileInfo info))
                {
                    SearchWorker.ReportProgress(-1, info);
                }
            }
        }
Exemplo n.º 7
0
    /// <summary>
    ///   Writes this save to disk.
    /// </summary>
    /// <remarks>
    ///   In order to save the screenshot as png this needs to save it to a temporary file on disk.
    /// </remarks>
    public void SaveToFile()
    {
        FileHelpers.MakeSureDirectoryExists(Constants.SAVE_FOLDER);
        var target = SaveFileInfo.SaveNameToPath(Name);

        var justInfo   = ThriveJsonConverter.Instance.SerializeObject(Info);
        var serialized = ThriveJsonConverter.Instance.SerializeObject(this);

        string tempScreenshot = null;

        if (Screenshot != null)
        {
            tempScreenshot = PathUtils.Join(Constants.SAVE_FOLDER, "tmp.png");
            if (Screenshot.SavePng(tempScreenshot) != Error.Ok)
            {
                GD.PrintErr("Failed to save screenshot for inclusion in save");
                Screenshot     = null;
                tempScreenshot = null;
            }
        }

        try
        {
            WriteDataToSaveFile(target, justInfo, serialized, tempScreenshot);
        }
        finally
        {
            // Remove the temp file
            if (tempScreenshot != null)
            {
                FileHelpers.DeleteFile(tempScreenshot);
            }
        }
    }
Exemplo n.º 8
0
        public bool TryLoadNewestWorld()
        {
            FileInfo fileInfo = ( from wf in SavedWorldsDatabase.AllWorldFiles
                                  orderby wf.LastWriteTime descending
                                  select wf ).FirstOrDefault<FileInfo>();
            if ( fileInfo == null )
            {
                return false;
            }

            SaveFileInfo saveFileInfo = new SaveFileInfo( fileInfo );
            if ( VersionControl.BuildFromVersionString( saveFileInfo.GameVersion )
                != VersionControl.BuildFromVersionString( VersionControl.CurrentVersionFull ) )
            {
                return false;
            }

            string fullName = fileInfo.FullName;
            WorldLoader.LoadWorldFromFile( fullName );

            if ( !ModListsMatch( ScribeHeaderUtility.loadedModsList, ( from mod in LoadedModManager.LoadedMods
                                                                       select mod.name ).ToList() ) )
            {
                return false;
            }

            return true;
        }
 public FileEntry(FileInfo file)
 {
     FileInfo     = new SaveFileInfo(file);
     Name         = Path.GetFileNameWithoutExtension(FileInfo.FileInfo.Name);
     Label        = Name;
     VersionLabel = string.Format("({0})", FileInfo.GameVersion);
 }
Exemplo n.º 10
0
    public static SaveInformation LoadJustInfoFromSave(string saveName)
    {
        var target = SaveFileInfo.SaveNameToPath(saveName);

        var(info, _, _) = LoadFromFile(target, true, false, false, null);

        return(info);
    }
Exemplo n.º 11
0
 protected override Color FileNameColor(SaveFileInfo sfi)
 {
     if (SaveGameFilesUtility.IsAutoSave(Path.GetFileNameWithoutExtension(sfi.FileInfo.Name)))
     {
         GUI.color = AutosaveTextColor;
     }
     return(base.FileNameColor(sfi));
 }
Exemplo n.º 12
0
 public void Refresh()
 {
     for (int i = 0; i < SaveFiles.Count; i++)
     {
         SaveFileInfo.TryGetInfo(SaveFiles[i].Path, out SaveFileInfo newInfo);
         SaveFiles[i] = newInfo;
     }
 }
Exemplo n.º 13
0
 void Awake()
 {
     DontDestroyOnLoad(this);
     saveFileCache   = new SaveFileInfo();
     settingFile     = new SettingSave();
     settingFilePath = Application.dataPath + "/Resources/Setting.json";
     LoadSettingFile();
 }
Exemplo n.º 14
0
    public static void SaveGame(SaveFileInfo levelsSave, int currentSaveFile = 0)
    {
        BinaryFormatter formatter = new BinaryFormatter();
        string          path      = Application.persistentDataPath + "/player" + currentSaveFile + ".slime";
        FileStream      stream    = new FileStream(path, FileMode.Create);

        formatter.Serialize(stream, levelsSave);
        stream.Close();
    }
Exemplo n.º 15
0
        protected override Color FileNameColor(SaveFileInfo sfi)
        {
            string fileNameWithoutExtension = Path.GetFileNameWithoutExtension(sfi.FileInfo.Name);

            if (SaveGameFilesUtility.IsAutoSave(fileNameWithoutExtension))
            {
                GUI.color = Dialog_SaveFileList.AutosaveTextColor;
            }
            return(base.FileNameColor(sfi));
        }
Exemplo n.º 16
0
    /// <summary>
    ///   Loads a save from a file or throws an exception
    /// </summary>
    /// <param name="saveName">The name of the save. This is not the full path.</param>
    /// <param name="readFinished">
    ///   A callback that is called when reading data has finished and creating objects start.
    /// </param>
    /// <returns>The loaded save</returns>
    public static Save LoadFromFile(string saveName, Action readFinished = null)
    {
        var target = SaveFileInfo.SaveNameToPath(saveName);

        var(_, save, screenshot) = LoadFromFile(target, false, true, true, readFinished);

        // Info is already contained in save so it doesn't need to be loaded and assigned here
        save.Screenshot = screenshot;

        return(save);
    }
Exemplo n.º 17
0
        public static bool LoadFile(string fileName, fsSerializer serializer, out SaveFileInfo saveFileInfo)
        {
            LoadFileResult result     = null;
            Thread         loadThread = new Thread(() => result = LoadFileAsync(fileName, serializer), 1024 * 1024 * 3);

            loadThread.Start();
            while (loadThread.IsAlive)
            {
            }
            saveFileInfo = result.success ? result.saveFileInfo : null;
            return(result.success);
        }
        private void DoImport(SaveFileInfo file)
        {
            try
            {
                // load stuff
                Scribe.InitLoading(_folder + "/" + file.FileInfo.Name);
                Manager.LoadSaveMode = Manager.Modes.ImportExport;
                ScribeMetaHeaderUtility.LoadGameDataHeader(ScribeMetaHeaderUtility.ScribeHeaderMode.Map, false);
                Scribe.EnterNode("JobStack");
                _jobStackIO.ExposeData();
                Scribe.ExitNode();
                Scribe.FinalizeLoading();

                // resolve crossreferences
                // these are registered during the loading stage, and cleared afterwards
                // will most definitely give errors/warnings on crossgame imports
                CrossRefResolver.ResolveAllCrossReferences();

                // replace the old jobstack
                Manager.For(manager).NewJobStack(_jobStackIO);

                // remove invalid jobs
                var invalid = 0;
                foreach (ManagerJob job in Manager.For(manager).JobStack.FullStack())
                {
                    if (!job.IsValid)
                    {
                        invalid++;
                        job.Delete(false);
                    }
                }

                // provide some feedback on failed import(s)
                // if debug is enabled the screen will also pop up with reference errors.
                if (invalid > 0)
                {
                    Messages.Message("FM.InvalidJobsDeleted".Translate(invalid), MessageSound.SeriousAlert);
                }
            }
            catch (Exception e)
            {
                Log.Error("Exception while loading jobstack: " + e);
            }
            finally
            {
                // done?
                Scribe.mode          = LoadSaveMode.Inactive;
                Manager.LoadSaveMode = Manager.Modes.Normal;
                Messages.Message("FM.JobsImported".Translate(_jobStackIO.FullStack().Count), MessageSound.Standard);
                Refresh();
            }
        }
Exemplo n.º 19
0
    public static Save LoadInfoAndScreenshotFromSave(string saveName)
    {
        var target = SaveFileInfo.SaveNameToPath(saveName);

        var(info, _, screenshot) = LoadFromFile(target, true, false, true, null);

        var save = new Save();

        save.Name       = saveName;
        save.Info       = info;
        save.Screenshot = screenshot;

        return(save);
    }
Exemplo n.º 20
0
    public static string DisplayNameToSaveName(string inDisplayName)
    {
        string str = SaveFileInfo.TrimAutoSaves(inDisplayName);

        foreach (char invalidFileNameChar in System.IO.Path.GetInvalidFileNameChars())
        {
            str = str.Replace(invalidFileNameChar, '_');
        }
        foreach (char invalidPathChar in System.IO.Path.GetInvalidPathChars())
        {
            str = str.Replace(invalidPathChar, '_');
        }
        return(str.ToLowerInvariant());
    }
Exemplo n.º 21
0
        public static void LoadSaveFiles()
        {
            allSaveFiles = new List <SaveFileInfo>();

            foreach (FileInfo allSavedGameFile in GenFilePaths.AllSavedGameFiles)
            {
                try {
                    SaveFileInfo saveFile = new SaveFileInfo(allSavedGameFile);
                    allSaveFiles.Add(saveFile);
                    Main.LogMessage("Loaded save file: " + saveFile.FileInfo.FullName);
                } catch (Exception ex) {
                    Log.Error("Exception loading " + allSavedGameFile.Name + ": " + ex.ToString());
                }
            }
        }
Exemplo n.º 22
0
    public static SaveInformation LoadJustInfoFromSave(string saveName)
    {
        var target = SaveFileInfo.SaveNameToPath(saveName);

        try
        {
            var(info, _, _) = LoadFromFile(target, true, false, false, null);

            return(info);
        }
        catch (Exception e)
        {
            GD.PrintErr($"Failed to load save info from ${saveName}, error: ${e}");
            return(SaveInformation.CreateInvalid());
        }
    }
        public static void DrawDateAndVersion(SaveFileInfo sfi, Rect rect)
        {
            GUI.BeginGroup(rect);
            Text.Font   = GameFont.Tiny;
            Text.Anchor = TextAnchor.UpperLeft;
            Rect rect2 = new Rect(0f, 2f, rect.width, rect.height / 2f);

            GUI.color = SaveFileInfo.UnimportantTextColor;
            Widgets.Label(rect2, sfi.FileInfo.LastWriteTime.ToString("g"));
            Rect rect3 = new Rect(0f, rect2.yMax, rect.width, rect.height / 2f);

            GUI.color = sfi.VersionColor;
            Widgets.Label(rect3, sfi.GameVersion);
            TooltipHandler.TipRegion(rect3, sfi.CompatibilityTip);
            GUI.EndGroup();
        }
Exemplo n.º 24
0
        public void UpdatePreferenceSaveFileInfo(int file, SaveFileInfo info)
        {
            if (file == 0)
            {
                DataHelper.PreferenceData.File0Info = info;
            }
            else if (file == 1)
            {
                DataHelper.PreferenceData.File1Info = info;
            }
            else if (file == 2)
            {
                DataHelper.PreferenceData.File2Info = info;
            }

            _backgroundThread.AddPreferenceRequest(DataHelper.PreferenceData.Copy());
        }
        private void DrawFileEntry(Rect rect, SaveFileInfo file)
        {
            GUI.BeginGroup(rect);

            // set up rects
            Rect nameRect = rect.AtZero();

            nameRect.width -= 200f + _iconSize + 4 * _margin;
            nameRect.xMin  += _margin;
            var timeRect   = new Rect(nameRect.xMax + _margin, 0f, 100f, rect.height);
            var buttonRect = new Rect(timeRect.xMax + _margin, 1f, 100f, rect.height - 2f);
            var deleteRect = new Rect(buttonRect.xMax + _margin, (rect.height - _iconSize) / 2, _iconSize, _iconSize);

            // name
            Text.Anchor = TextAnchor.MiddleLeft;
            Widgets.Label(nameRect, Path.GetFileNameWithoutExtension(file.FileInfo.Name));
            Text.Anchor = TextAnchor.UpperLeft;

            // timestamp
            GUI.color = Color.gray;
            Dialog_FileList.DrawDateAndVersion(file, timeRect);
            Text.Font = GameFont.Small;
            GUI.color = Color.white;

            // load button
            if (Widgets.ButtonText(buttonRect, "FM.Import".Translate()))
            {
                TryImport(file);
            }

            // delete button
            if (Widgets.ButtonImage(deleteRect, Resources.DeleteX))
            {
                Find.WindowStack.Add(new Dialog_Confirm("ConfirmDelete".Translate(file.FileInfo.Name), delegate
                {
                    file
                    .FileInfo
                    .Delete
                        ();
                    Refresh
                        ();
                }, true));
            }

            GUI.EndGroup();
        }
Exemplo n.º 26
0
 public static void SaveFile(string openFilePath, fsSerializer serializer, SaveFileInfo saveFileInfo)
 {
     try
     {
         fsData   data1;
         fsResult fsResult1 = serializer.TrySerialize(saveFileInfo, out data1);
         if (fsResult1.Failed)
         {
             throw new Exception(string.Format("Failed to serialise SaveFileInfo: {0}", fsResult1.FormattedMessages));
         }
         string   s1 = fsJsonPrinter.CompressedJson(data1);
         fsData   data2;
         fsResult fsResult2 = serializer.TrySerialize(Game.instance, out data2);
         if (fsResult2.Failed)
         {
             throw new Exception(string.Format("Failed to serialise Game: {0}",
                                               fsResult2.FormattedMessages));
         }
         string s2     = fsJsonPrinter.CompressedJson(data2);
         byte[] bytes1 = Encoding.UTF8.GetBytes(s1);
         byte[] bytes2 = Encoding.UTF8.GetBytes(s2);
         Debug.Assert(bytes1.Length < 268435456 && bytes2.Length < 268435456, "Uh-oh. Ben has underestimated how large save files might get, and we're about to save a file so large it will be detected as corrupt when loading. Best increase the limit!", null);
         byte[]   buffer1  = LZ4Codec.Encode(bytes1, 0, bytes1.Length);
         byte[]   buffer2  = LZ4Codec.Encode(bytes2, 0, bytes2.Length);
         FileInfo fileInfo = new FileInfo(openFilePath);
         using (FileStream fileStream = File.Create(fileInfo.FullName))
         {
             using (BinaryWriter binaryWriter = new BinaryWriter(fileStream))
             {
                 binaryWriter.Write(1932684653);
                 binaryWriter.Write(saveFileVersion);
                 binaryWriter.Write(buffer1.Length);
                 binaryWriter.Write(bytes1.Length);
                 binaryWriter.Write(buffer2.Length);
                 binaryWriter.Write(bytes2.Length);
                 binaryWriter.Write(buffer1);
                 binaryWriter.Write(buffer2);
             }
         }
     }
     catch (Exception ex)
     {
         MessageBoxResult result = MessageBox.Show(ex.Message, "Exception", MessageBoxButton.OK, MessageBoxImage.Error);
     }
 }
Exemplo n.º 27
0
    public static SaveFileInfo LoadGame(int currentSaveFile = 0)
    {
        string path = Application.persistentDataPath + "/player" + currentSaveFile + ".slime";

        if (File.Exists(path))
        {
            BinaryFormatter formatter = new BinaryFormatter();
            FileStream      stream    = new FileStream(path, FileMode.Open);
            SaveFileInfo    save      = formatter.Deserialize(stream) as SaveFileInfo;
            stream.Close();
            return(save);
        }
        else
        {
            Debug.LogWarning("Save File not found in : " + path);
            return(null);
        }
    }
Exemplo n.º 28
0
    public static SaveFileInfo Create(string name, bool isAutoSave)
    {
        SaveFileInfo saveFileInfo = new SaveFileInfo();

        saveFileInfo.saveInfo = new SaveFileInfo.SaveInfo()
        {
            name       = name,
            date       = DateTime.Now,
            version    = GameVersionNumber.version,
            isAutoSave = isAutoSave
        };
        Game instance = Game.instance;

        saveFileInfo.gameInfo.isChallenge        = Game.instance.challengeManager.IsAttemptingChallenge();
        saveFileInfo.gameInfo.gameTime           = DateTime.Now;
        saveFileInfo.gameInfo.teamName           = instance.player.team.name;
        saveFileInfo.gameInfo.teamLogoID         = instance.player.team.teamID;
        saveFileInfo.gameInfo.teamColor          = null;//TeamColorManager.Instance.GetColor(instance.player.team.colorID);
        saveFileInfo.gameInfo.championship       = instance.player.team.championship.GetChampionshipName(false);
        saveFileInfo.gameInfo.championshipID     = instance.player.team.championship.championshipID;
        saveFileInfo.gameInfo.championshipSeries = instance.player.team.championship.series;
        saveFileInfo.gameInfo.playerName         = instance.player.name;
        saveFileInfo.gameInfo.playerAge          = instance.player.GetAge();
        saveFileInfo.gameInfo.playerGender       = instance.player.gender;
        saveFileInfo.gameInfo.playerPortrait     = instance.player.portrait;
        saveFileInfo.gameInfo.playerNationality  = instance.player.nationality;
        saveFileInfo.gameInfo.teamLogo           = !instance.player.team.isCreatedByPlayer ? (TeamLogo)null : instance.player.team.customLogo;
        Team team = instance.player.careerHistory.currentTeam != null ? instance.player.careerHistory.currentTeam : instance.player.careerHistory.previousTeam;

        saveFileInfo.gameInfo.seasonNumber  = team.championship.standingsHistory.historyCount + 1;
        saveFileInfo.gameInfo.raceNumber    = team.championship.eventNumberForUI;
        saveFileInfo.gameInfo.racesInSeason = team.championship.eventCount;
        for (int index = 0; index < CarManager.carCount; ++index)
        {
            saveFileInfo.gameInfo.playerTeamCarData[index] = instance.player.team != Game.instance.teamManager.nullTeam ? instance.player.team.carManager.GetCar(index).GetDataForCar(index) : new FrontendCarData();
        }
        //if (SteamManager.Initialized)
        //  saveFileInfo.subscribedModsInfo = instance.savedSubscribedModsInfo;
        //for (int index = 0; index < App.instance.dlcManager.allDlc.Count; ++index)
        //  saveFileInfo.ownedDLCInfo.Add(App.instance.dlcManager.allDlc[index]);
        return(saveFileInfo);
    }
Exemplo n.º 29
0
        public void PopulateList()
        {
            List <string> toRemove = new List <string>();

            foreach (string path in TheSettings.WelcomeList)
            {
                if (!SaveFileInfo.TryGetInfo(path, out SaveFileInfo info))
                {
                    toRemove.Add(path);
                    continue;
                }
                SaveFiles.Add(info);
            }

            if (toRemove.Count > 0)
            {
                foreach (string path in toRemove)
                {
                    TheSettings.WelcomeList.Remove(path);
                }
            }
        }
Exemplo n.º 30
0
            public static bool TryGetInfo(string path, out SaveFileInfo info)
            {
                if (Editor.TryOpenFile(path, out LCSSave saveFile))
                {
                    string lastMissionPassedKey = saveFile.Stats.LastMissionPassedName;
                    if (!Gxt.TheText.TryGetValue("MAIN", lastMissionPassedKey, out string title))
                    {
                        title = $"(invalid GXT key: {lastMissionPassedKey})";
                    }

                    saveFile.SimpleVars.TimeStamp.TryGetDateTime(out DateTime timeStamp);
                    if (!saveFile.FileFormat.IsPS2)
                    {
                        timeStamp = File.GetLastWriteTime(path);
                    }

                    info = new SaveFileInfo()
                    {
                        SaveFile     = saveFile,
                        Path         = path,
                        FileType     = saveFile.FileFormat,
                        LastModified = timeStamp,
                        Title        = title
                    };

                    return(true);
                }

                info = new SaveFileInfo()
                {
                    SaveFile     = null,
                    Path         = path,
                    FileType     = FileFormat.Default,
                    LastModified = DateTime.MinValue,
                    Title        = "(invalid save file)"
                };

                return(false);
            }
Exemplo n.º 31
0
        internal static Blueprint LoadFromXML(SaveFileInfo file)
        {
            // set up empty blueprint
            Blueprint blueprint = new Blueprint();

#if DEBUG
            Log.Message("Attempting to load from: " + file.FileInfo.FullName);
#endif

            // load stuff
            try
            {
                Scribe.InitLoading(BlueprintSaveLocation + "/" + file.FileInfo.Name);
                ScribeMetaHeaderUtility.LoadGameDataHeader(ScribeMetaHeaderUtility.ScribeHeaderMode.Map, true);
                Scribe.EnterNode("Blueprint");
                blueprint.ExposeData();
                Scribe.ExitNode();
            }
            catch (Exception e)
            {
                Log.Error("Exception while loading blueprint: " + e);
            }
            finally
            {
                // done loading
                Scribe.FinalizeLoading();
                Scribe.mode = LoadSaveMode.Inactive;
            }

            // if a def used in the blueprint doesn't exist, exposeData will throw an error,
            // which is fine. in addition, it'll set the field to null - which may result in problems down the road.
            // Make sure each item in the blueprint has a def set, if not - remove it.
            // This check itself will throw another error, which is also fine. User will have to resolve the issue manually.
            blueprint.contents = blueprint.contents.Where(item => item.BuildableDef != null).ToList();

            // return blueprint.
            return(blueprint);
        }
 private void TryImport( SaveFileInfo file )
 {
     // TODO some basic checks?
     DoImport( file );
 }
        private void DoImport( SaveFileInfo file )
        {
            try
            {
                // load stuff
                Scribe.InitLoading( _folder + "/" + file.FileInfo.Name );
                Manager.LoadSaveMode = Manager.Modes.ImportExport;
                ScribeHeaderUtility.LoadGameDataHeader( ScribeHeaderUtility.ScribeHeaderMode.Map );
                Scribe.EnterNode( "JobStack" );
                _jobStackIO.ExposeData();
                Scribe.ExitNode();
                Scribe.FinalizeLoading();

                // resolve crossreferences
                // these are registered during the loading stage, and cleared afterwards
                // will most definitely give errors/warnings on crossgame imports
                CrossRefResolver.ResolveAllCrossReferences();

                // replace the old jobstack
                Manager.Get.NewJobStack( _jobStackIO );

                // remove invalid jobs
                int invalid = 0;
                foreach ( ManagerJob job in Manager.Get.JobStack.FullStack() )
                {
                    if ( !job.IsValid )
                    {
                        invalid++;
                        job.Delete( false );
                    }
                }

                // provide some feedback on failed import(s)
                // if debug is enabled the screen will also pop up with reference errors.
                if ( invalid > 0 )
                {
                    Messages.Message( "FM.InvalidJobsDeleted".Translate( invalid ), MessageSound.SeriousAlert );
                }
            }
            catch ( Exception e )
            {
                Log.Error( "Exception while loading jobstack: " + e );
            }
            finally
            {
                // done?
                Scribe.mode = LoadSaveMode.Inactive;
                Manager.LoadSaveMode = Manager.Modes.Normal;
                Messages.Message( "FM.JobsImported".Translate( _jobStackIO.FullStack().Count ), MessageSound.Standard );
                Refresh();
            }
        }
        private void DrawFileEntry( Rect rect, SaveFileInfo file )
        {
            GUI.BeginGroup( rect );

            // set up rects
            Rect nameRect = rect.AtZero();
            nameRect.width -= 200f + _iconSize + 4 * _margin;
            nameRect.xMin += _margin;
            Rect timeRect = new Rect( nameRect.xMax + _margin, 0f, 100f, rect.height );
            Rect buttonRect = new Rect( timeRect.xMax + _margin, 1f, 100f, rect.height - 2f );
            Rect deleteRect = new Rect( buttonRect.xMax + _margin, ( rect.height - _iconSize ) / 2, _iconSize, _iconSize );

            // name
            Text.Anchor = TextAnchor.MiddleLeft;
            Widgets.Label( nameRect, Path.GetFileNameWithoutExtension( file.FileInfo.Name ) );
            Text.Anchor = TextAnchor.UpperLeft;

            // timestamp
            GUI.color = Color.gray;
            Dialog_MapList.DrawDateAndVersion( file, timeRect );
            Text.Font = GameFont.Small;
            GUI.color = Color.white;

            // load button
            if ( Widgets.TextButton( buttonRect, "FM.Import".Translate() ) )
            {
                TryImport( file );
            }

            // delete button
            if ( Widgets.ImageButton( deleteRect, Resources.DeleteX ) )
            {
                Find.WindowStack.Add( new Dialog_Confirm( "ConfirmDelete".Translate( file.FileInfo.Name ), delegate
                {
                    file.FileInfo.Delete();
                    Refresh();
                }, true ) );
            }

            GUI.EndGroup();
        }