using System.Collections;
using System.Collections.Generic;
using System.IO;
using System.Text;
using BayatGames.SaveGameFree.Encoders;
using BayatGames.SaveGameFree.Serializers;
using UnityEngine;
using UnityEngine.Networking;
namespace BayatGames.SaveGameFree
{
///
/// Save game path. base paths for your save games.
///
public enum SaveGamePath
{
///
/// The persistent data path. Application.persistentDataPath
///
PersistentDataPath,
///
/// The data path. Application.dataPath
///
DataPath
}
///
/// Save Game.
/// Use these APIs to Save & Load game data.
/// If you are looking for Web saving and loading use SaveGameWeb.
///
public static class SaveGame
{
///
/// Save handler.
///
public delegate void SaveHandler(object obj, string identifier, bool encode, string password, ISaveGameSerializer serializer, ISaveGameEncoder encoder, Encoding encoding, SaveGamePath path);
///
/// Load handler.
///
public delegate void LoadHandler(object loadedObj, string identifier, bool encode, string password, ISaveGameSerializer serializer, ISaveGameEncoder encoder, Encoding encoding, SaveGamePath path);
///
/// Occurs when on saved.
///
public static event SaveHandler OnSaved;
///
/// Occurs when on loaded.
///
public static event LoadHandler OnLoaded;
///
/// The save callback.
///
public static SaveHandler SaveCallback;
///
/// The load callback.
///
public static LoadHandler LoadCallback;
private static ISaveGameSerializer m_Serializer = new SaveGameJsonSerializer();
private static ISaveGameEncoder m_Encoder = new SaveGameSimpleEncoder();
private static Encoding m_Encoding = Encoding.UTF8;
private static bool m_Encode = false;
private static SaveGamePath m_SavePath = SaveGamePath.PersistentDataPath;
private static string m_EncodePassword = "h@e#ll$o%^";
private static bool m_LogError = false;
///
/// Gets or sets the serializer.
///
/// The serializer.
public static ISaveGameSerializer Serializer
{
get
{
if (m_Serializer == null)
{
m_Serializer = new SaveGameJsonSerializer();
}
return m_Serializer;
}
set
{
m_Serializer = value;
}
}
///
/// Gets or sets the encoder.
///
/// The encoder.
public static ISaveGameEncoder Encoder
{
get
{
if (m_Encoder == null)
{
m_Encoder = new SaveGameSimpleEncoder();
}
return m_Encoder;
}
set
{
m_Encoder = value;
}
}
///
/// Gets or sets the encoding.
///
/// The encoding.
public static Encoding DefaultEncoding
{
get
{
if (m_Encoding == null)
{
m_Encoding = Encoding.UTF8;
}
return m_Encoding;
}
set
{
m_Encoding = value;
}
}
///
/// Gets or sets a value indicating whether this encrypt data by default.
///
/// true if encode; otherwise, false.
public static bool Encode
{
get
{
return m_Encode;
}
set
{
m_Encode = value;
}
}
///
/// Gets or sets the save path.
///
/// The save path.
public static SaveGamePath SavePath
{
get
{
return m_SavePath;
}
set
{
m_SavePath = value;
}
}
///
/// Gets or sets the encryption password.
///
/// The encryption password.
public static string EncodePassword
{
get
{
return m_EncodePassword;
}
set
{
m_EncodePassword = value;
}
}
///
/// Gets or sets a value indicating whether this log error.
///
/// true if log error; otherwise, false.
public static bool LogError
{
get
{
return m_LogError;
}
set
{
m_LogError = value;
}
}
///
/// Saves data using the identifier.
///
/// Identifier.
/// Object to save.
/// The 1st type parameter.
public static void Save(string identifier, T obj)
{
Save(identifier, obj, Encode, EncodePassword, Serializer, Encoder, DefaultEncoding, SavePath);
}
///
/// Save the specified identifier, obj, encode and encodePassword.
///
/// Identifier.
/// Object.
/// If set to true encode.
/// The 1st type parameter.
public static void Save(string identifier, T obj, bool encode)
{
Save(identifier, obj, encode, EncodePassword, Serializer, Encoder, DefaultEncoding, SavePath);
}
///
/// Save the specified identifier, obj and encodePassword.
///
/// Identifier.
/// Object.
/// Encode password.
/// The 1st type parameter.
public static void Save(string identifier, T obj, string encodePassword)
{
Save(identifier, obj, Encode, encodePassword, Serializer, Encoder, DefaultEncoding, SavePath);
}
///
/// Save the specified identifier, obj and serializer.
///
/// Identifier.
/// Object.
/// Serializer.
/// The 1st type parameter.
public static void Save(string identifier, T obj, ISaveGameSerializer serializer)
{
Save(identifier, obj, Encode, EncodePassword, serializer, Encoder, DefaultEncoding, SavePath);
}
///
/// Save the specified identifier, obj and encoder.
///
/// Identifier.
/// Object.
/// Encoder.
/// The 1st type parameter.
public static void Save(string identifier, T obj, ISaveGameEncoder encoder)
{
Save(identifier, obj, Encode, EncodePassword, Serializer, encoder, DefaultEncoding, SavePath);
}
///
/// Save the specified identifier, obj and encoding.
///
/// Identifier.
/// Object.
/// Encoding.
/// The 1st type parameter.
public static void Save(string identifier, T obj, Encoding encoding)
{
Save(identifier, obj, Encode, EncodePassword, Serializer, Encoder, encoding, SavePath);
}
///
/// Save the specified identifier, obj and savePath.
///
/// Identifier.
/// Object.
/// Save path.
/// The 1st type parameter.
public static void Save(string identifier, T obj, SaveGamePath savePath)
{
Save(identifier, obj, Encode, EncodePassword, Serializer, Encoder, DefaultEncoding, savePath);
}
///
/// Saves data using the identifier.
///
/// Identifier.
/// Object to save.
/// Encrypt the data?
/// Encryption Password.
/// Serializer.
/// Encoder.
/// Encoding.
/// Path.
/// The 1st type parameter.
public static void Save(string identifier, T obj, bool encode, string password, ISaveGameSerializer serializer, ISaveGameEncoder encoder, Encoding encoding, SaveGamePath path)
{
if (string.IsNullOrEmpty(identifier))
{
throw new System.ArgumentNullException("identifier");
}
if (serializer == null)
{
serializer = SaveGame.Serializer;
}
if (encoding == null)
{
encoding = SaveGame.DefaultEncoding;
}
string filePath = "";
if (!IsFilePath(identifier))
{
switch (path)
{
default:
case SaveGamePath.PersistentDataPath:
filePath = string.Format("{0}/{1}", Application.persistentDataPath, identifier);
break;
case SaveGamePath.DataPath:
filePath = string.Format("{0}/{1}", Application.dataPath, identifier);
break;
}
}
else
{
filePath = identifier;
}
if (obj == null)
{
obj = default(T);
}
Stream stream = null;
#if !UNITY_SAMSUNGTV && !UNITY_TVOS && !UNITY_WEBGL
#if UNITY_WSA || UNITY_WINRT
UnityEngine.Windows.Directory.CreateDirectory ( filePath );
#else
Directory.CreateDirectory(Path.GetDirectoryName(filePath));
#endif
#endif
if (encode)
{
stream = new MemoryStream();
}
else
{
#if !UNITY_SAMSUNGTV && !UNITY_TVOS && !UNITY_WEBGL
if (IOSupported())
{
#if UNITY_WSA || UNITY_WINRT
stream = new MemoryStream ();
#else
stream = File.Create(filePath);
#endif
}
else
{
stream = new MemoryStream();
}
#else
stream = new MemoryStream ();
#endif
}
serializer.Serialize(obj, stream, encoding);
if (encode)
{
string data = System.Convert.ToBase64String(((MemoryStream)stream).ToArray());
string encoded = encoder.Encode(data, password);
#if !UNITY_SAMSUNGTV && !UNITY_TVOS && !UNITY_WEBGL
if (IOSupported())
{
#if UNITY_WSA || UNITY_WINRT
UnityEngine.Windows.File.WriteAllBytes ( filePath, encoding.GetBytes ( encoded ) );
#else
File.WriteAllText(filePath, encoded, encoding);
#endif
}
else
{
PlayerPrefs.SetString(filePath, encoded);
PlayerPrefs.Save();
}
#else
PlayerPrefs.SetString ( filePath, encoded );
PlayerPrefs.Save ();
#endif
}
else if (!IOSupported())
{
string data = encoding.GetString(((MemoryStream)stream).ToArray());
PlayerPrefs.SetString(filePath, data);
PlayerPrefs.Save();
}
stream.Dispose();
if (SaveCallback != null)
{
SaveCallback.Invoke(
obj,
identifier,
encode,
password,
serializer,
encoder,
encoding,
path);
}
if (OnSaved != null)
{
OnSaved(
obj,
identifier,
encode,
password,
serializer,
encoder,
encoding,
path);
}
}
///
/// Loads data using identifier.
///
/// Identifier.
/// The 1st type parameter.
public static T Load(string identifier)
{
return Load(identifier, default(T), Encode, EncodePassword, Serializer, Encoder, DefaultEncoding, SavePath);
}
///
/// Load the specified identifier and defaultValue.
///
/// Identifier.
/// Default value.
/// The 1st type parameter.
public static T Load(string identifier, T defaultValue)
{
return Load(identifier, defaultValue, Encode, EncodePassword, Serializer, Encoder, DefaultEncoding, SavePath);
}
///
/// Load the specified identifier and encodePassword.
///
/// Identifier.
/// Encode password.
/// The 1st type parameter.
public static T Load(string identifier, bool encode, string encodePassword)
{
return Load(identifier, default(T), encode, encodePassword, Serializer, Encoder, DefaultEncoding, SavePath);
}
///
/// Load the specified identifier and serializer.
///
/// Identifier.
/// Serializer.
/// The 1st type parameter.
public static T Load(string identifier, ISaveGameSerializer serializer)
{
return Load(identifier, default(T), Encode, EncodePassword, serializer, Encoder, DefaultEncoding, SavePath);
}
///
/// Load the specified identifier and encoder.
///
/// Identifier.
/// Encoder.
/// The 1st type parameter.
public static T Load(string identifier, ISaveGameEncoder encoder)
{
return Load(identifier, default(T), Encode, EncodePassword, Serializer, encoder, DefaultEncoding, SavePath);
}
///
/// Load the specified identifier and encoding.
///
/// Identifier.
/// Encoding.
/// The 1st type parameter.
public static T Load(string identifier, Encoding encoding)
{
return Load(identifier, default(T), Encode, EncodePassword, Serializer, Encoder, encoding, SavePath);
}
///
/// Load the specified identifier and savePath.
///
/// Identifier.
/// Save path.
/// The 1st type parameter.
public static T Load(string identifier, SaveGamePath savePath)
{
return Load(identifier, default(T), Encode, EncodePassword, Serializer, Encoder, DefaultEncoding, savePath);
}
///
/// Load the specified identifier, defaultValue and encode.
///
/// Identifier.
/// Default value.
/// If set to true encode.
/// The 1st type parameter.
public static T Load(string identifier, T defaultValue, bool encode)
{
return Load(identifier, defaultValue, encode, EncodePassword, Serializer, Encoder, DefaultEncoding, SavePath);
}
///
/// Load the specified identifier, defaultValue and encodePassword.
///
/// Identifier.
/// Default value.
/// Encode password.
/// The 1st type parameter.
public static T Load(string identifier, T defaultValue, string encodePassword)
{
return Load(identifier, defaultValue, Encode, encodePassword, Serializer, Encoder, DefaultEncoding, SavePath);
}
///
/// Load the specified identifier, defaultValue and serializer.
///
/// Identifier.
/// Default value.
/// Serializer.
/// The 1st type parameter.
public static T Load(string identifier, T defaultValue, ISaveGameSerializer serializer)
{
return Load(identifier, defaultValue, Encode, EncodePassword, serializer, Encoder, DefaultEncoding, SavePath);
}
///
/// Load the specified identifier, defaultValue and encoder.
///
/// Identifier.
/// Default value.
/// Encoder.
/// The 1st type parameter.
public static T Load(string identifier, T defaultValue, ISaveGameEncoder encoder)
{
return Load(identifier, defaultValue, Encode, EncodePassword, Serializer, encoder, DefaultEncoding, SavePath);
}
///
/// Load the specified identifier, defaultValue and encoding.
///
/// Identifier.
/// Default value.
/// Encoding.
/// The 1st type parameter.
public static T Load(string identifier, T defaultValue, Encoding encoding)
{
return Load(identifier, defaultValue, Encode, EncodePassword, Serializer, Encoder, encoding, SavePath);
}
///
/// Load the specified identifier, defaultValue and savePath.
///
/// Identifier.
/// Default value.
/// Save path.
/// The 1st type parameter.
public static T Load(string identifier, T defaultValue, SaveGamePath savePath)
{
return Load(identifier, defaultValue, Encode, EncodePassword, Serializer, Encoder, DefaultEncoding, savePath);
}
///
/// Loads data using identifier.
///
/// Identifier.
/// Default Value.
/// Load encrypted data? (set it to true if you have used encryption in save)
/// Encryption Password.
/// Serializer.
/// Encoder.
/// Encoding.
/// Path.
/// The 1st type parameter.
public static T Load(string identifier, T defaultValue, bool encode, string password, ISaveGameSerializer serializer, ISaveGameEncoder encoder, Encoding encoding, SaveGamePath path)
{
if (string.IsNullOrEmpty(identifier))
{
throw new System.ArgumentNullException("identifier");
}
if (serializer == null)
{
serializer = SaveGame.Serializer;
}
if (encoding == null)
{
encoding = SaveGame.DefaultEncoding;
}
if (defaultValue == null)
{
defaultValue = default(T);
}
T result = defaultValue;
string filePath = "";
if (!IsFilePath(identifier))
{
switch (path)
{
default:
case SaveGamePath.PersistentDataPath:
filePath = string.Format("{0}/{1}", Application.persistentDataPath, identifier);
break;
case SaveGamePath.DataPath:
filePath = string.Format("{0}/{1}", Application.dataPath, identifier);
break;
}
}
else
{
filePath = identifier;
}
#if !UNITY_SAMSUNGTV && !UNITY_TVOS && !UNITY_WEBGL
if (!Exists(filePath, path))
#else
if ( !Exists ( filePath, path ) )
#endif
{
Debug.LogWarningFormat(
"The specified identifier ({1}) does not exists. please use Exists () to check for existent before calling Load.\n" +
"returning the default(T) instance.",
filePath,
identifier);
return result;
}
Stream stream = null;
if (encode)
{
string data = "";
#if !UNITY_SAMSUNGTV && !UNITY_TVOS && !UNITY_WEBGL
if (IOSupported())
{
#if UNITY_WSA || UNITY_WINRT
data = encoding.GetString ( UnityEngine.Windows.File.ReadAllBytes ( filePath ) );
#else
data = File.ReadAllText(filePath, encoding);
#endif
}
else
{
data = PlayerPrefs.GetString(filePath);
}
#else
data = PlayerPrefs.GetString ( filePath );
#endif
string decoded = encoder.Decode(data, password);
stream = new MemoryStream(System.Convert.FromBase64String(decoded), true);
}
else
{
#if !UNITY_SAMSUNGTV && !UNITY_TVOS && !UNITY_WEBGL
if (IOSupported())
{
#if UNITY_WSA || UNITY_WINRT
stream = new MemoryStream ( UnityEngine.Windows.File.ReadAllBytes ( filePath ) );
#else
stream = File.OpenRead(filePath);
#endif
}
else
{
string data = PlayerPrefs.GetString(filePath);
stream = new MemoryStream(encoding.GetBytes(data));
}
#else
string data = PlayerPrefs.GetString ( filePath );
stream = new MemoryStream ( encoding.GetBytes ( data ) );
#endif
}
result = serializer.Deserialize(stream, encoding);
stream.Dispose();
if (result == null)
{
result = defaultValue;
}
if (LoadCallback != null)
{
LoadCallback.Invoke(
result,
identifier,
encode,
password,
serializer,
encoder,
encoding,
path);
}
if (OnLoaded != null)
{
OnLoaded(
result,
identifier,
encode,
password,
serializer,
encoder,
encoding,
path);
}
return result;
}
///
/// Checks whether the specified identifier exists or not.
///
/// Identifier.
public static bool Exists(string identifier)
{
return Exists(identifier, SavePath);
}
///
/// Checks whether the specified identifier exists or not.
///
/// Identifier.
/// Path.
/// Check in Web?
/// Web username.
/// Web password.
/// Web URL.
public static bool Exists(string identifier, SaveGamePath path)
{
if (string.IsNullOrEmpty(identifier))
{
throw new System.ArgumentNullException("identifier");
}
string filePath = "";
if (!IsFilePath(identifier))
{
switch (path)
{
default:
case SaveGamePath.PersistentDataPath:
filePath = string.Format("{0}/{1}", Application.persistentDataPath, identifier);
break;
case SaveGamePath.DataPath:
filePath = string.Format("{0}/{1}", Application.dataPath, identifier);
break;
}
}
else
{
filePath = identifier;
}
#if !UNITY_SAMSUNGTV && !UNITY_TVOS && !UNITY_WEBGL
if (IOSupported())
{
bool exists = false;
#if UNITY_WSA || UNITY_WINRT
exists = UnityEngine.Windows.Directory.Exists ( filePath );
#else
exists = Directory.Exists(filePath);
#endif
if (!exists)
{
#if UNITY_WSA || UNITY_WINRT
exists = UnityEngine.Windows.File.Exists ( filePath );
#else
exists = File.Exists(filePath);
#endif
}
return exists;
}
else
{
return PlayerPrefs.HasKey(filePath);
}
#else
return PlayerPrefs.HasKey ( filePath );
#endif
}
///
/// Delete the specified identifier.
///
/// Identifier.
public static void Delete(string identifier)
{
Delete(identifier, SavePath);
}
///
/// Delete the specified identifier and path.
///
/// Identifier.
/// Path.
public static void Delete(string identifier, SaveGamePath path)
{
if (string.IsNullOrEmpty(identifier))
{
throw new System.ArgumentNullException("identifier");
}
string filePath = "";
if (!IsFilePath(identifier))
{
switch (path)
{
default:
case SaveGamePath.PersistentDataPath:
filePath = string.Format("{0}/{1}", Application.persistentDataPath, identifier);
break;
case SaveGamePath.DataPath:
filePath = string.Format("{0}/{1}", Application.dataPath, identifier);
break;
}
}
else
{
filePath = identifier;
}
if (!Exists(filePath, path))
{
return;
}
#if !UNITY_SAMSUNGTV && !UNITY_TVOS && !UNITY_WEBGL
if (IOSupported())
{
#if UNITY_WSA || UNITY_WINRT
if (UnityEngine.Windows.File.Exists(filePath))
UnityEngine.Windows.File.Delete(filePath);
else if (UnityEngine.Windows.Directory.Exists(filePath))
UnityEngine.Windows.Directory.Delete(filePath, true);
#else
if (File.Exists(filePath))
File.Delete(filePath);
else if (Directory.Exists(filePath))
Directory.Delete(filePath, true);
#endif
}
else
{
PlayerPrefs.DeleteKey(filePath);
}
#else
PlayerPrefs.DeleteKey ( filePath );
#endif
}
///
/// Clear this instance.
/// Alias of DeleteAll
///
public static void Clear()
{
DeleteAll(SavePath);
}
///
/// Clear the specified path.
/// Alias of DeleteAll
///
/// Path.
public static void Clear(SaveGamePath path)
{
DeleteAll(path);
}
///
/// Deletes all.
///
public static void DeleteAll()
{
DeleteAll(SavePath);
}
///
/// Deletes all.
///
/// Path.
public static void DeleteAll(SaveGamePath path)
{
string dirPath = "";
switch (path)
{
case SaveGamePath.PersistentDataPath:
dirPath = Application.persistentDataPath;
break;
case SaveGamePath.DataPath:
dirPath = Application.dataPath;
break;
}
#if !UNITY_SAMSUNGTV && !UNITY_TVOS && !UNITY_WEBGL
if (IOSupported())
{
#if UNITY_WSA || UNITY_WINRT
UnityEngine.Windows.Directory.Delete ( dirPath );
#else
DirectoryInfo info = new DirectoryInfo(dirPath);
FileInfo[] files = info.GetFiles();
for (int i = 0; i < files.Length; i++)
{
files[i].Delete();
}
DirectoryInfo[] dirs = info.GetDirectories();
for (int i = 0; i < dirs.Length; i++)
{
dirs[i].Delete(true);
}
#endif
}
else
{
PlayerPrefs.DeleteAll();
}
#else
PlayerPrefs.DeleteAll ();
#endif
}
///
/// Retrieves files from the save path home.
///
///
public static FileInfo[] GetFiles()
{
return GetFiles(string.Empty, SavePath);
}
///
/// Retrieves files from the given directory path.
///
///
///
public static FileInfo[] GetFiles(string identifier)
{
return GetFiles(identifier, SavePath);
}
///
/// Retrieves files from the given directory path.
///
///
///
///
public static FileInfo[] GetFiles(string identifier, SaveGamePath path)
{
if (string.IsNullOrEmpty(identifier))
{
identifier = string.Empty;
}
string filePath = "";
if (!IsFilePath(identifier))
{
switch (path)
{
default:
case SaveGamePath.PersistentDataPath:
filePath = string.Format("{0}/{1}", Application.persistentDataPath, identifier);
break;
case SaveGamePath.DataPath:
filePath = string.Format("{0}/{1}", Application.dataPath, identifier);
break;
}
}
else
{
filePath = identifier;
}
FileInfo[] files = new FileInfo[0];
if (!Exists(filePath, path))
{
return files;
}
if (Directory.Exists(filePath))
{
DirectoryInfo info = new DirectoryInfo(filePath);
files = info.GetFiles();
}
return files;
}
///
/// Retrieves directories from the save path home.
///
///
public static DirectoryInfo[] GetDirectories()
{
return GetDirectories(string.Empty, SavePath);
}
///
/// Retrieves directories from the given directory path.
///
///
///
public static DirectoryInfo[] GetDirectories(string identifier)
{
return GetDirectories(identifier, SavePath);
}
///
/// Retrieves directories from the given directory path.
///
///
///
///
public static DirectoryInfo[] GetDirectories(string identifier, SaveGamePath path)
{
if (string.IsNullOrEmpty(identifier))
{
identifier = string.Empty;
}
string filePath = "";
if (!IsFilePath(identifier))
{
switch (path)
{
default:
case SaveGamePath.PersistentDataPath:
filePath = string.Format("{0}/{1}", Application.persistentDataPath, identifier);
break;
case SaveGamePath.DataPath:
filePath = string.Format("{0}/{1}", Application.dataPath, identifier);
break;
}
}
else
{
filePath = identifier;
}
DirectoryInfo[] directories = new DirectoryInfo[0];
if (!Exists(filePath, path))
{
return directories;
}
if (Directory.Exists(filePath))
{
DirectoryInfo info = new DirectoryInfo(filePath);
directories = info.GetDirectories();
}
return directories;
}
///
/// Checks if the IO is supported on current platform or not.
///
/// true, if supported was IOed, false otherwise.
public static bool IOSupported()
{
return Application.platform != RuntimePlatform.WebGLPlayer &&
Application.platform != RuntimePlatform.WSAPlayerARM &&
Application.platform != RuntimePlatform.WSAPlayerX64 &&
Application.platform != RuntimePlatform.WSAPlayerX86 &&
#if !UNITY_2017_3_OR_NEWER
Application.platform != RuntimePlatform.SamsungTVPlayer &&
#endif
Application.platform != RuntimePlatform.tvOS &&
Application.platform != RuntimePlatform.PS4;
}
///
/// Determines if the string is file path.
///
/// true if is file path the specified str; otherwise, false.
/// String.
public static bool IsFilePath(string str)
{
bool result = false;
#if !UNITY_SAMSUNGTV && !UNITY_TVOS && !UNITY_WEBGL
if (Path.IsPathRooted(str))
{
try
{
Path.GetFullPath(str);
result = true;
}
catch (System.Exception)
{
result = false;
}
}
#endif
return result;
}
}
}