Google Drive Integration
This commit is contained in:
parent
a9fa9b9ba7
commit
545962cfa7
32 changed files with 986 additions and 56 deletions
|
@ -58,6 +58,30 @@ namespace Mesen.GUI.Config
|
|||
}
|
||||
}
|
||||
|
||||
public static string SaveFolder
|
||||
{
|
||||
get
|
||||
{
|
||||
string movieFolder = Path.Combine(ConfigManager.HomeFolder, "Saves");
|
||||
if(!Directory.Exists(movieFolder)) {
|
||||
Directory.CreateDirectory(movieFolder);
|
||||
}
|
||||
return movieFolder;
|
||||
}
|
||||
}
|
||||
|
||||
public static string SaveStateFolder
|
||||
{
|
||||
get
|
||||
{
|
||||
string movieFolder = Path.Combine(ConfigManager.HomeFolder, "SaveStates");
|
||||
if(!Directory.Exists(movieFolder)) {
|
||||
Directory.CreateDirectory(movieFolder);
|
||||
}
|
||||
return movieFolder;
|
||||
}
|
||||
}
|
||||
|
||||
public static string DownloadFolder
|
||||
{
|
||||
get
|
||||
|
|
|
@ -36,6 +36,9 @@ namespace Mesen.GUI.Config
|
|||
|
||||
public bool UseAlternativeMmc3Irq = false;
|
||||
|
||||
public bool CloudSaveIntegration = false;
|
||||
public DateTime CloudLastSync = DateTime.MinValue;
|
||||
|
||||
public PreferenceInfo()
|
||||
{
|
||||
}
|
||||
|
|
BIN
GUI.NET/Dependencies/BouncyCastle.Crypto.dll
Normal file
BIN
GUI.NET/Dependencies/BouncyCastle.Crypto.dll
Normal file
Binary file not shown.
BIN
GUI.NET/Dependencies/Google.Apis.Auth.PlatformServices.dll
Normal file
BIN
GUI.NET/Dependencies/Google.Apis.Auth.PlatformServices.dll
Normal file
Binary file not shown.
BIN
GUI.NET/Dependencies/Google.Apis.Auth.dll
Normal file
BIN
GUI.NET/Dependencies/Google.Apis.Auth.dll
Normal file
Binary file not shown.
BIN
GUI.NET/Dependencies/Google.Apis.Core.dll
Normal file
BIN
GUI.NET/Dependencies/Google.Apis.Core.dll
Normal file
Binary file not shown.
BIN
GUI.NET/Dependencies/Google.Apis.Drive.v3.dll
Normal file
BIN
GUI.NET/Dependencies/Google.Apis.Drive.v3.dll
Normal file
Binary file not shown.
BIN
GUI.NET/Dependencies/Google.Apis.PlatformServices.dll
Normal file
BIN
GUI.NET/Dependencies/Google.Apis.PlatformServices.dll
Normal file
Binary file not shown.
BIN
GUI.NET/Dependencies/Google.Apis.dll
Normal file
BIN
GUI.NET/Dependencies/Google.Apis.dll
Normal file
Binary file not shown.
BIN
GUI.NET/Dependencies/Newtonsoft.Json.dll
Normal file
BIN
GUI.NET/Dependencies/Newtonsoft.Json.dll
Normal file
Binary file not shown.
BIN
GUI.NET/Dependencies/Zlib.Portable.dll
Normal file
BIN
GUI.NET/Dependencies/Zlib.Portable.dll
Normal file
Binary file not shown.
|
@ -35,6 +35,8 @@
|
|||
<Message ID="UpgradeSuccess">Upgrade completed successfully.</Message>
|
||||
<Message ID="UpdaterNotFound">The update process could not be started due to missing files.</Message>
|
||||
<Message ID="Net45NotFound">The Microsoft .NET Framework 4.5 could not be found. Please download and install the latest version of the .NET Framework from Microsoft's website and try again.</Message>
|
||||
|
||||
<Message ID="GoogleDriveIntegrationError">Mesen could not connect to your Google Drive account - please try again.</Message>
|
||||
</Messages>
|
||||
<Enums>
|
||||
<Enum ID="ControllerType">
|
||||
|
|
|
@ -197,6 +197,15 @@
|
|||
<Control ID="chkRemoveSpriteLimit">Éliminer la limite de sprites (Réduit le clignotement dans certains jeux)</Control>
|
||||
<Control ID="chkFdsAutoLoadDisk">Insérer le côté A du disque 1 lors du chargement d'un jeu de FDS</Control>
|
||||
<Control ID="chkFdsFastForwardOnLoad">Augmenter la vitesse d'émulation pendant le chargement des jeux FDS</Control>
|
||||
|
||||
<Control ID="tpgCloudSave">Sauvegarde en ligne</Control>
|
||||
<Control ID="lblGoogleDriveIntegration">Mesen peut utiliser Google Drive pour mettre vos sauvegardes dans votre compte Google Drive. Lorsque l'intégration est activée, toutes les données de sauvegarde de vos jeux (fichiers .sav et sauvegardes rapides) sont facilement accessibles à partir de n'importe quel ordinateur.</Control>
|
||||
<Control ID="lblIntegrationOK">L'intégration avec Google Drive est active.</Control>
|
||||
<Control ID="btnDisableIntegration">Désactiver l'intégration Google Drive</Control>
|
||||
<Control ID="btnEnableIntegration">Activer l'intégration Google Drive</Control>
|
||||
<Control ID="lblLastSync">Dernière synchronisation : </Control>
|
||||
<Control ID="btnResync">Resynchroniser</Control>
|
||||
|
||||
<Control ID="btnOK">OK</Control>
|
||||
<Control ID="btnCancel">Annuler</Control>
|
||||
</Form>
|
||||
|
@ -297,8 +306,9 @@
|
|||
<Message ID="UpdateDownloadFailed">Le téléchargement a échoué - le fichier semble être corrompu. Veuillez visiter le site de Mesen pour télécharger manuellement la version la plus récente.</Message>
|
||||
<Message ID="UpgradeSuccess">La mise-à-jour s'est faite avec succès.</Message>
|
||||
<Message ID="UpdaterNotFound">Le processus de mise-à-jour ne peut être démarré puisque certains fichiers sont manquants.</Message>
|
||||
|
||||
<Message ID="Net45NotFound">Le .NET Framework 4.5 de Microsoft n'a pas été trouvé. Veuillez télécharger la plus récente version du .NET Framework à partir du site de Microsoft et essayer à nouveau.</Message>
|
||||
|
||||
<Message ID="GoogleDriveIntegrationError">Mesen n'a pas été en mesure de se connecter à votre compte Google Drive, veuillez essayer à nouveau.</Message>
|
||||
</Messages>
|
||||
<Enums>
|
||||
<Enum ID="ControllerType">
|
||||
|
|
|
@ -197,6 +197,15 @@
|
|||
<Control ID="chkRemoveSpriteLimit">スプライトの制限を解除 (点滅を軽減する)</Control>
|
||||
<Control ID="chkFdsAutoLoadDisk">ファミコンディスクシステムのゲームをロードする時に自動的にディスク1のA面を入れる</Control>
|
||||
<Control ID="chkFdsFastForwardOnLoad">ファミコンディスクシステムのゲームをディスクからロードする時に自動的に最高速度にする</Control>
|
||||
|
||||
<Control ID="tpgCloudSave">クラウドバックアップ</Control>
|
||||
<Control ID="lblGoogleDriveIntegration">MesenはGoogle Driveを利用することでクラウドバックアップが出来ます。 Google Drive同期を有効にすれば、ゲームのセーブデータはGoogle Driveにバックアップされ、どんなパソコンからのアクセスが可能になります。</Control>
|
||||
<Control ID="lblIntegrationOK">Google Drive同期は有効です。</Control>
|
||||
<Control ID="btnDisableIntegration">Google Drive同期を無効にする</Control>
|
||||
<Control ID="btnEnableIntegration">Google Drive同期を有効にする</Control>
|
||||
<Control ID="btnResync">同期</Control>
|
||||
<Control ID="lblLastSync">最終同期: </Control>
|
||||
|
||||
<Control ID="btnOK">OK</Control>
|
||||
<Control ID="btnCancel">キャンセル</Control>
|
||||
</Form>
|
||||
|
@ -290,8 +299,9 @@
|
|||
<Message ID="UpdateDownloadFailed">ダウンロードは失敗しました。 Mesenのサイトに行って、新しいバージョンをダウンロードしてください。</Message>
|
||||
<Message ID="UpdaterNotFound">必要不可欠なファイルがないため、アップデートは出来なかった。</Message>
|
||||
<Message ID="UpgradeSuccess">アップデートは完了しました。</Message>
|
||||
|
||||
<Message ID="Net45NotFound">Microsoft .NET Framework 4.5はインストールされていないため、Mesenは起動できません。Microsoft .NET Frameworkの最新版をMicrosoftのサイトからダウンロードして、インストールしてください。</Message>
|
||||
|
||||
<Message ID="GoogleDriveIntegrationError">MesenはGoogle Driveにアクセス出来ませんでした。</Message>
|
||||
</Messages>
|
||||
<Enums>
|
||||
<Enum ID="ControllerType">
|
||||
|
|
246
GUI.NET/Forms/Config/frmPreferences.Designer.cs
generated
246
GUI.NET/Forms/Config/frmPreferences.Designer.cs
generated
|
@ -27,6 +27,8 @@
|
|||
/// </summary>
|
||||
private void InitializeComponent()
|
||||
{
|
||||
this.components = new System.ComponentModel.Container();
|
||||
System.ComponentModel.ComponentResourceManager resources = new System.ComponentModel.ComponentResourceManager(typeof(frmPreferences));
|
||||
this.tlpMain = new System.Windows.Forms.TableLayoutPanel();
|
||||
this.chkSingleInstance = new System.Windows.Forms.CheckBox();
|
||||
this.chkAutomaticallyCheckForUpdates = new System.Windows.Forms.CheckBox();
|
||||
|
@ -42,6 +44,20 @@
|
|||
this.cboDisplayLanguage = new System.Windows.Forms.ComboBox();
|
||||
this.tabMain = new System.Windows.Forms.TabControl();
|
||||
this.tpgGeneral = new System.Windows.Forms.TabPage();
|
||||
this.tpgCloudSave = new System.Windows.Forms.TabPage();
|
||||
this.tlpCloudSaves = new System.Windows.Forms.TableLayoutPanel();
|
||||
this.tlpCloudSaveDesc = new System.Windows.Forms.TableLayoutPanel();
|
||||
this.lblGoogleDriveIntegration = new System.Windows.Forms.Label();
|
||||
this.btnEnableIntegration = new System.Windows.Forms.Button();
|
||||
this.tlpCloudSaveEnabled = new System.Windows.Forms.TableLayoutPanel();
|
||||
this.btnDisableIntegration = new System.Windows.Forms.Button();
|
||||
this.flowLayoutPanel3 = new System.Windows.Forms.FlowLayoutPanel();
|
||||
this.picOK = new System.Windows.Forms.PictureBox();
|
||||
this.lblIntegrationOK = new System.Windows.Forms.Label();
|
||||
this.flowLayoutPanel4 = new System.Windows.Forms.FlowLayoutPanel();
|
||||
this.lblLastSync = new System.Windows.Forms.Label();
|
||||
this.lblLastSyncDateTime = new System.Windows.Forms.Label();
|
||||
this.btnResync = new System.Windows.Forms.Button();
|
||||
this.tpgFileAssociations = new System.Windows.Forms.TabPage();
|
||||
this.grpFileAssociations = new System.Windows.Forms.GroupBox();
|
||||
this.tlpFileFormat = new System.Windows.Forms.TableLayoutPanel();
|
||||
|
@ -56,10 +72,18 @@
|
|||
this.chkRemoveSpriteLimit = new System.Windows.Forms.CheckBox();
|
||||
this.chkFdsAutoLoadDisk = new System.Windows.Forms.CheckBox();
|
||||
this.chkFdsFastForwardOnLoad = new System.Windows.Forms.CheckBox();
|
||||
this.tmrSyncDateTime = new System.Windows.Forms.Timer(this.components);
|
||||
this.tlpMain.SuspendLayout();
|
||||
this.flowLayoutPanel2.SuspendLayout();
|
||||
this.tabMain.SuspendLayout();
|
||||
this.tpgGeneral.SuspendLayout();
|
||||
this.tpgCloudSave.SuspendLayout();
|
||||
this.tlpCloudSaves.SuspendLayout();
|
||||
this.tlpCloudSaveDesc.SuspendLayout();
|
||||
this.tlpCloudSaveEnabled.SuspendLayout();
|
||||
this.flowLayoutPanel3.SuspendLayout();
|
||||
((System.ComponentModel.ISupportInitialize)(this.picOK)).BeginInit();
|
||||
this.flowLayoutPanel4.SuspendLayout();
|
||||
this.tpgFileAssociations.SuspendLayout();
|
||||
this.grpFileAssociations.SuspendLayout();
|
||||
this.tlpFileFormat.SuspendLayout();
|
||||
|
@ -69,7 +93,7 @@
|
|||
//
|
||||
// baseConfigPanel
|
||||
//
|
||||
this.baseConfigPanel.Location = new System.Drawing.Point(0, 270);
|
||||
this.baseConfigPanel.Location = new System.Drawing.Point(0, 255);
|
||||
this.baseConfigPanel.Size = new System.Drawing.Size(458, 29);
|
||||
//
|
||||
// tlpMain
|
||||
|
@ -100,7 +124,7 @@
|
|||
this.tlpMain.RowStyles.Add(new System.Windows.Forms.RowStyle());
|
||||
this.tlpMain.RowStyles.Add(new System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Percent, 100F));
|
||||
this.tlpMain.RowStyles.Add(new System.Windows.Forms.RowStyle());
|
||||
this.tlpMain.Size = new System.Drawing.Size(444, 238);
|
||||
this.tlpMain.Size = new System.Drawing.Size(444, 223);
|
||||
this.tlpMain.TabIndex = 1;
|
||||
//
|
||||
// chkSingleInstance
|
||||
|
@ -188,7 +212,7 @@
|
|||
// btnOpenMesenFolder
|
||||
//
|
||||
this.btnOpenMesenFolder.AutoSize = true;
|
||||
this.btnOpenMesenFolder.Location = new System.Drawing.Point(3, 212);
|
||||
this.btnOpenMesenFolder.Location = new System.Drawing.Point(3, 197);
|
||||
this.btnOpenMesenFolder.Name = "btnOpenMesenFolder";
|
||||
this.btnOpenMesenFolder.Size = new System.Drawing.Size(117, 23);
|
||||
this.btnOpenMesenFolder.TabIndex = 16;
|
||||
|
@ -228,13 +252,14 @@
|
|||
// tabMain
|
||||
//
|
||||
this.tabMain.Controls.Add(this.tpgGeneral);
|
||||
this.tabMain.Controls.Add(this.tpgCloudSave);
|
||||
this.tabMain.Controls.Add(this.tpgFileAssociations);
|
||||
this.tabMain.Controls.Add(this.tpgAdvanced);
|
||||
this.tabMain.Dock = System.Windows.Forms.DockStyle.Fill;
|
||||
this.tabMain.Location = new System.Drawing.Point(0, 0);
|
||||
this.tabMain.Name = "tabMain";
|
||||
this.tabMain.SelectedIndex = 0;
|
||||
this.tabMain.Size = new System.Drawing.Size(458, 270);
|
||||
this.tabMain.Size = new System.Drawing.Size(458, 255);
|
||||
this.tabMain.TabIndex = 2;
|
||||
//
|
||||
// tpgGeneral
|
||||
|
@ -243,18 +268,186 @@
|
|||
this.tpgGeneral.Location = new System.Drawing.Point(4, 22);
|
||||
this.tpgGeneral.Name = "tpgGeneral";
|
||||
this.tpgGeneral.Padding = new System.Windows.Forms.Padding(3);
|
||||
this.tpgGeneral.Size = new System.Drawing.Size(450, 244);
|
||||
this.tpgGeneral.Size = new System.Drawing.Size(450, 229);
|
||||
this.tpgGeneral.TabIndex = 0;
|
||||
this.tpgGeneral.Text = "General";
|
||||
this.tpgGeneral.UseVisualStyleBackColor = true;
|
||||
//
|
||||
// tpgCloudSave
|
||||
//
|
||||
this.tpgCloudSave.Controls.Add(this.tlpCloudSaves);
|
||||
this.tpgCloudSave.Location = new System.Drawing.Point(4, 22);
|
||||
this.tpgCloudSave.Name = "tpgCloudSave";
|
||||
this.tpgCloudSave.Padding = new System.Windows.Forms.Padding(3);
|
||||
this.tpgCloudSave.Size = new System.Drawing.Size(450, 229);
|
||||
this.tpgCloudSave.TabIndex = 3;
|
||||
this.tpgCloudSave.Text = "Cloud Saves";
|
||||
this.tpgCloudSave.UseVisualStyleBackColor = true;
|
||||
//
|
||||
// tlpCloudSaves
|
||||
//
|
||||
this.tlpCloudSaves.ColumnCount = 1;
|
||||
this.tlpCloudSaves.ColumnStyles.Add(new System.Windows.Forms.ColumnStyle(System.Windows.Forms.SizeType.Percent, 100F));
|
||||
this.tlpCloudSaves.Controls.Add(this.tlpCloudSaveDesc, 0, 0);
|
||||
this.tlpCloudSaves.Controls.Add(this.tlpCloudSaveEnabled, 0, 1);
|
||||
this.tlpCloudSaves.Dock = System.Windows.Forms.DockStyle.Fill;
|
||||
this.tlpCloudSaves.Location = new System.Drawing.Point(3, 3);
|
||||
this.tlpCloudSaves.Name = "tlpCloudSaves";
|
||||
this.tlpCloudSaves.RowCount = 2;
|
||||
this.tlpCloudSaves.RowStyles.Add(new System.Windows.Forms.RowStyle());
|
||||
this.tlpCloudSaves.RowStyles.Add(new System.Windows.Forms.RowStyle());
|
||||
this.tlpCloudSaves.Size = new System.Drawing.Size(444, 223);
|
||||
this.tlpCloudSaves.TabIndex = 0;
|
||||
//
|
||||
// tlpCloudSaveDesc
|
||||
//
|
||||
this.tlpCloudSaveDesc.ColumnCount = 1;
|
||||
this.tlpCloudSaveDesc.ColumnStyles.Add(new System.Windows.Forms.ColumnStyle(System.Windows.Forms.SizeType.Percent, 100F));
|
||||
this.tlpCloudSaveDesc.Controls.Add(this.lblGoogleDriveIntegration, 0, 0);
|
||||
this.tlpCloudSaveDesc.Controls.Add(this.btnEnableIntegration, 0, 1);
|
||||
this.tlpCloudSaveDesc.Dock = System.Windows.Forms.DockStyle.Fill;
|
||||
this.tlpCloudSaveDesc.Location = new System.Drawing.Point(0, 0);
|
||||
this.tlpCloudSaveDesc.Margin = new System.Windows.Forms.Padding(0);
|
||||
this.tlpCloudSaveDesc.Name = "tlpCloudSaveDesc";
|
||||
this.tlpCloudSaveDesc.RowCount = 2;
|
||||
this.tlpCloudSaveDesc.RowStyles.Add(new System.Windows.Forms.RowStyle());
|
||||
this.tlpCloudSaveDesc.RowStyles.Add(new System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Percent, 100F));
|
||||
this.tlpCloudSaveDesc.Size = new System.Drawing.Size(444, 100);
|
||||
this.tlpCloudSaveDesc.TabIndex = 0;
|
||||
//
|
||||
// lblGoogleDriveIntegration
|
||||
//
|
||||
this.lblGoogleDriveIntegration.AutoSize = true;
|
||||
this.lblGoogleDriveIntegration.Location = new System.Drawing.Point(3, 0);
|
||||
this.lblGoogleDriveIntegration.Name = "lblGoogleDriveIntegration";
|
||||
this.lblGoogleDriveIntegration.Size = new System.Drawing.Size(436, 52);
|
||||
this.lblGoogleDriveIntegration.TabIndex = 0;
|
||||
this.lblGoogleDriveIntegration.Text = resources.GetString("lblGoogleDriveIntegration.Text");
|
||||
this.lblGoogleDriveIntegration.UseWaitCursor = true;
|
||||
//
|
||||
// btnEnableIntegration
|
||||
//
|
||||
this.btnEnableIntegration.Location = new System.Drawing.Point(3, 55);
|
||||
this.btnEnableIntegration.Name = "btnEnableIntegration";
|
||||
this.btnEnableIntegration.Size = new System.Drawing.Size(172, 23);
|
||||
this.btnEnableIntegration.TabIndex = 1;
|
||||
this.btnEnableIntegration.Text = "Enable Google Drive Integration";
|
||||
this.btnEnableIntegration.UseVisualStyleBackColor = true;
|
||||
this.btnEnableIntegration.Click += new System.EventHandler(this.btnEnableIntegration_Click);
|
||||
//
|
||||
// tlpCloudSaveEnabled
|
||||
//
|
||||
this.tlpCloudSaveEnabled.ColumnCount = 1;
|
||||
this.tlpCloudSaveEnabled.ColumnStyles.Add(new System.Windows.Forms.ColumnStyle(System.Windows.Forms.SizeType.Percent, 100F));
|
||||
this.tlpCloudSaveEnabled.Controls.Add(this.btnDisableIntegration, 0, 2);
|
||||
this.tlpCloudSaveEnabled.Controls.Add(this.flowLayoutPanel3, 0, 0);
|
||||
this.tlpCloudSaveEnabled.Controls.Add(this.flowLayoutPanel4, 0, 1);
|
||||
this.tlpCloudSaveEnabled.Dock = System.Windows.Forms.DockStyle.Fill;
|
||||
this.tlpCloudSaveEnabled.Location = new System.Drawing.Point(0, 100);
|
||||
this.tlpCloudSaveEnabled.Margin = new System.Windows.Forms.Padding(0);
|
||||
this.tlpCloudSaveEnabled.Name = "tlpCloudSaveEnabled";
|
||||
this.tlpCloudSaveEnabled.RowCount = 4;
|
||||
this.tlpCloudSaveEnabled.RowStyles.Add(new System.Windows.Forms.RowStyle());
|
||||
this.tlpCloudSaveEnabled.RowStyles.Add(new System.Windows.Forms.RowStyle());
|
||||
this.tlpCloudSaveEnabled.RowStyles.Add(new System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Percent, 100F));
|
||||
this.tlpCloudSaveEnabled.RowStyles.Add(new System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Absolute, 20F));
|
||||
this.tlpCloudSaveEnabled.Size = new System.Drawing.Size(444, 123);
|
||||
this.tlpCloudSaveEnabled.TabIndex = 1;
|
||||
//
|
||||
// btnDisableIntegration
|
||||
//
|
||||
this.btnDisableIntegration.Location = new System.Drawing.Point(3, 53);
|
||||
this.btnDisableIntegration.Name = "btnDisableIntegration";
|
||||
this.btnDisableIntegration.Size = new System.Drawing.Size(172, 23);
|
||||
this.btnDisableIntegration.TabIndex = 2;
|
||||
this.btnDisableIntegration.Text = "Disable Google Drive Integration";
|
||||
this.btnDisableIntegration.UseVisualStyleBackColor = true;
|
||||
this.btnDisableIntegration.Click += new System.EventHandler(this.btnDisableIntegration_Click);
|
||||
//
|
||||
// flowLayoutPanel3
|
||||
//
|
||||
this.flowLayoutPanel3.Controls.Add(this.picOK);
|
||||
this.flowLayoutPanel3.Controls.Add(this.lblIntegrationOK);
|
||||
this.flowLayoutPanel3.Dock = System.Windows.Forms.DockStyle.Fill;
|
||||
this.flowLayoutPanel3.Location = new System.Drawing.Point(0, 0);
|
||||
this.flowLayoutPanel3.Margin = new System.Windows.Forms.Padding(0);
|
||||
this.flowLayoutPanel3.Name = "flowLayoutPanel3";
|
||||
this.flowLayoutPanel3.Size = new System.Drawing.Size(444, 22);
|
||||
this.flowLayoutPanel3.TabIndex = 1;
|
||||
//
|
||||
// picOK
|
||||
//
|
||||
this.picOK.Image = global::Mesen.GUI.Properties.Resources.Accept;
|
||||
this.picOK.Location = new System.Drawing.Point(3, 3);
|
||||
this.picOK.Name = "picOK";
|
||||
this.picOK.Size = new System.Drawing.Size(16, 16);
|
||||
this.picOK.TabIndex = 0;
|
||||
this.picOK.TabStop = false;
|
||||
//
|
||||
// lblIntegrationOK
|
||||
//
|
||||
this.lblIntegrationOK.Anchor = System.Windows.Forms.AnchorStyles.Left;
|
||||
this.lblIntegrationOK.AutoSize = true;
|
||||
this.lblIntegrationOK.Location = new System.Drawing.Point(25, 4);
|
||||
this.lblIntegrationOK.Name = "lblIntegrationOK";
|
||||
this.lblIntegrationOK.Size = new System.Drawing.Size(166, 13);
|
||||
this.lblIntegrationOK.TabIndex = 1;
|
||||
this.lblIntegrationOK.Text = "Google Drive integration is active.";
|
||||
//
|
||||
// flowLayoutPanel4
|
||||
//
|
||||
this.flowLayoutPanel4.Controls.Add(this.lblLastSync);
|
||||
this.flowLayoutPanel4.Controls.Add(this.lblLastSyncDateTime);
|
||||
this.flowLayoutPanel4.Controls.Add(this.btnResync);
|
||||
this.flowLayoutPanel4.Location = new System.Drawing.Point(0, 22);
|
||||
this.flowLayoutPanel4.Margin = new System.Windows.Forms.Padding(0);
|
||||
this.flowLayoutPanel4.Name = "flowLayoutPanel4";
|
||||
this.flowLayoutPanel4.Size = new System.Drawing.Size(444, 28);
|
||||
this.flowLayoutPanel4.TabIndex = 3;
|
||||
//
|
||||
// lblLastSync
|
||||
//
|
||||
this.lblLastSync.Anchor = System.Windows.Forms.AnchorStyles.Left;
|
||||
this.lblLastSync.AutoSize = true;
|
||||
this.lblLastSync.Location = new System.Drawing.Point(3, 9);
|
||||
this.lblLastSync.Name = "lblLastSync";
|
||||
this.lblLastSync.Size = new System.Drawing.Size(57, 13);
|
||||
this.lblLastSync.TabIndex = 0;
|
||||
this.lblLastSync.Text = "Last Sync:";
|
||||
//
|
||||
// lblLastSyncDateTime
|
||||
//
|
||||
this.lblLastSyncDateTime.Anchor = System.Windows.Forms.AnchorStyles.Left;
|
||||
this.lblLastSyncDateTime.AutoSize = true;
|
||||
this.lblLastSyncDateTime.Location = new System.Drawing.Point(66, 9);
|
||||
this.lblLastSyncDateTime.Name = "lblLastSyncDateTime";
|
||||
this.lblLastSyncDateTime.Size = new System.Drawing.Size(114, 13);
|
||||
this.lblLastSyncDateTime.TabIndex = 1;
|
||||
this.lblLastSyncDateTime.Text = "9999/01/01 12:00 PM";
|
||||
//
|
||||
// btnResync
|
||||
//
|
||||
this.btnResync.AutoSize = true;
|
||||
this.btnResync.AutoSizeMode = System.Windows.Forms.AutoSizeMode.GrowAndShrink;
|
||||
this.btnResync.Image = global::Mesen.GUI.Properties.Resources.Reset;
|
||||
this.btnResync.ImageAlign = System.Drawing.ContentAlignment.MiddleLeft;
|
||||
this.btnResync.Location = new System.Drawing.Point(186, 3);
|
||||
this.btnResync.MinimumSize = new System.Drawing.Size(0, 25);
|
||||
this.btnResync.Name = "btnResync";
|
||||
this.btnResync.Size = new System.Drawing.Size(69, 25);
|
||||
this.btnResync.TabIndex = 4;
|
||||
this.btnResync.Text = "Resync";
|
||||
this.btnResync.TextImageRelation = System.Windows.Forms.TextImageRelation.ImageBeforeText;
|
||||
this.btnResync.UseVisualStyleBackColor = true;
|
||||
this.btnResync.Click += new System.EventHandler(this.btnResync_Click);
|
||||
//
|
||||
// tpgFileAssociations
|
||||
//
|
||||
this.tpgFileAssociations.Controls.Add(this.grpFileAssociations);
|
||||
this.tpgFileAssociations.Location = new System.Drawing.Point(4, 22);
|
||||
this.tpgFileAssociations.Name = "tpgFileAssociations";
|
||||
this.tpgFileAssociations.Padding = new System.Windows.Forms.Padding(3);
|
||||
this.tpgFileAssociations.Size = new System.Drawing.Size(450, 244);
|
||||
this.tpgFileAssociations.Size = new System.Drawing.Size(450, 229);
|
||||
this.tpgFileAssociations.TabIndex = 2;
|
||||
this.tpgFileAssociations.Text = "File Associations";
|
||||
this.tpgFileAssociations.UseVisualStyleBackColor = true;
|
||||
|
@ -265,7 +458,7 @@
|
|||
this.grpFileAssociations.Dock = System.Windows.Forms.DockStyle.Fill;
|
||||
this.grpFileAssociations.Location = new System.Drawing.Point(3, 3);
|
||||
this.grpFileAssociations.Name = "grpFileAssociations";
|
||||
this.grpFileAssociations.Size = new System.Drawing.Size(444, 238);
|
||||
this.grpFileAssociations.Size = new System.Drawing.Size(444, 223);
|
||||
this.grpFileAssociations.TabIndex = 12;
|
||||
this.grpFileAssociations.TabStop = false;
|
||||
this.grpFileAssociations.Text = "File Associations";
|
||||
|
@ -287,7 +480,7 @@
|
|||
this.tlpFileFormat.RowStyles.Add(new System.Windows.Forms.RowStyle());
|
||||
this.tlpFileFormat.RowStyles.Add(new System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Absolute, 20F));
|
||||
this.tlpFileFormat.RowStyles.Add(new System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Absolute, 20F));
|
||||
this.tlpFileFormat.Size = new System.Drawing.Size(438, 219);
|
||||
this.tlpFileFormat.Size = new System.Drawing.Size(438, 204);
|
||||
this.tlpFileFormat.TabIndex = 0;
|
||||
//
|
||||
// chkNesFormat
|
||||
|
@ -337,7 +530,7 @@
|
|||
this.tpgAdvanced.Location = new System.Drawing.Point(4, 22);
|
||||
this.tpgAdvanced.Name = "tpgAdvanced";
|
||||
this.tpgAdvanced.Padding = new System.Windows.Forms.Padding(3);
|
||||
this.tpgAdvanced.Size = new System.Drawing.Size(450, 244);
|
||||
this.tpgAdvanced.Size = new System.Drawing.Size(450, 229);
|
||||
this.tpgAdvanced.TabIndex = 1;
|
||||
this.tpgAdvanced.Text = "Advanced";
|
||||
this.tpgAdvanced.UseVisualStyleBackColor = true;
|
||||
|
@ -361,7 +554,7 @@
|
|||
this.tableLayoutPanel1.RowStyles.Add(new System.Windows.Forms.RowStyle());
|
||||
this.tableLayoutPanel1.RowStyles.Add(new System.Windows.Forms.RowStyle());
|
||||
this.tableLayoutPanel1.RowStyles.Add(new System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Percent, 100F));
|
||||
this.tableLayoutPanel1.Size = new System.Drawing.Size(444, 238);
|
||||
this.tableLayoutPanel1.Size = new System.Drawing.Size(444, 223);
|
||||
this.tableLayoutPanel1.TabIndex = 0;
|
||||
//
|
||||
// chkUseAlternativeMmc3Irq
|
||||
|
@ -414,15 +607,21 @@
|
|||
this.chkFdsFastForwardOnLoad.Text = "Automatically fast forward FDS games when disk or BIOS is loading";
|
||||
this.chkFdsFastForwardOnLoad.UseVisualStyleBackColor = true;
|
||||
//
|
||||
// tmrSyncDateTime
|
||||
//
|
||||
this.tmrSyncDateTime.Enabled = true;
|
||||
this.tmrSyncDateTime.Tick += new System.EventHandler(this.tmrSyncDateTime_Tick);
|
||||
//
|
||||
// frmPreferences
|
||||
//
|
||||
this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
|
||||
this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
|
||||
this.ClientSize = new System.Drawing.Size(458, 299);
|
||||
this.ClientSize = new System.Drawing.Size(458, 284);
|
||||
this.Controls.Add(this.tabMain);
|
||||
this.FormBorderStyle = System.Windows.Forms.FormBorderStyle.FixedSingle;
|
||||
this.MaximizeBox = false;
|
||||
this.MinimizeBox = false;
|
||||
this.MinimumSize = new System.Drawing.Size(474, 322);
|
||||
this.Name = "frmPreferences";
|
||||
this.StartPosition = System.Windows.Forms.FormStartPosition.CenterParent;
|
||||
this.Text = "Preferences";
|
||||
|
@ -434,6 +633,16 @@
|
|||
this.flowLayoutPanel2.PerformLayout();
|
||||
this.tabMain.ResumeLayout(false);
|
||||
this.tpgGeneral.ResumeLayout(false);
|
||||
this.tpgCloudSave.ResumeLayout(false);
|
||||
this.tlpCloudSaves.ResumeLayout(false);
|
||||
this.tlpCloudSaveDesc.ResumeLayout(false);
|
||||
this.tlpCloudSaveDesc.PerformLayout();
|
||||
this.tlpCloudSaveEnabled.ResumeLayout(false);
|
||||
this.flowLayoutPanel3.ResumeLayout(false);
|
||||
this.flowLayoutPanel3.PerformLayout();
|
||||
((System.ComponentModel.ISupportInitialize)(this.picOK)).EndInit();
|
||||
this.flowLayoutPanel4.ResumeLayout(false);
|
||||
this.flowLayoutPanel4.PerformLayout();
|
||||
this.tpgFileAssociations.ResumeLayout(false);
|
||||
this.grpFileAssociations.ResumeLayout(false);
|
||||
this.tlpFileFormat.ResumeLayout(false);
|
||||
|
@ -476,5 +685,20 @@
|
|||
private System.Windows.Forms.FlowLayoutPanel flowLayoutPanel2;
|
||||
private System.Windows.Forms.Label lblDisplayLanguage;
|
||||
private System.Windows.Forms.ComboBox cboDisplayLanguage;
|
||||
private System.Windows.Forms.TabPage tpgCloudSave;
|
||||
private System.Windows.Forms.TableLayoutPanel tlpCloudSaves;
|
||||
private System.Windows.Forms.TableLayoutPanel tlpCloudSaveDesc;
|
||||
private System.Windows.Forms.Label lblGoogleDriveIntegration;
|
||||
private System.Windows.Forms.Button btnEnableIntegration;
|
||||
private System.Windows.Forms.TableLayoutPanel tlpCloudSaveEnabled;
|
||||
private System.Windows.Forms.Button btnDisableIntegration;
|
||||
private System.Windows.Forms.FlowLayoutPanel flowLayoutPanel3;
|
||||
private System.Windows.Forms.PictureBox picOK;
|
||||
private System.Windows.Forms.Label lblIntegrationOK;
|
||||
private System.Windows.Forms.FlowLayoutPanel flowLayoutPanel4;
|
||||
private System.Windows.Forms.Label lblLastSync;
|
||||
private System.Windows.Forms.Label lblLastSyncDateTime;
|
||||
private System.Windows.Forms.Timer tmrSyncDateTime;
|
||||
private System.Windows.Forms.Button btnResync;
|
||||
}
|
||||
}
|
|
@ -8,6 +8,7 @@ using System.Text;
|
|||
using System.Threading.Tasks;
|
||||
using System.Windows.Forms;
|
||||
using Mesen.GUI.Config;
|
||||
using Mesen.GUI.GoogleDriveIntegration;
|
||||
|
||||
namespace Mesen.GUI.Forms.Config
|
||||
{
|
||||
|
@ -40,6 +41,8 @@ namespace Mesen.GUI.Forms.Config
|
|||
AddBinding("AllowBackgroundInput", chkAllowBackgroundInput);
|
||||
|
||||
AddBinding("PauseOnMovieEnd", chkPauseOnMovieEnd);
|
||||
|
||||
UpdateCloudDisplay();
|
||||
}
|
||||
|
||||
protected override void OnFormClosed(FormClosedEventArgs e)
|
||||
|
@ -60,5 +63,64 @@ namespace Mesen.GUI.Forms.Config
|
|||
{
|
||||
System.Diagnostics.Process.Start(ConfigManager.HomeFolder);
|
||||
}
|
||||
|
||||
private void UpdateCloudDisplay()
|
||||
{
|
||||
if(!this.IsDisposed) {
|
||||
if(this.InvokeRequired) {
|
||||
this.BeginInvoke((MethodInvoker)(() => this.UpdateCloudDisplay()));
|
||||
} else {
|
||||
this.tlpCloudSaveDesc.Visible = !ConfigManager.Config.PreferenceInfo.CloudSaveIntegration;
|
||||
this.tlpCloudSaveEnabled.Visible = ConfigManager.Config.PreferenceInfo.CloudSaveIntegration;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void TryEnableSync(bool retry = true)
|
||||
{
|
||||
if(CloudSyncHelper.EnableSync()) {
|
||||
if(!CloudSyncHelper.Sync()) {
|
||||
if(retry) {
|
||||
TryEnableSync(false);
|
||||
} else {
|
||||
MesenMsgBox.Show("GoogleDriveIntegrationError", MessageBoxButtons.OK, MessageBoxIcon.Error);
|
||||
}
|
||||
} else {
|
||||
UpdateCloudDisplay();
|
||||
}
|
||||
} else {
|
||||
MesenMsgBox.Show("GoogleDriveIntegrationError", MessageBoxButtons.OK, MessageBoxIcon.Error);
|
||||
}
|
||||
}
|
||||
|
||||
private void btnEnableIntegration_Click(object sender, EventArgs e)
|
||||
{
|
||||
Task.Run(() => TryEnableSync());
|
||||
}
|
||||
|
||||
private void btnDisableIntegration_Click(object sender, EventArgs e)
|
||||
{
|
||||
Task.Run(() => {
|
||||
CloudSyncHelper.DisableSync();
|
||||
UpdateCloudDisplay();
|
||||
});
|
||||
}
|
||||
|
||||
private void tmrSyncDateTime_Tick(object sender, EventArgs e)
|
||||
{
|
||||
btnDisableIntegration.Enabled = !CloudSyncHelper.Syncing;
|
||||
btnResync.Enabled = btnDisableIntegration.Enabled;
|
||||
|
||||
if(ConfigManager.Config.PreferenceInfo.CloudLastSync != DateTime.MinValue) {
|
||||
lblLastSyncDateTime.Text = ConfigManager.Config.PreferenceInfo.CloudLastSync.ToLongDateString() + " " + ConfigManager.Config.PreferenceInfo.CloudLastSync.ToLongTimeString();
|
||||
} else {
|
||||
lblLastSyncDateTime.Text = "";
|
||||
}
|
||||
}
|
||||
|
||||
private void btnResync_Click(object sender, EventArgs e)
|
||||
{
|
||||
Task.Run(() => CloudSyncHelper.Sync());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -120,4 +120,10 @@
|
|||
<metadata name="toolTip.TrayLocation" type="System.Drawing.Point, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a">
|
||||
<value>17, 17</value>
|
||||
</metadata>
|
||||
<data name="lblGoogleDriveIntegration.Text" xml:space="preserve">
|
||||
<value>Mesen can integrate with Google Drive to keep your save data in the cloud. When Google Drive integration is enabled, your save data is easily accessible from any computer and is synced between computers. Additionally, save data stored on Google Drive can be restored in the event it is erased from your computer.</value>
|
||||
</data>
|
||||
<metadata name="tmrSyncDateTime.TrayLocation" type="System.Drawing.Point, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a">
|
||||
<value>110, 17</value>
|
||||
</metadata>
|
||||
</root>
|
|
@ -14,7 +14,11 @@ namespace Mesen.GUI.Forms
|
|||
string resourceText = ResourceHelper.GetMessage(text, args);
|
||||
|
||||
if(resourceText.StartsWith("[[")) {
|
||||
return MessageBox.Show(string.Format("Critical error (" + text + ") {0}", args), "Mesen", buttons, icon);
|
||||
if(args != null && args.Length > 0) {
|
||||
return MessageBox.Show(string.Format("Critical error (" + text + ") {0}", args), "Mesen", buttons, icon);
|
||||
} else {
|
||||
return MessageBox.Show(string.Format("Critical error (" + text + ")"), "Mesen", buttons, icon);
|
||||
}
|
||||
} else {
|
||||
return MessageBox.Show(ResourceHelper.GetMessage(text, args), "Mesen", buttons, icon);
|
||||
}
|
||||
|
|
12
GUI.NET/Forms/frmMain.Designer.cs
generated
12
GUI.NET/Forms/frmMain.Designer.cs
generated
|
@ -18,19 +18,7 @@ namespace Mesen.GUI.Forms
|
|||
if(disposing && (components != null)) {
|
||||
components.Dispose();
|
||||
}
|
||||
if(_notifListener != null) {
|
||||
_notifListener.Dispose();
|
||||
_notifListener = null;
|
||||
}
|
||||
if(_debugger != null) {
|
||||
_debugger.Close();
|
||||
}
|
||||
|
||||
ConfigManager.Config.VideoInfo.VideoScale = _regularScale;
|
||||
ConfigManager.ApplyChanges();
|
||||
|
||||
StopEmu();
|
||||
InteropEmu.Release();
|
||||
base.Dispose(disposing);
|
||||
}
|
||||
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.ComponentModel;
|
||||
using System.Diagnostics;
|
||||
using System.Drawing;
|
||||
using System.IO;
|
||||
|
@ -15,6 +16,7 @@ using Mesen.GUI.Debugger;
|
|||
using Mesen.GUI.Forms.Cheats;
|
||||
using Mesen.GUI.Forms.Config;
|
||||
using Mesen.GUI.Forms.NetPlay;
|
||||
using Mesen.GUI.GoogleDriveIntegration;
|
||||
|
||||
namespace Mesen.GUI.Forms
|
||||
{
|
||||
|
@ -73,6 +75,10 @@ namespace Mesen.GUI.Forms
|
|||
|
||||
UpdateViewerSize();
|
||||
|
||||
if(ConfigManager.Config.PreferenceInfo.CloudSaveIntegration) {
|
||||
Task.Run(() => CloudSyncHelper.Sync());
|
||||
}
|
||||
|
||||
if(_romToLoad != null) {
|
||||
LoadFile(this._romToLoad);
|
||||
}
|
||||
|
@ -89,6 +95,30 @@ namespace Mesen.GUI.Forms
|
|||
PerformUpgrade();
|
||||
}
|
||||
|
||||
protected override void OnClosing(CancelEventArgs e)
|
||||
{
|
||||
if(_notifListener != null) {
|
||||
_notifListener.Dispose();
|
||||
_notifListener = null;
|
||||
}
|
||||
if(_debugger != null) {
|
||||
_debugger.Close();
|
||||
}
|
||||
|
||||
ConfigManager.Config.VideoInfo.VideoScale = _regularScale;
|
||||
ConfigManager.ApplyChanges();
|
||||
|
||||
StopEmu();
|
||||
|
||||
if(ConfigManager.Config.PreferenceInfo.CloudSaveIntegration) {
|
||||
CloudSyncHelper.Sync();
|
||||
}
|
||||
|
||||
InteropEmu.Release();
|
||||
|
||||
base.OnClosing(e);
|
||||
}
|
||||
|
||||
void PerformUpgrade()
|
||||
{
|
||||
if(new Version(ConfigManager.Config.MesenVersion) < new Version(InteropEmu.GetMesenVersion())) {
|
||||
|
|
|
@ -147,6 +147,46 @@
|
|||
<SignManifests>false</SignManifests>
|
||||
</PropertyGroup>
|
||||
<ItemGroup>
|
||||
<Reference Include="BouncyCastle.Crypto, Version=1.7.4137.9688, Culture=neutral, PublicKeyToken=a4292a325f69b123, processorArchitecture=MSIL">
|
||||
<SpecificVersion>False</SpecificVersion>
|
||||
<HintPath>Dependencies\BouncyCastle.Crypto.dll</HintPath>
|
||||
<Private>False</Private>
|
||||
</Reference>
|
||||
<Reference Include="Google.Apis, Version=1.13.0.0, Culture=neutral, PublicKeyToken=4b01fa6e34db77ab, processorArchitecture=MSIL">
|
||||
<SpecificVersion>False</SpecificVersion>
|
||||
<HintPath>Dependencies\Google.Apis.dll</HintPath>
|
||||
<Private>False</Private>
|
||||
</Reference>
|
||||
<Reference Include="Google.Apis.Auth, Version=1.13.0.0, Culture=neutral, PublicKeyToken=4b01fa6e34db77ab, processorArchitecture=MSIL">
|
||||
<SpecificVersion>False</SpecificVersion>
|
||||
<HintPath>Dependencies\Google.Apis.Auth.dll</HintPath>
|
||||
<Private>False</Private>
|
||||
</Reference>
|
||||
<Reference Include="Google.Apis.Auth.PlatformServices, Version=1.13.0.0, Culture=neutral, PublicKeyToken=4b01fa6e34db77ab, processorArchitecture=MSIL">
|
||||
<SpecificVersion>False</SpecificVersion>
|
||||
<HintPath>Dependencies\Google.Apis.Auth.PlatformServices.dll</HintPath>
|
||||
<Private>False</Private>
|
||||
</Reference>
|
||||
<Reference Include="Google.Apis.Core, Version=1.13.0.0, Culture=neutral, PublicKeyToken=4b01fa6e34db77ab, processorArchitecture=MSIL">
|
||||
<SpecificVersion>False</SpecificVersion>
|
||||
<HintPath>Dependencies\Google.Apis.Core.dll</HintPath>
|
||||
<Private>False</Private>
|
||||
</Reference>
|
||||
<Reference Include="Google.Apis.Drive.v3, Version=1.13.0.483, Culture=neutral, PublicKeyToken=4b01fa6e34db77ab, processorArchitecture=MSIL">
|
||||
<SpecificVersion>False</SpecificVersion>
|
||||
<HintPath>Dependencies\Google.Apis.Drive.v3.dll</HintPath>
|
||||
<Private>False</Private>
|
||||
</Reference>
|
||||
<Reference Include="Google.Apis.PlatformServices, Version=1.13.0.0, Culture=neutral, PublicKeyToken=4b01fa6e34db77ab, processorArchitecture=MSIL">
|
||||
<SpecificVersion>False</SpecificVersion>
|
||||
<HintPath>Dependencies\Google.Apis.PlatformServices.dll</HintPath>
|
||||
<Private>False</Private>
|
||||
</Reference>
|
||||
<Reference Include="Newtonsoft.Json, Version=7.0.0.0, Culture=neutral, PublicKeyToken=30ad4fe6b2a6aeed, processorArchitecture=MSIL">
|
||||
<SpecificVersion>False</SpecificVersion>
|
||||
<HintPath>Dependencies\Newtonsoft.Json.dll</HintPath>
|
||||
<Private>False</Private>
|
||||
</Reference>
|
||||
<Reference Include="System" />
|
||||
<Reference Include="System.Core" />
|
||||
<Reference Include="System.IO.Compression" />
|
||||
|
@ -160,6 +200,11 @@
|
|||
<Reference Include="System.Windows.Forms" />
|
||||
<Reference Include="System.Xml" />
|
||||
<Reference Include="UIAutomationClient" />
|
||||
<Reference Include="Zlib.Portable, Version=1.11.0.0, Culture=neutral, PublicKeyToken=431cba815f6a8b5b, processorArchitecture=MSIL">
|
||||
<SpecificVersion>False</SpecificVersion>
|
||||
<HintPath>Dependencies\Zlib.Portable.dll</HintPath>
|
||||
<Private>False</Private>
|
||||
</Reference>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Compile Include="Config\PreferenceInfo.cs" />
|
||||
|
@ -425,6 +470,9 @@
|
|||
<DependentUpon>frmServerConfig.cs</DependentUpon>
|
||||
</Compile>
|
||||
<Compile Include="Forms\ResourceHelper.cs" />
|
||||
<Compile Include="GoogleDriveIntegration\CloudSyncHelper.cs" />
|
||||
<Compile Include="GoogleDriveIntegration\GoogleDriveAccessor.cs" />
|
||||
<Compile Include="GoogleDriveIntegration\MesenCodeReceiver.cs" />
|
||||
<Compile Include="InteropEmu.cs" />
|
||||
<Compile Include="Program.cs" />
|
||||
<Compile Include="Properties\AssemblyInfo.cs" />
|
||||
|
@ -520,6 +568,7 @@
|
|||
</EmbeddedResource>
|
||||
<EmbeddedResource Include="Forms\Config\frmPreferences.resx">
|
||||
<DependentUpon>frmPreferences.cs</DependentUpon>
|
||||
<SubType>Designer</SubType>
|
||||
</EmbeddedResource>
|
||||
<EmbeddedResource Include="Forms\Config\frmVideoConfig.resx">
|
||||
<DependentUpon>frmVideoConfig.cs</DependentUpon>
|
||||
|
@ -567,12 +616,6 @@
|
|||
<None Include="Dependencies\Font.64.spritefont">
|
||||
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
|
||||
</None>
|
||||
<None Include="Dependencies\MSVCx64.zip">
|
||||
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
|
||||
</None>
|
||||
<None Include="Dependencies\MSVCx86.zip">
|
||||
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
|
||||
</None>
|
||||
<None Include="Properties\Settings.settings">
|
||||
<Generator>SettingsSingleFileGenerator</Generator>
|
||||
<LastGenOutput>Settings.Designer.cs</LastGenOutput>
|
||||
|
@ -584,9 +627,33 @@
|
|||
</Compile>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Content Include="Dependencies\BouncyCastle.Crypto.dll">
|
||||
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
|
||||
</Content>
|
||||
<Content Include="Dependencies\Google.Apis.Auth.dll">
|
||||
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
|
||||
</Content>
|
||||
<Content Include="Dependencies\Google.Apis.Auth.PlatformServices.dll">
|
||||
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
|
||||
</Content>
|
||||
<Content Include="Dependencies\Google.Apis.Core.dll">
|
||||
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
|
||||
</Content>
|
||||
<Content Include="Dependencies\Google.Apis.dll">
|
||||
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
|
||||
</Content>
|
||||
<Content Include="Dependencies\Google.Apis.Drive.v3.dll">
|
||||
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
|
||||
</Content>
|
||||
<Content Include="Dependencies\Google.Apis.PlatformServices.dll">
|
||||
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
|
||||
</Content>
|
||||
<Content Include="Dependencies\LICENSE.txt">
|
||||
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
|
||||
</Content>
|
||||
<Content Include="Dependencies\Newtonsoft.Json.dll">
|
||||
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
|
||||
</Content>
|
||||
<Content Include="Dependencies\resources.en.xml">
|
||||
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
|
||||
<SubType>Designer</SubType>
|
||||
|
@ -603,7 +670,11 @@
|
|||
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
|
||||
<SubType>Designer</SubType>
|
||||
</Content>
|
||||
<Content Include="Dependencies\Zlib.Portable.dll">
|
||||
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
|
||||
</Content>
|
||||
<Content Include="Icon.ico" />
|
||||
<None Include="Resources\accept.png" />
|
||||
<Content Include="Resources\coins.png" />
|
||||
<None Include="Resources\DipSwitches.png" />
|
||||
<None Include="Resources\MesenIcon.png" />
|
||||
|
@ -647,21 +718,13 @@ if "x64" == "$(PlatformName)" copy "C:\Program Files (x86)\Microsoft Visual Stud
|
|||
|
||||
if "PGO Optimize" == "$(ConfigurationName)" (
|
||||
copy "$(SolutionDir)bin\x86\PGO Profile\WinMesen.dll" "Dependencies\WinMesen.x86.dll"
|
||||
copy "$(SolutionDir)bin\x86\PGO Profile\BlipBuffer.dll" "Dependencies\BlipBuffer.x86.dll"
|
||||
copy "$(SolutionDir)bin\x86\PGO Profile\NesNtsc.dll" "Dependencies\NesNtsc.x86.dll"
|
||||
|
||||
copy "$(SolutionDir)bin\x64\PGO Profile\WinMesen.dll" "Dependencies\WinMesen.x64.dll"
|
||||
copy "$(SolutionDir)bin\x64\PGO Profile\BlipBuffer.dll" "Dependencies\BlipBuffer.x64.dll"
|
||||
copy "$(SolutionDir)bin\x64\PGO Profile\NesNtsc.dll" "Dependencies\NesNtsc.x64.dll"
|
||||
)
|
||||
if NOT "PGO Optimize" == "$(ConfigurationName)" (
|
||||
copy "$(SolutionDir)bin\x86\$(ConfigurationName)\WinMesen.dll" "Dependencies\WinMesen.x86.dll"
|
||||
copy "$(SolutionDir)bin\x86\$(ConfigurationName)\BlipBuffer.dll" "Dependencies\BlipBuffer.x86.dll"
|
||||
copy "$(SolutionDir)bin\x86\$(ConfigurationName)\NesNtsc.dll" "Dependencies\NesNtsc.x86.dll"
|
||||
|
||||
copy "$(SolutionDir)bin\x64\$(ConfigurationName)\WinMesen.dll" "Dependencies\WinMesen.x64.dll"
|
||||
copy "$(SolutionDir)bin\x64\$(ConfigurationName)\BlipBuffer.dll" "Dependencies\BlipBuffer.x64.dll"
|
||||
copy "$(SolutionDir)bin\x64\$(ConfigurationName)\NesNtsc.dll" "Dependencies\NesNtsc.x64.dll"
|
||||
)
|
||||
copy "MesenUpdater.exe" "Dependencies\MesenUpdater.exe"
|
||||
call DependencyPacker.exe
|
||||
|
|
145
GUI.NET/GoogleDriveIntegration/CloudSyncHelper.cs
Normal file
145
GUI.NET/GoogleDriveIntegration/CloudSyncHelper.cs
Normal file
|
@ -0,0 +1,145 @@
|
|||
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("Google Drive", "Synchronization started.");
|
||||
using(_accessor = new GoogleDriveAccessor()) {
|
||||
if(!CloudSyncHelper.DownloadData()) {
|
||||
InteropEmu.DisplayMessage("Google Drive", "Synchronization failed.");
|
||||
ConfigManager.Config.PreferenceInfo.CloudLastSync = DateTime.Now;
|
||||
ConfigManager.ApplyChanges();
|
||||
return false;
|
||||
}
|
||||
|
||||
CloudSyncHelper.UploadData();
|
||||
InteropEmu.DisplayMessage("Google Drive", "Synchronization completed.");
|
||||
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.RejectChanges();
|
||||
ConfigManager.Config.PreferenceInfo.CloudSaveIntegration = true;
|
||||
ConfigManager.ApplyChanges();
|
||||
}
|
||||
return result;
|
||||
}
|
||||
}
|
||||
|
||||
public static void DisableSync()
|
||||
{
|
||||
using(_accessor = new GoogleDriveAccessor()) {
|
||||
_accessor.RevokeToken();
|
||||
}
|
||||
|
||||
ConfigManager.RejectChanges();
|
||||
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;
|
||||
}
|
||||
}
|
||||
}
|
203
GUI.NET/GoogleDriveIntegration/GoogleDriveAccessor.cs
Normal file
203
GUI.NET/GoogleDriveIntegration/GoogleDriveAccessor.cs
Normal file
|
@ -0,0 +1,203 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
using Google.Apis.Auth.OAuth2;
|
||||
using Google.Apis.Auth.OAuth2.Responses;
|
||||
using Google.Apis.Download;
|
||||
using Google.Apis.Drive.v3;
|
||||
using Google.Apis.Drive.v3.Data;
|
||||
using Google.Apis.Services;
|
||||
using Google.Apis.Upload;
|
||||
|
||||
namespace Mesen.GUI.GoogleDriveIntegration
|
||||
{
|
||||
public class GoogleDriveAccessor : IDisposable
|
||||
{
|
||||
private const string _contentType = @"application/zip";
|
||||
private readonly string[] _scopes = new[] { DriveService.Scope.DriveAppdata };
|
||||
private File _driveFile = null;
|
||||
private UserCredential _credentials = null;
|
||||
private DriveService _service = null;
|
||||
private bool _connected = false;
|
||||
private bool _revoked = false;
|
||||
|
||||
public bool Revoked { get { return _revoked; } }
|
||||
|
||||
public bool UploadFile(System.IO.MemoryStream fileStream, string filename)
|
||||
{
|
||||
fileStream.Position = 0;
|
||||
try {
|
||||
this.Connect().GetAwaiter().GetResult();
|
||||
if(_connected) {
|
||||
this.UploadFileAsync(fileStream, filename).GetAwaiter().GetResult();
|
||||
}
|
||||
} catch(TokenResponseException ex) {
|
||||
_revoked = true;
|
||||
_connected = false;
|
||||
_credentials = null;
|
||||
_service = null;
|
||||
} catch {
|
||||
_connected = false;
|
||||
_credentials = null;
|
||||
_service = null;
|
||||
}
|
||||
|
||||
return _connected;
|
||||
}
|
||||
|
||||
public bool DownloadFile(System.IO.MemoryStream fileStream, string filename)
|
||||
{
|
||||
try {
|
||||
this.Connect().GetAwaiter().GetResult();
|
||||
|
||||
if(_connected) {
|
||||
this.DownloadFileAsync(fileStream, filename).GetAwaiter().GetResult();
|
||||
}
|
||||
} catch(TokenResponseException ex) {
|
||||
_revoked = true;
|
||||
_connected = false;
|
||||
_credentials = null;
|
||||
_service = null;
|
||||
} catch {
|
||||
_connected = false;
|
||||
_credentials = null;
|
||||
_service = null;
|
||||
}
|
||||
return _connected;
|
||||
}
|
||||
|
||||
public bool AcquireToken()
|
||||
{
|
||||
this.Connect().GetAwaiter().GetResult();
|
||||
|
||||
return _connected;
|
||||
}
|
||||
|
||||
public void RevokeToken()
|
||||
{
|
||||
Task.Run(async () => {
|
||||
try {
|
||||
_credentials = await this.GetCredentials().ConfigureAwait(false);
|
||||
await _credentials.RevokeTokenAsync(CancellationToken.None).ConfigureAwait(false);
|
||||
} catch {
|
||||
}
|
||||
_service = null;
|
||||
_credentials = null;
|
||||
}).Wait();
|
||||
}
|
||||
|
||||
private async Task Connect()
|
||||
{
|
||||
if(_service == null) {
|
||||
try {
|
||||
_credentials = await this.GetCredentials().ConfigureAwait(false);
|
||||
_service = new DriveService(new BaseClientService.Initializer() {
|
||||
HttpClientInitializer = _credentials,
|
||||
ApplicationName = "Mesen",
|
||||
});
|
||||
_connected = true;
|
||||
} catch(AggregateException ex) {
|
||||
foreach(Exception innerException in ex.InnerExceptions) {
|
||||
if(innerException is TokenResponseException) {
|
||||
_connected = false;
|
||||
_revoked = true;
|
||||
}
|
||||
}
|
||||
_connected = false;
|
||||
_credentials = null;
|
||||
_service = null;
|
||||
} catch {
|
||||
_connected = false;
|
||||
_credentials = null;
|
||||
_service = null;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private async Task<UserCredential> GetCredentials()
|
||||
{
|
||||
var clientSecrets = new ClientSecrets { ClientId = "478233037635-nf90q052c32suhm0l8r9fkkk34k7hkl5.apps.googleusercontent.com", ClientSecret = "zGatV81vs5kKuhHq3fZuw4lc" };
|
||||
GoogleWebAuthorizationBroker.Folder = System.IO.Path.Combine(Config.ConfigManager.HomeFolder, "GoogleDrive");
|
||||
|
||||
return await GoogleWebAuthorizationBroker.AuthorizeAsync(clientSecrets, _scopes, Environment.UserName, CancellationToken.None, codeReceiver: new MesenCodeReceiver()).ConfigureAwait(false);
|
||||
}
|
||||
|
||||
private File GetFileMatchingName(string filename)
|
||||
{
|
||||
var listService = _service.Files.List();
|
||||
listService.Spaces = "appDataFolder";
|
||||
|
||||
foreach(File file in listService.Execute().Files) {
|
||||
if(file.Name == filename) {
|
||||
return file;
|
||||
}
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
private Task<IUploadProgress> UploadFileAsync(System.IO.MemoryStream fileStream, string filename)
|
||||
{
|
||||
File driveFile = this.GetFileMatchingName(filename);
|
||||
|
||||
Task<IUploadProgress> task;
|
||||
if(driveFile == null) {
|
||||
//File does not exist, create it
|
||||
var insert = _service.Files.Create(new File { Name = "MesenData.zip", Parents = new List<string>() { "appDataFolder" } }, fileStream, _contentType);
|
||||
insert.ChunkSize = FilesResource.CreateMediaUpload.MinimumChunkSize * 2;
|
||||
insert.ResponseReceived += Upload_ResponseReceived;
|
||||
|
||||
task = insert.UploadAsync();
|
||||
} else {
|
||||
//File exists, update it
|
||||
var update = _service.Files.Update(null, driveFile.Id, fileStream, _contentType);
|
||||
update.ResponseReceived += Upload_ResponseReceived;
|
||||
task = update.UploadAsync();
|
||||
}
|
||||
|
||||
task.ContinueWith(t => {
|
||||
// NotOnRanToCompletion - this code will be called if the upload fails
|
||||
Console.WriteLine("Upload Failed. " + t.Exception);
|
||||
}, TaskContinuationOptions.NotOnRanToCompletion);
|
||||
|
||||
task.ContinueWith(t => {
|
||||
fileStream.Dispose();
|
||||
});
|
||||
|
||||
return task;
|
||||
}
|
||||
|
||||
private async Task DownloadFileAsync(System.IO.MemoryStream outStream, string filename)
|
||||
{
|
||||
File driveFile = this.GetFileMatchingName(filename);
|
||||
|
||||
if(driveFile != null) {
|
||||
var request = _service.Files.Get(driveFile.Id);
|
||||
var progress = await request.DownloadAsync(outStream).ConfigureAwait(false);
|
||||
if(progress.Status == DownloadStatus.Completed) {
|
||||
_driveFile = driveFile;
|
||||
} else {
|
||||
_driveFile = null;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private async Task DeleteFile(File file)
|
||||
{
|
||||
await _service.Files.Delete(file.Id).ExecuteAsync().ConfigureAwait(false);
|
||||
}
|
||||
|
||||
void Upload_ResponseReceived(File file)
|
||||
{
|
||||
_driveFile = file;
|
||||
}
|
||||
|
||||
void IDisposable.Dispose()
|
||||
{
|
||||
if(_service != null) {
|
||||
_service.Dispose();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
101
GUI.NET/GoogleDriveIntegration/MesenCodeReceiver.cs
Normal file
101
GUI.NET/GoogleDriveIntegration/MesenCodeReceiver.cs
Normal file
|
@ -0,0 +1,101 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Collections.Specialized;
|
||||
using System.Diagnostics;
|
||||
using System.Linq;
|
||||
using System.Net;
|
||||
using System.Net.Sockets;
|
||||
using System.Text;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
using Google.Apis.Auth.OAuth2;
|
||||
using Google.Apis.Auth.OAuth2.Requests;
|
||||
using Google.Apis.Auth.OAuth2.Responses;
|
||||
|
||||
namespace Mesen.GUI.GoogleDriveIntegration
|
||||
{
|
||||
public class MesenCodeReceiver : LocalServerCodeReceiver, ICodeReceiver
|
||||
{
|
||||
private const string baseResponse =
|
||||
@"<html>
|
||||
<head>
|
||||
<title>Mesen - Authentication Successful</title>
|
||||
<style>
|
||||
html, body {
|
||||
font-family: Calibri;
|
||||
height:100%;
|
||||
background-color: #EEE;
|
||||
}
|
||||
img {
|
||||
margin: 10px;
|
||||
vertical-align: middle;
|
||||
}
|
||||
div {
|
||||
background-color: #FFF;
|
||||
position: relative;
|
||||
top: 50px;
|
||||
|
||||
margin:auto;
|
||||
width:600px;
|
||||
height:154px;
|
||||
border:1px solid #999;
|
||||
text-align:center;
|
||||
}
|
||||
span {
|
||||
vertical-align: middle;
|
||||
}
|
||||
</style>
|
||||
</head>";
|
||||
|
||||
private const string successResponse = baseResponse +
|
||||
@"<body>
|
||||
<div>
|
||||
<img src='http://www.mesen.ca/Images/MesenIcon.png'/><span>Mesen - Authentication Successful</span><br/>
|
||||
Mesen will now save battery files and save states in your Google Drive account.<br/>
|
||||
<br/>
|
||||
Please close this window.
|
||||
</div>
|
||||
</body>
|
||||
</html>";
|
||||
|
||||
private const string failureResponse = baseResponse +
|
||||
@"<body>
|
||||
<div>
|
||||
<img src='http://www.mesen.ca/Images/MesenIcon.png'/><span>Mesen - Authentication <span style='color:red'>Failed</span></span><br/>
|
||||
Mesen was unable to integrate with your Google Drive account - please close this window and try again.<br/>
|
||||
</div>
|
||||
</body>
|
||||
</html>";
|
||||
|
||||
async Task<AuthorizationCodeResponseUrl> ICodeReceiver.ReceiveCodeAsync(AuthorizationCodeRequestUrl url, CancellationToken taskCancellationToken)
|
||||
{
|
||||
var authorizationUrl = url.Build().ToString();
|
||||
using(var listener = new HttpListener()) {
|
||||
listener.Prefixes.Add(RedirectUri);
|
||||
try {
|
||||
listener.Start();
|
||||
|
||||
Process.Start(authorizationUrl);
|
||||
|
||||
// Wait to get the authorization code response.
|
||||
var context = await listener.GetContextAsync().ConfigureAwait(false);
|
||||
NameValueCollection coll = context.Request.QueryString;
|
||||
|
||||
// Write a "close" response.
|
||||
Thread.Sleep(200);
|
||||
|
||||
// Create a new response URL with a dictionary that contains all the response query parameters.
|
||||
var codeResponse = new AuthorizationCodeResponseUrl(coll.AllKeys.ToDictionary(k => k, k => coll[k]));
|
||||
using(var writer = new System.IO.StreamWriter(context.Response.OutputStream)) {
|
||||
writer.WriteLine(string.IsNullOrWhiteSpace(codeResponse.Error) ? successResponse : failureResponse);
|
||||
writer.Flush();
|
||||
}
|
||||
context.Response.OutputStream.Close();
|
||||
return codeResponse;
|
||||
} finally {
|
||||
listener.Close();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -3,6 +3,7 @@ using System.Collections.Generic;
|
|||
using System.Diagnostics;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Reflection;
|
||||
using System.Runtime.ExceptionServices;
|
||||
using System.Runtime.InteropServices;
|
||||
using System.Threading;
|
||||
|
@ -29,6 +30,26 @@ namespace Mesen.GUI
|
|||
MesenMsgBox.Show("UnexpectedError", MessageBoxButtons.OK, MessageBoxIcon.Error, e.ExceptionObject.ToString());
|
||||
}
|
||||
|
||||
[DebuggerNonUserCode]
|
||||
private static Assembly LoadAssemblies(object sender, ResolveEventArgs e)
|
||||
{
|
||||
//Allow assemblies to be loaded from subfolders in the home folder (used for Google Drive API dlls)
|
||||
string assemblyFile = e.Name.Contains(',') ? e.Name.Substring(0, e.Name.IndexOf(',')) : e.Name;
|
||||
assemblyFile += ".dll";
|
||||
|
||||
string absoluteFolder = new FileInfo((new System.Uri(Assembly.GetExecutingAssembly().CodeBase)).LocalPath).Directory.FullName;
|
||||
string targetPath = Path.Combine(ConfigManager.HomeFolder, "GoogleDrive", assemblyFile);
|
||||
|
||||
try {
|
||||
if(File.Exists(targetPath)) {
|
||||
return Assembly.LoadFile(targetPath);
|
||||
}
|
||||
} catch(Exception) {
|
||||
return null;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// The main entry point for the application.
|
||||
/// </summary>
|
||||
|
@ -37,6 +58,7 @@ namespace Mesen.GUI
|
|||
private static void Main(string[] args)
|
||||
{
|
||||
try {
|
||||
AppDomain.CurrentDomain.AssemblyResolve += LoadAssemblies;
|
||||
Application.SetUnhandledExceptionMode(UnhandledExceptionMode.CatchException);
|
||||
Application.ThreadException += Application_ThreadException;
|
||||
AppDomain.CurrentDomain.UnhandledException += CurrentDomain_UnhandledException;
|
||||
|
|
10
GUI.NET/Properties/Resources.Designer.cs
generated
10
GUI.NET/Properties/Resources.Designer.cs
generated
|
@ -60,6 +60,16 @@ namespace Mesen.GUI.Properties {
|
|||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Looks up a localized resource of type System.Drawing.Bitmap.
|
||||
/// </summary>
|
||||
internal static System.Drawing.Bitmap Accept {
|
||||
get {
|
||||
object obj = ResourceManager.GetObject("Accept", resourceCulture);
|
||||
return ((System.Drawing.Bitmap)(obj));
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Looks up a localized resource of type System.Drawing.Bitmap.
|
||||
/// </summary>
|
||||
|
|
|
@ -199,4 +199,7 @@
|
|||
<data name="DipSwitches" type="System.Resources.ResXFileRef, System.Windows.Forms">
|
||||
<value>..\Resources\DipSwitches.png;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a</value>
|
||||
</data>
|
||||
<data name="Accept" type="System.Resources.ResXFileRef, System.Windows.Forms">
|
||||
<value>..\Resources\accept.png;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a</value>
|
||||
</data>
|
||||
</root>
|
|
@ -52,29 +52,46 @@ namespace Mesen.GUI
|
|||
return null;
|
||||
}
|
||||
|
||||
private static void CleanupOldFiles()
|
||||
{
|
||||
try {
|
||||
if(Directory.Exists(Path.Combine(ConfigManager.HomeFolder, "Resources"))) {
|
||||
Directory.Delete(Path.Combine(ConfigManager.HomeFolder, "Resources"), true);
|
||||
}
|
||||
|
||||
if(Directory.Exists(Path.Combine(ConfigManager.HomeFolder, "WinMesen"))) {
|
||||
Directory.Delete(Path.Combine(ConfigManager.HomeFolder, "WinMesen"), true);
|
||||
}
|
||||
if(File.Exists(Path.Combine(ConfigManager.HomeFolder, "NesNtsc.dll"))) {
|
||||
File.Delete(Path.Combine(ConfigManager.HomeFolder, "NesNtsc.dll"));
|
||||
}
|
||||
if(File.Exists(Path.Combine(ConfigManager.HomeFolder, "BlipBuffer.dll"))) {
|
||||
File.Delete(Path.Combine(ConfigManager.HomeFolder, "BlipBuffer.dll"));
|
||||
}
|
||||
} catch { }
|
||||
}
|
||||
|
||||
public static void ExtractResources()
|
||||
{
|
||||
CleanupOldFiles();
|
||||
|
||||
Directory.CreateDirectory(Path.Combine(ConfigManager.HomeFolder, "Resources"));
|
||||
Directory.CreateDirectory(Path.Combine(ConfigManager.HomeFolder, "WinMesen"));
|
||||
Directory.CreateDirectory(Path.Combine(ConfigManager.HomeFolder, "GoogleDrive"));
|
||||
|
||||
ZipArchive zip = new ZipArchive(Assembly.GetExecutingAssembly().GetManifestResourceStream("Mesen.GUI.Dependencies.Dependencies.zip"));
|
||||
|
||||
//Extract all needed files
|
||||
string suffix = IntPtr.Size == 4 ? ".x86" : ".x64";
|
||||
foreach(ZipArchiveEntry entry in zip.Entries) {
|
||||
if(entry.Name == "MSVCx64.zip" && IntPtr.Size == 8 || entry.Name == "MSVCx86.zip" && IntPtr.Size == 4) {
|
||||
using(Stream stream = entry.Open()) {
|
||||
ZipArchive msvcZip = new ZipArchive(stream);
|
||||
foreach(ZipArchiveEntry msvcEntry in msvcZip.Entries) {
|
||||
ExtractFile(msvcEntry, Path.Combine(ConfigManager.HomeFolder, "WinMesen", msvcEntry.Name));
|
||||
}
|
||||
}
|
||||
} else if(entry.Name.Contains(suffix)) {
|
||||
string outputFilename = Path.Combine(ConfigManager.HomeFolder, "WinMesen", entry.Name.Replace(suffix, ""));
|
||||
if(entry.Name.Contains(suffix)) {
|
||||
string outputFilename = Path.Combine(ConfigManager.HomeFolder, entry.Name.Replace(suffix, ""));
|
||||
ExtractFile(entry, outputFilename);
|
||||
} else if(entry.Name == "MesenUpdater.exe") {
|
||||
string outputFilename = Path.Combine(ConfigManager.HomeFolder, entry.Name.Replace(suffix, ""));
|
||||
ExtractFile(entry, outputFilename);
|
||||
} else if(entry.Name.StartsWith("Google.Apis") || entry.Name == "BouncyCastle.Crypto.dll" || entry.Name == "Zlib.Portable.dll" || entry.Name == "Newtonsoft.Json.dll") {
|
||||
string outputFilename = Path.Combine(ConfigManager.HomeFolder, "GoogleDrive", entry.Name.Replace(suffix, ""));
|
||||
ExtractFile(entry, outputFilename);
|
||||
} else if(entry.Name == "Font.24.spritefont" || entry.Name == "Font.64.spritefont" || entry.Name == "LICENSE.txt") {
|
||||
string outputFilename = Path.Combine(ConfigManager.HomeFolder, "Resources", entry.Name.Replace(suffix, ""));
|
||||
ExtractFile(entry, outputFilename);
|
||||
|
|
BIN
GUI.NET/Resources/accept.png
Normal file
BIN
GUI.NET/Resources/accept.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 643 B |
|
@ -17,11 +17,8 @@ namespace Mesen.GUI
|
|||
public static bool TestDll()
|
||||
{
|
||||
try {
|
||||
Directory.SetCurrentDirectory(Path.Combine(ConfigManager.HomeFolder, "WinMesen"));
|
||||
return InteropEmu.TestDll();
|
||||
} catch {
|
||||
} finally {
|
||||
Directory.SetCurrentDirectory(Path.Combine(ConfigManager.HomeFolder));
|
||||
}
|
||||
|
||||
if(!File.Exists("WinMesen.dll")) {
|
||||
|
|
|
@ -382,6 +382,8 @@ namespace NES
|
|||
}
|
||||
_pDeviceContext->Unmap(_pTexture[0], 0);
|
||||
|
||||
_needFlip = true;
|
||||
|
||||
_frameLock.Release();
|
||||
|
||||
_frameChanged = true;
|
||||
|
@ -390,9 +392,12 @@ namespace NES
|
|||
void Renderer::DrawNESScreen()
|
||||
{
|
||||
//Swap buffers - emulator always writes to texture 0, screen always draws texture 1 (allows us to release a lock earlier while avoiding crashes)
|
||||
ID3D11Texture2D *texture = _pTexture[0];
|
||||
_pTexture[0] = _pTexture[1];
|
||||
_pTexture[1] = texture;
|
||||
if(_needFlip) {
|
||||
ID3D11Texture2D *texture = _pTexture[0];
|
||||
_pTexture[0] = _pTexture[1];
|
||||
_pTexture[1] = texture;
|
||||
_needFlip = false;
|
||||
}
|
||||
|
||||
ID3D11ShaderResourceView *nesOutputBuffer = GetShaderResourceView(_pTexture[1]);
|
||||
|
||||
|
|
|
@ -29,6 +29,7 @@ namespace NES {
|
|||
|
||||
ID3D11SamplerState* _samplerState = nullptr;
|
||||
|
||||
atomic<bool> _needFlip = false;
|
||||
ID3D11Texture2D* _pTexture[2] = { nullptr,nullptr };
|
||||
ID3D11Texture2D* _overlayTexture = nullptr;
|
||||
|
||||
|
|
Loading…
Add table
Reference in a new issue