IndieGame/client/Assets/Plugins/Easy Save 3/Scripts/ES3IO.cs

178 lines
6.9 KiB
C#
Raw Normal View History

2024-10-11 10:12:15 +08:00
using System.IO;
using System;
using UnityEngine;
namespace ES3Internal
{
public static class ES3IO
{
#if UNITY_SWITCH
internal static readonly string persistentDataPath = "";
internal static readonly string dataPath = "";
#else
internal static readonly string persistentDataPath = Application.persistentDataPath;
internal static readonly string dataPath = Application.dataPath;
#endif
internal const string backupFileSuffix = ".bac";
internal const string temporaryFileSuffix = ".tmp";
public enum ES3FileMode { Read, Write, Append }
public static DateTime GetTimestamp(string filePath)
{
if (!FileExists(filePath))
return new DateTime(1970, 1, 1, 0, 0, 0, 0, System.DateTimeKind.Utc);
return File.GetLastWriteTime(filePath).ToUniversalTime();
}
public static string GetExtension(string path)
{
return Path.GetExtension(path);
}
public static void DeleteFile(string filePath)
{
if (FileExists(filePath))
File.Delete(filePath);
}
public static bool FileExists(string filePath) { return File.Exists(filePath); }
public static void MoveFile(string sourcePath, string destPath) { File.Move(sourcePath, destPath); }
public static void CopyFile(string sourcePath, string destPath) { File.Copy(sourcePath, destPath); }
public static void MoveDirectory(string sourcePath, string destPath) { Directory.Move(sourcePath, destPath); }
public static void CreateDirectory(string directoryPath) { Directory.CreateDirectory(directoryPath); }
public static bool DirectoryExists(string directoryPath) { return Directory.Exists(directoryPath); }
/*
* Given a path, it returns the directory that path points to.
* eg. "C:/myFolder/thisFolder/myFile.txt" will return "C:/myFolder/thisFolder".
*/
public static string GetDirectoryPath(string path, char seperator = '/')
{
//return Path.GetDirectoryName(path);
// Path.GetDirectoryName turns forward slashes to backslashes in some cases on Windows, which is why
// Substring is used instead.
char slashChar = UsesForwardSlash(path) ? '/' : '\\';
int slash = path.LastIndexOf(slashChar);
// If this path ends in a slash it is assumed to already be a path to a Directory.
if (slash == path.Length - 1)
return path;
// Ignore trailing slash if necessary.
if (slash == (path.Length - 1))
slash = path.Substring(0, slash).LastIndexOf(slashChar);
if (slash == -1)
ES3Debug.LogError("Path provided is not a directory path as it contains no slashes.");
return path.Substring(0, slash);
}
public static bool UsesForwardSlash(string path)
{
if (path.Contains("/"))
return true;
return false;
}
// Takes a directory path and a file or directory name and combines them into a single path.
public static string CombinePathAndFilename(string directoryPath, string fileOrDirectoryName)
{
if (directoryPath[directoryPath.Length - 1] != '/' && directoryPath[directoryPath.Length - 1] != '\\')
directoryPath += '/';
return directoryPath + fileOrDirectoryName;
}
public static string[] GetDirectories(string path, bool getFullPaths = true)
{
var paths = Directory.GetDirectories(path);
for (int i = 0; i < paths.Length; i++)
{
if (!getFullPaths)
paths[i] = Path.GetFileName(paths[i]);
// GetDirectories sometimes returns backslashes, so we need to convert them to
// forward slashes.
paths[i].Replace("\\", "/");
}
return paths;
}
public static void DeleteDirectory(string directoryPath)
{
if (DirectoryExists(directoryPath))
Directory.Delete(directoryPath, true);
}
// Note: Paths not ending in a slash are assumed to be a path to a file.
// In this case the Directory containing the file will be searched.
public static string[] GetFiles(string path, bool getFullPaths = true)
{
var paths = Directory.GetFiles(GetDirectoryPath(path));
if (!getFullPaths)
{
for (int i = 0; i < paths.Length; i++)
paths[i] = Path.GetFileName(paths[i]);
}
return paths;
}
public static byte[] ReadAllBytes(string path)
{
return File.ReadAllBytes(path);
}
public static void WriteAllBytes(string path, byte[] bytes)
{
File.WriteAllBytes(path, bytes);
}
public static void CommitBackup(ES3Settings settings)
{
ES3Debug.Log("Committing backup for " + settings.path + " to storage location " + settings.location);
var temporaryFilePath = settings.FullPath + temporaryFileSuffix;
if (settings.location == ES3.Location.File)
{
var oldFileBackup = settings.FullPath + temporaryFileSuffix + ".bak";
// If there's existing save data to overwrite ...
if (FileExists(settings.FullPath))
{
// Delete any old backups.
DeleteFile(oldFileBackup);
// Rename the old file so we can restore it if it fails.
CopyFile(settings.FullPath, oldFileBackup);
try
{
// Delete the old file so that we can move it.
DeleteFile(settings.FullPath);
// Now rename the temporary file to the name of the save file.
MoveFile(temporaryFilePath, settings.FullPath);
}
catch (Exception e)
{
// If any exceptions occur, restore the original save file.
try { DeleteFile(settings.FullPath); } catch { }
MoveFile(oldFileBackup, settings.FullPath);
throw e;
}
DeleteFile(oldFileBackup);
}
// Else just rename the temporary file to the main file.
else
MoveFile(temporaryFilePath, settings.FullPath);
}
else if (settings.location == ES3.Location.PlayerPrefs)
{
PlayerPrefs.SetString(settings.FullPath, PlayerPrefs.GetString(temporaryFilePath));
PlayerPrefs.DeleteKey(temporaryFilePath);
PlayerPrefs.Save();
}
}
}
}