157 lines
4.7 KiB
C#
157 lines
4.7 KiB
C#
using System;
|
|
using System.Collections.Generic;
|
|
using System.IO;
|
|
using System.IO.Compression;
|
|
using System.Linq;
|
|
using System.Text;
|
|
using System.Threading.Tasks;
|
|
using Mesen.GUI.Config;
|
|
|
|
namespace Mesen.GUI.GoogleDriveIntegration
|
|
{
|
|
public class CloudSyncHelper
|
|
{
|
|
private static object _lock = new object();
|
|
private static GoogleDriveAccessor _accessor;
|
|
|
|
public static bool Syncing
|
|
{
|
|
get
|
|
{
|
|
bool lockTaken = false;
|
|
System.Threading.Monitor.TryEnter(_lock, ref lockTaken);
|
|
if(lockTaken) {
|
|
System.Threading.Monitor.Exit(_lock);
|
|
}
|
|
return !lockTaken;
|
|
}
|
|
}
|
|
|
|
public static bool Sync()
|
|
{
|
|
if(!System.Threading.Monitor.TryEnter(_lock)) {
|
|
//Already syncing, return when on-going sync is done
|
|
lock(_lock) {
|
|
return true;
|
|
}
|
|
} else {
|
|
try {
|
|
string googleDriveFolder = Path.Combine(ConfigManager.HomeFolder, "GoogleDrive");
|
|
if(!Directory.Exists(googleDriveFolder) || Directory.EnumerateFiles(googleDriveFolder).Where((string filename) => filename.Contains("TokenResponse")).Count() == 0) {
|
|
//Sync token has been deleted, disable sync
|
|
ConfigManager.Config.PreferenceInfo.CloudSaveIntegration = false;
|
|
ConfigManager.ApplyChanges();
|
|
return false;
|
|
}
|
|
|
|
InteropEmu.DisplayMessage("GoogleDrive", "SynchronizationStarted");
|
|
using(_accessor = new GoogleDriveAccessor()) {
|
|
FileDownloadResult result = CloudSyncHelper.DownloadData();
|
|
if(result == FileDownloadResult.Error) {
|
|
InteropEmu.DisplayMessage("GoogleDrive", "SynchronizationFailed");
|
|
return false;
|
|
}
|
|
|
|
CloudSyncHelper.UploadData();
|
|
InteropEmu.DisplayMessage("GoogleDrive", "SynchronizationCompleted");
|
|
ConfigManager.Config.PreferenceInfo.CloudLastSync = DateTime.Now;
|
|
ConfigManager.ApplyChanges();
|
|
|
|
return true;
|
|
}
|
|
} finally {
|
|
System.Threading.Monitor.Exit(_lock);
|
|
}
|
|
}
|
|
}
|
|
|
|
public static bool EnableSync()
|
|
{
|
|
using(_accessor = new GoogleDriveAccessor()) {
|
|
bool result = _accessor.AcquireToken();
|
|
if(result) {
|
|
ConfigManager.Config.PreferenceInfo.CloudSaveIntegration = true;
|
|
ConfigManager.ApplyChanges();
|
|
}
|
|
return result;
|
|
}
|
|
}
|
|
|
|
public static void DisableSync()
|
|
{
|
|
using(_accessor = new GoogleDriveAccessor()) {
|
|
_accessor.RevokeToken();
|
|
}
|
|
|
|
ConfigManager.Config.PreferenceInfo.CloudSaveIntegration = false;
|
|
ConfigManager.ApplyChanges();
|
|
}
|
|
|
|
private static bool UploadData()
|
|
{
|
|
using(MemoryStream stream = CloudSyncHelper.GetDataStream()) {
|
|
return _accessor.UploadFile(stream, "MesenData.zip");
|
|
}
|
|
}
|
|
|
|
private static FileDownloadResult DownloadData()
|
|
{
|
|
using(MemoryStream stream = new MemoryStream()) {
|
|
FileDownloadResult result = _accessor.DownloadFile(stream, "MesenData.zip");
|
|
|
|
if(result == FileDownloadResult.OK) {
|
|
try {
|
|
stream.Position = 0;
|
|
|
|
string homeFolder = ConfigManager.HomeFolder;
|
|
|
|
//Make sure the folders exist
|
|
string saveFolder = ConfigManager.SaveFolder;
|
|
string saveStateFolder = ConfigManager.SaveStateFolder;
|
|
|
|
using(ZipArchive archive = new ZipArchive(stream)) {
|
|
foreach(ZipArchiveEntry entry in archive.Entries) {
|
|
if(!string.IsNullOrWhiteSpace(entry.Name)) {
|
|
string[] fileAndFolder = entry.FullName.Split('/');
|
|
string fileName = Path.Combine(homeFolder, fileAndFolder[0], fileAndFolder[1]);
|
|
if(!File.Exists(fileName) || File.GetLastWriteTime(fileName) < entry.LastWriteTime.ToLocalTime()) {
|
|
//File on server is more recent, or doesn't exist on local computer, extract it
|
|
try {
|
|
entry.ExtractToFile(fileName, true);
|
|
} catch {
|
|
//Files might be opened by another program or not read-only, etc.
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
} catch {
|
|
result = FileDownloadResult.FileCorrupted;
|
|
}
|
|
} else if(_accessor.Revoked) {
|
|
ConfigManager.Config.PreferenceInfo.CloudSaveIntegration = false;
|
|
ConfigManager.ApplyChanges();
|
|
}
|
|
|
|
return result;
|
|
}
|
|
}
|
|
|
|
private static MemoryStream GetDataStream()
|
|
{
|
|
MemoryStream outputStream = new MemoryStream();
|
|
using(ZipArchive archive = new ZipArchive(outputStream, ZipArchiveMode.Create, true)) {
|
|
archive.CreateEntry("Saves/");
|
|
foreach(string filename in System.IO.Directory.EnumerateFiles(ConfigManager.SaveFolder, "*.sav", System.IO.SearchOption.AllDirectories)) {
|
|
archive.CreateEntryFromFile(filename, "Saves/" + System.IO.Path.GetFileName(filename));
|
|
}
|
|
|
|
archive.CreateEntry("SaveStates/");
|
|
foreach(string filename in System.IO.Directory.EnumerateFiles(ConfigManager.SaveStateFolder, "*.mst", System.IO.SearchOption.AllDirectories)) {
|
|
archive.CreateEntryFromFile(filename, "SaveStates/" + System.IO.Path.GetFileName(filename));
|
|
}
|
|
}
|
|
return outputStream;
|
|
}
|
|
}
|
|
}
|