141 lines
4 KiB
C#
141 lines
4 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 {
|
|
InteropEmu.DisplayMessage("GoogleDrive", "SynchronizationStarted");
|
|
using(_accessor = new GoogleDriveAccessor()) {
|
|
if(!CloudSyncHelper.DownloadData()) {
|
|
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()) {
|
|
var gdAccessor = new GoogleDriveAccessor();
|
|
return _accessor.UploadFile(stream, "MesenData.zip");
|
|
}
|
|
}
|
|
|
|
private static bool DownloadData()
|
|
{
|
|
using(MemoryStream stream = new MemoryStream()) {
|
|
bool result = _accessor.DownloadFile(stream, "MesenData.zip");
|
|
|
|
if(result) {
|
|
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
|
|
entry.ExtractToFile(fileName, true);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
} 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;
|
|
}
|
|
}
|
|
}
|