/// <summary> /// Takes the name of the Unity stored TextAsset and reserializes it to a persistent location for access and modification /// </summary> /// <param name="fileName">Name of the file in the Resources Folder</param> private static void unpackFile(string fileName) { try { TextAsset textAsset = Resources.Load(fileName) as TextAsset; MemoryStream memoryStream = new MemoryStream(textAsset.bytes); string filePath = UnityTools.getPersistentFilePath() + "/" + filenamePrefix + fileName + fileNameExtension; FileStream fileStream = new FileStream(filePath, FileMode.Create, FileAccess.Write); memoryStream.WriteTo(fileStream); fileStream.Close(); memoryStream.Close(); } catch (IOException) { string message = "When trying to unpack file '" + fileName + "', an IO exception occured and the file was not unpacked."; DS_MessageLogger.logMessageToBuildFile(message, SerializerLogType.Error); return; } catch (Exception) { string message = "When trying to unpack file '" + fileName + "', an unknown exception occured and the file was not unpacked."; DS_MessageLogger.logMessageToBuildFile(message, SerializerLogType.Error); } }
/// <summary> /// Deserializes a file from the Unity Resources folder and returns it as the provided object type. /// </summary> /// <typeparam name="T">Object type to deserialize file into</typeparam> /// <param name="fileName">Name of the file to deserialize</param> /// <returns>Deserialized file in the provided type</returns> private static T loadFromPersistentFolder <T> (string fileName) { string filePath = UnityTools.getPersistentFilePath() + "/" + fileName; //make sure file exists if (SystemTools.fileExists(filePath) == false) { DS_MessageLogger.logMessageToUnityConsole("Failed to find file '" + fileName + "' when loading the" + "file for deserialization on the loadSave() call.", SerializerLogType.Warning); return(default(T)); } //Try to load the file try { BinaryFormatter binaryFormatter = new BinaryFormatter(); FileStream fileStream = new FileStream(filePath, FileMode.Open); T returnObject = (T)binaryFormatter.Deserialize(fileStream); fileStream.Close(); return(returnObject); } catch (IOException) { DS_MessageLogger.logMessageToUnityConsole("An IO exception occurred while trying to load '" + fileName + "' in the Persistent build folder.", SerializerLogType.Error); return(default(T)); } catch (Exception) { DS_MessageLogger.logMessageToUnityConsole("An unknown exception occurred while trying to load '" + fileName + "' in the Persistent build folder.", SerializerLogType.Error); return(default(T)); } }
/// <summary> /// Makes sure the folder used for non-deplyed files is available to save binaries to. /// </summary> private static void makeSureNonPersistentPathExists() { //If the folder doesn't exist, create it if (Directory.Exists(nonPersistentFilePath) == false) { Directory.CreateDirectory(nonPersistentFilePath); //Log message that we're creating a Folder for the devs DS_MessageLogger.logMessageToUnityConsole("Failed to find the DeveloperBinaries folder in your Assets folder. " + "Creating the folder for your project. \n" + "This folder is used by the asset to store saves that will not be accessible in builds of the game", SerializerLogType.Standard); } }
/// <summary> /// Makes sure the Resources folder exists under the Assets folder. If it doesn't exist, create it. /// </summary> private static void makeSureResourcesExists() { //If the folder doesn't exist, create it if (Directory.Exists(resourcesFilePath) == false) { Directory.CreateDirectory(resourcesFilePath); //Log message that we're creating a Folder for the devs DS_MessageLogger.logMessageToUnityConsole("Failed to find the Resources folder in your Assets folder. Creating Resources folder " + "for your project. \n" + "This is required for any persistent object saving between the engine and the game build.", SerializerLogType.Standard); } }
/// <summary> /// Call this in the game build to take all persistent files and load them into the PersistentPath directory /// </summary> /// <returns>Boolean indicating if the unpack was sucessful</returns> public static bool unpackPersistentSaves() { //Make sure the file exists TextAsset ta = Resources.Load(fileNameTrackerName) as TextAsset; if (ta == null) { DS_MessageLogger.logMessageToBuildFile("Failed to find FileNameTracker File, either no saves were created or file was deleted", SerializerLogType.Warning); return(false); } FileNameTracker fileNameTracker = null; //Deserialize the file to read from try { BinaryFormatter binaryFormatter = new BinaryFormatter(); MemoryStream mStream = new MemoryStream(ta.bytes); fileNameTracker = binaryFormatter.Deserialize(mStream) as FileNameTracker; } catch (IOException) { DS_MessageLogger.logMessageToBuildFile("IO Failure when trying to deserialize the FileNameTracker while unpacking the " + "persistent binaries.", SerializerLogType.Error); return(false); } catch (Exception) { DS_MessageLogger.logMessageToBuildFile("General failure when trying to deserialize the FileNameTracker while unpacking the " + "persistent binaries.", SerializerLogType.Error); return(false); } //Load all saved files into the persistent folder foreach (string fileName in fileNameTracker.fileNames) { unpackFile(fileName); } return(true); }
/// <summary> /// Saves the object to a binary file in the PersistentPath for post deployment saves /// </summary> /// <typeparam name="T">Object type to be serialized</typeparam> /// <param name="objectToSave">Object to be serialized</param> /// <param name="fileName">Name to save the file under</param> private static void serializeObject_Build(object objectToSave, string fileName) { //Initialize objects for use BinaryFormatter binaryFormatter; FileStream fileStream; //Build file name and save reference fileName = filenamePrefix + fileName; string filePath = UnityTools.getPersistentFilePath() + "/" + filenamePrefix + fileName + fileNameExtension; //Serialize the new Object provided by the Dev try { //Create stream and formatter binaryFormatter = new BinaryFormatter(); fileStream = new FileStream(filePath, FileMode.Create); //Serialize file and close stream binaryFormatter.Serialize(fileStream, objectToSave); fileStream.Close(); } catch (IOException) { DS_MessageLogger.logMessageToUnityConsole("An unexpected IO failure occured when trying to serialize the provided object to the" + " Persistent File Path in build. " + "Process is being aborted! \n" + "Class Name: " + SystemTools.getObjectName(objectToSave), SerializerLogType.Error); return; } catch (Exception) { DS_MessageLogger.logMessageToUnityConsole("An unknown failure occured when trying to serialize the provided object to the " + " Persistent File Path in build." + "Process is being aborted! \n" + "Class Name: " + SystemTools.getObjectName(objectToSave), SerializerLogType.Error); return; } //Log the save if messages are enabled DS_MessageLogger.logMessageToUnityConsole(SystemTools.getObjectName(objectToSave) + " was saved successfully", SerializerLogType.Standard); }
/// <summary> /// Saves the provided Object to a binary file. If marked as persistent the file is saved to the Resources folder to be rebuilt for /// builds of the game. If called in game build the isPersistentInBuild parameter is ignored. /// </summary> /// <typeparam name="T">Type of Object to save</typeparam> /// <param name="objectToSave">Object to be saved</param> /// <param name="isPersistentInBuild">Determines if the file is saved to the resources folder to keep persistent in game build</param> public static void saveObject(object objectToSave, string fileName, bool isPersistentInBuild) { //Preliminary check to make sure the provided Object is serializable if (SystemTools.isSerializable(objectToSave) == false) { DS_MessageLogger.logNonSerializableObjectCall(objectToSave); return; } //Check if we're running in build or engine - Save to correct location if (UnityTools.isRunningInEngine()) { //Guarentee file paths exists makeSureResourcesExists(); makeSureNonPersistentPathExists(); //Saves the object to the persistent location using a thread. //Threading is used to make sure that OS read/write cycles do not prevent multiple saves from stopping each other from updating //or saving to the FNTP file if (isPersistentInBuild) { Thread saveThread = new Thread(() => serializeObject_Persistent(objectToSave, fileName)); saveThread.Start(); } //Save to DevelopmentBinaries for dev only else { serializeObject_Developer(objectToSave, fileName); } } //Otherwise we're in a build of the game and can save normally else { serializeObject_Build(objectToSave, fileName); } }
/// <summary> /// /// </summary> /// <param name="objectToSave"></param> /// <param name="fileName"></param> private static void serializeObject_Persistent(object objectToSave, string fileName, int attemptsRemaining) { //Initialize objects for use BinaryFormatter binaryFormatter; FileStream fileStream; FileNameTracker fileNameTracker; ////Get a valid copy of the FileNameTracker //If the file tracker exists we deserialize it if (SystemTools.fileExists(fileNamesTrackerPath)) { try { binaryFormatter = new BinaryFormatter(); fileStream = new FileStream(fileNamesTrackerPath, FileMode.Open); fileNameTracker = binaryFormatter.Deserialize(fileStream) as FileNameTracker; fileStream.Close(); } catch (IOException) { //DS_MessageLogger.logMessageToUnityConsole("An unexpected IO failure occured when trying to open the FileNameTracker" + // " binary stored in the Resources Folder. Object saving process is being aborted!", SerializerLogType.Error); Debug.Log("File already open, waiting then trying again"); //System.Threading.Thread.Sleep(500); //serializeObject_Persistent(objectToSave, fileName); return; } catch (Exception) { DS_MessageLogger.logMessageToUnityConsole("An unknown failure occured when trying to open the FileNameTracker" + " binary stored in the Resources Folder. Onject saving process is being aborted!", SerializerLogType.Error); return; } } //Otherwise we need to make it else { fileNameTracker = new FileNameTracker(); } //Build file name and save reference fileName = filenamePrefix + fileName; string filePath = resourcesFilePath + fileName + fileNameExtension; //Serialize the new Object provided by the Dev try { //Create stream and formatter binaryFormatter = new BinaryFormatter(); fileStream = new FileStream(filePath, FileMode.Create); //Serialize file and close stream binaryFormatter.Serialize(fileStream, objectToSave); fileStream.Close(); } catch (IOException) { DS_MessageLogger.logMessageToUnityConsole("An unexpected IO failure occured when trying to serialize the provided object to the " + "Resources Folder for persistance. " + "Process is being aborted! \n" + "Class Name: " + SystemTools.getObjectName(objectToSave), SerializerLogType.Error); return; } catch (Exception) { DS_MessageLogger.logMessageToUnityConsole("An unknown failure occured when trying to serialize the provided object to the " + "Resources Folder for persistance." + "Process is being aborted! \n" + "Class Name: " + SystemTools.getObjectName(objectToSave), SerializerLogType.Error); return; } //Serialize the FileNameTracker for persistence try { //Add the new file name fileNameTracker.fileNames.Add(fileName); //Create stream and formatter binaryFormatter = new BinaryFormatter(); fileStream = new FileStream(fileNamesTrackerPath, FileMode.Create); //Serialize the file and close the stream binaryFormatter.Serialize(fileStream, fileNameTracker); } catch (IOException) { DS_MessageLogger.logMessageToUnityConsole("An unexpected IO failure occured when trying to serialize the FileNameTracker object. " + "Process is being aborted!", SerializerLogType.Error); return; } catch (Exception) { DS_MessageLogger.logMessageToUnityConsole("An unknown failure occured when trying to serialize the FileNameTracker object. " + "Process is being aborted!", SerializerLogType.Error); return; } //Log the save if messages are enabled DS_MessageLogger.logMessageToUnityConsole(SystemTools.getObjectName(objectToSave) + " was saved successfully", SerializerLogType.Standard); }