LSLEditor/trunk/UpdateApplicationForm.cs
2012-03-18 05:52:21 +00:00

510 lines
No EOL
14 KiB
C#

// /**
// ********
// *
// * ORIGINAL CODE BASE IS Copyright (C) 2006-2010 by Alphons van der Heijden
// * The code was donated on 4/28/2010 by Alphons van der Heijden
// * To Brandon 'Dimentox Travanti' Husbands & Malcolm J. Kudra, who in turn License under the GPLv2.
// * In agreement with Alphons van der Heijden's wishes.
// *
// * The community would like to thank Alphons for all of his hard work, blood sweat and tears.
// * Without his work the community would be stuck with crappy editors.
// *
// * The source code in this file ("Source Code") is provided by The LSLEditor Group
// * to you under the terms of the GNU General Public License, version 2.0
// * ("GPL"), unless you have obtained a separate licensing agreement
// * ("Other License"), formally executed by you and The LSLEditor Group. Terms of
// * the GPL can be found in the gplv2.txt document.
// *
// ********
// * GPLv2 Header
// ********
// * LSLEditor, a External editor for the LSL Language.
// * Copyright (C) 2010 The LSLEditor Group.
//
// * This program is free software; you can redistribute it and/or
// * modify it under the terms of the GNU General Public License
// * as published by the Free Software Foundation; either version 2
// * of the License, or (at your option) any later version.
// *
// * This program is distributed in the hope that it will be useful,
// * but WITHOUT ANY WARRANTY; without even the implied warranty of
// * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// * GNU General Public License for more details.
// *
// * You should have received a copy of the GNU General Public License
// * along with this program; if not, write to the Free Software
// * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
// ********
// *
// * The above copyright notice and this permission notice shall be included in all
// * copies or substantial portions of the Software.
// *
// ********
// */
using System;
using System.IO;
using System.Net;
using System.Reflection;
using System.ComponentModel;
using System.Windows.Forms;
using LSLEditor.Decompressor;
namespace LSLEditor
{
public partial class UpdateApplicationForm : Form
{
private WebClient manifest;
private WebClient client;
private string strHashWeb;
private string strDownloadUrl;
private string strHelpHashWeb;
private string strHelpUrl;
private string strHelpReferer;
private bool blnOnlyHelpFile;
private struct versionInfo
{
public Version version;
public string hash;
public string uri;
public versionInfo(string ver)
{
version = new Version(ver);
hash = "";
uri = "";
}
public versionInfo(string ver, string md5)
{
version = new Version(ver);
hash = md5;
uri = "";
}
public versionInfo(string ver, string md5, string URI)
{
version = new Version(ver);
hash = md5;
uri = URI;
}
}
public UpdateApplicationForm()
{
InitializeComponent();
this.strHashWeb = "";
this.strHelpHashWeb = "";
this.strDownloadUrl = null;
this.strHelpUrl = null;
this.strHelpReferer = null;
this.buttonUpdate.Enabled = false;
this.blnOnlyHelpFile = false;
}
public event EventHandler OnUpdateAvailable;
private void StartDownloadinManifest()
{
Uri url;
string strVersion = Assembly.GetExecutingAssembly().GetName().Version.ToString();
if (Path.GetFileNameWithoutExtension(Assembly.GetExecutingAssembly().Location).Contains("beta"))
url = new Uri(Properties.Settings.Default.UpdateManifest + "?beta-" + strVersion);
else
url = new Uri(Properties.Settings.Default.UpdateManifest + "?" + strVersion);
manifest = new WebClient();
manifest.DownloadStringCompleted += new DownloadStringCompletedEventHandler(manifest_DownloadCompleted);
manifest.DownloadStringAsync(url);
}
public void CheckForHelpFile()
{
this.blnOnlyHelpFile = true;
StartDownloadinManifest();
}
public void CheckForUpdate(bool blnForce)
{
if (!blnForce)
{
if (Properties.Settings.Default.DeleteOldFiles)
DeleteOldFile();
DateTime dateTime = Properties.Settings.Default.CheckDate;
if (Properties.Settings.Default.CheckEveryDay)
{
TimeSpan lastUpdate = DateTime.Now - dateTime;
if (lastUpdate.TotalDays >= 1.0)
blnForce = true;
}
else if (Properties.Settings.Default.CheckEveryWeek)
{
TimeSpan lastUpdate = DateTime.Now - dateTime;
if(lastUpdate.TotalDays >= 7.0)
blnForce = true;
}
}
if (blnForce)
{
Properties.Settings.Default.CheckDate = DateTime.Now;
Properties.Settings.Default.Save(); // save also all settings
StartDownloadinManifest();
}
}
void manifest_DownloadCompleted(object sender, DownloadStringCompletedEventArgs e)
{
if (e.Error != null)
return;
versionInfo bzip = new versionInfo();
versionInfo gzip = new versionInfo();
versionInfo wzip = new versionInfo();
versionInfo web = new versionInfo();
versionInfo current = new versionInfo(Assembly.GetExecutingAssembly().GetName().Version.ToString());
current.hash = Decompressor.MD5Verify.ComputeHash(Assembly.GetExecutingAssembly().Location);
current.uri = "";
string strHelpHashMe = "";
string strHelpFile = Path.Combine(Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location), Properties.Settings.Default.HelpOfflineFile);
if (File.Exists(strHelpFile))
{
strHelpHashMe = Decompressor.MD5Verify.ComputeHash(strHelpFile);
}
else
{
// help file does not exist
if (Properties.Settings.Default.HelpOffline || blnOnlyHelpFile)
{
strHelpHashMe = "*"; // force new update
}
else
{
strHelpHashMe = ""; // no update
this.labelHelpFile.Visible = false;
this.labelHelpversionString.Visible = false;
}
}
StringReader sr = new StringReader(e.Result);
for (int intI = 0; intI < 255; intI++)
{
string strLine = sr.ReadLine();
if (strLine == null)
break;
int intSplit = strLine.IndexOf("=");
if (intSplit < 0)
continue;
string strName = strLine.Substring(0, intSplit);
string strValue = strLine.Substring(intSplit + 1);
//All hashes are of the uncompressed file. However, different archives may contain different versions.
switch (strName)
{
case "Version":
case "BZipVersion":
bzip = new versionInfo(strValue);
break;
case "Hash":
case "BZipHash":
bzip.hash = strValue;
break;
case "Url":
case "BZipUrl":
bzip.uri = strValue;
break;
case "GZipVersion":
gzip = new versionInfo(strValue);
break;
case "GZipHash":
gzip.hash = strValue;
break;
case "GZipUrl":
gzip.uri = strValue;
break;
case "ZipVersion":
wzip = new versionInfo(strValue);
break;
case "ZipHash":
wzip.hash = strValue;
break;
case "ZipUrl":
wzip.uri = strValue;
break;
case "HelpHash":
strHelpHashWeb = strValue;
break;
case "HelpUrl2":
strHelpUrl = strValue;
break;
case "HelpReferer":
strHelpReferer = strValue;
break;
default:
break;
}
}
web = bzip;
/*
if (!String.IsNullOrEmpty(gzip.uri) && (gzip.compare(web) == 1))
{
web = gzip;
}
if (!String.IsNullOrEmpty(wzip.uri) && (wzip.compare(web) == 1))
{
web = wzip;
}
*/
strHashWeb = web.hash;
this.labelOurVersionString.Text = current.version.ToString();
this.labelLatestVersionString.Text = web.version.ToString();
if (String.IsNullOrEmpty(web.uri) || (web.version.CompareTo(current.version) != 1))
{
return;
}
if (strHelpHashMe == "")
strHelpHashMe = strHelpHashWeb;
if (strHelpHashMe == strHelpHashWeb)
{
this.labelHelpversionString.Text = "Up to date";
this.strHelpUrl = null;
}
else
{
this.labelHelpversionString.Text = "Out of date";
}
if (current.hash == web.hash)
{
this.strDownloadUrl = null;
}
else
{
this.strDownloadUrl = web.uri;
}
if (this.blnOnlyHelpFile)
{
this.strDownloadUrl = null;
this.labelLatestVersion.Visible = false;
this.labelLatestVersionString.Visible = false;
}
if (this.strHelpUrl != null || this.strDownloadUrl != null)
{
this.buttonUpdate.Enabled = true;
if (OnUpdateAvailable != null)
OnUpdateAvailable(this, null);
}
}
private void buttonCancel_Click(object sender, EventArgs e)
{
this.Close();
}
private void buttonUpdate_Click(object sender, EventArgs e)
{
this.buttonUpdate.Enabled = false;
Download();
}
private void Download()
{
if (strHelpUrl != null)
DownloadHelpFile(); // starts also DownloadProgram when finished
else
DownloadProgram();
}
private void DownloadHelpFile()
{
if (strHelpUrl == null)
return;
Uri url = new Uri(strHelpUrl);
client = new WebClient();
if(this.strHelpReferer != null)
client.Headers.Add("Referer", strHelpReferer);
client.DownloadFileCompleted += new AsyncCompletedEventHandler(client_DownloadHelpFileCompleted);
client.DownloadProgressChanged += new DownloadProgressChangedEventHandler(client_DownloadProgressChanged);
string strCurrentFile = Assembly.GetExecutingAssembly().Location;
string strDirectory = Path.GetDirectoryName(strCurrentFile);
string strNewFile = Path.Combine(strDirectory, Properties.Settings.Default.HelpOfflineFile);
if (File.Exists(strNewFile))
File.Delete(strNewFile);
client.DownloadFileAsync(url, strNewFile);
}
void client_DownloadHelpFileCompleted(object sender, AsyncCompletedEventArgs e)
{
try
{
if (e.Error != null)
throw e.Error;
string strCurrentFile = Assembly.GetExecutingAssembly().Location;
string strDirectory = Path.GetDirectoryName(strCurrentFile);
string strNewFile = Path.Combine(strDirectory, Properties.Settings.Default.HelpOfflineFile);
string strComputedHash = Decompressor.MD5Verify.ComputeHash(strNewFile);
if (strComputedHash != strHelpHashWeb)
{
this.buttonUpdate.Enabled = true;
throw new Exception("MD5 Hash of HelpFile not correct, try downloading again!");
}
if (this.strDownloadUrl != null)
DownloadProgram();
else
this.Close();
}
catch (Exception exception)
{
MessageBox.Show(exception.Message, "Oops...", MessageBoxButtons.OK, MessageBoxIcon.Error);
}
}
private void DownloadProgram()
{
if (strDownloadUrl == null)
return;
Uri url = new Uri(strDownloadUrl);
client = new WebClient();
client.DownloadFileCompleted += new AsyncCompletedEventHandler(client_DownloadFileCompleted);
client.DownloadProgressChanged += new DownloadProgressChangedEventHandler(client_DownloadProgressChanged);
string strCurrentFile = Assembly.GetExecutingAssembly().Location;
string strDirectory = Path.GetDirectoryName(strCurrentFile);
string strNewFileName = Path.GetFileName(strDownloadUrl);
string strNewFile = Path.Combine(strDirectory, strNewFileName);
if (File.Exists(strNewFile))
File.Delete(strNewFile);
client.DownloadFileAsync(url, strNewFile, strNewFileName);
}
void client_DownloadProgressChanged(object sender, DownloadProgressChangedEventArgs e)
{
this.progressBar1.Value = e.ProgressPercentage;
}
void client_DownloadFileCompleted(object sender, AsyncCompletedEventArgs e)
{
try
{
if (e.Error != null)
throw e.Error;
string strNewFileName = e.UserState.ToString();
string strCurrentFile = Assembly.GetExecutingAssembly().Location;
string strDirectory = Path.GetDirectoryName(strCurrentFile);
string strZipFile = Path.Combine(strDirectory, strNewFileName);
string strNewFile = Path.Combine(strDirectory, "LSLEditor.exe.new");
string strOldFile = Path.Combine(strDirectory, "_LSLEditor.exe");
string strExtension = Path.GetExtension(strNewFileName);
switch (strExtension)
{
case ".bz2":
Decompressor.BZip2.Decompress(File.OpenRead(strZipFile), File.Create(strNewFile));
break;
case ".gz":
case ".gzip":
Decompressor.Gzip.Decompress(File.OpenRead(strZipFile), File.Create(strNewFile));
break;
case ".zip":
Decompressor.Zip.Decompress(File.OpenRead(strZipFile), File.Create(strNewFile));
break;
default:
break;
}
string strComputedHash = Decompressor.MD5Verify.ComputeHash(strNewFile);
if (strComputedHash == strHashWeb)
{
if (File.Exists(strOldFile))
File.Delete(strOldFile);
File.Move(strCurrentFile, strOldFile);
File.Move(strNewFile, strCurrentFile);
if (File.Exists(strZipFile))
File.Delete(strZipFile);
// save all there is pending (if any)
Properties.Settings.Default.Save();
System.Diagnostics.Process.Start(strCurrentFile);
Environment.Exit(0);
}
else
{
this.buttonUpdate.Enabled = true;
throw new Exception("MD5 Hash not correct, try downloading again!");
}
}
catch (Exception exception)
{
MessageBox.Show(exception.Message, "Oops...", MessageBoxButtons.OK, MessageBoxIcon.Error);
}
}
private void UpdateApplicationForm_FormClosing(object sender, FormClosingEventArgs e)
{
if (client != null)
{
if (client.IsBusy)
client.CancelAsync();
client.Dispose();
}
client = null;
if (manifest != null)
{
if (manifest.IsBusy)
manifest.CancelAsync();
manifest.Dispose();
}
manifest = null;
}
private void DeleteOldFile()
{
string strCurrentFile = Assembly.GetExecutingAssembly().Location;
string strDirectory = Path.GetDirectoryName(strCurrentFile);
string strOldFile = Path.Combine(strDirectory, "_LSLEditor.exe");
if (File.Exists(strOldFile))
File.Delete(strOldFile);
}
}
}