mirror of
https://git.do.srb2.org/STJr/SRB2.git
synced 2024-12-23 11:10:56 +00:00
658 lines
27 KiB
C#
658 lines
27 KiB
C#
using System;
|
|
using System.Collections.Generic;
|
|
using System.ComponentModel;
|
|
using System.Data;
|
|
//using System.Data.OleDb;
|
|
using System.Xml;
|
|
//using System.Drawing;
|
|
using System.Text;
|
|
using System.Windows.Forms;
|
|
using System.Net;
|
|
using System.IO;
|
|
using System.Threading;
|
|
using System.Security.Cryptography;
|
|
//using System.Runtime.InteropServices;
|
|
using System.Diagnostics;
|
|
using System.Drawing;
|
|
using System.Media;
|
|
|
|
namespace SRB2Updater
|
|
{
|
|
public partial class Launcher : Form
|
|
{
|
|
private Settings settings = new Settings();
|
|
private Debug debug = new Debug();
|
|
// The thread inside which the download happens
|
|
private Thread thrDownload;
|
|
private Thread thrTotal;
|
|
// The stream of data retrieved from the web server
|
|
private Stream strResponse;
|
|
// The stream of data that we write to the harddrive
|
|
private Stream strLocal;
|
|
// The request to the web server for file information
|
|
private HttpWebRequest webRequest;
|
|
// The response from the web server containing information about the file
|
|
private HttpWebResponse webResponse;
|
|
// The progress of the download in percentage
|
|
private static int PercentProgress;
|
|
private static int OverallPercentProgress;
|
|
// Overall progress as a percentage
|
|
private static Int64 OverallProgress;
|
|
// Progress stored, for calculating overall
|
|
private static Int64 CurrentProgress;
|
|
// Total File Size of entire update
|
|
private static Int64 TotalSize;
|
|
// The delegate which we will call from the thread to update the form
|
|
private delegate void UpdateProgessCallback(Int64 BytesRead, Int64 TotalBytes);
|
|
private delegate void OverallProgessCallback(Int64 BytesRead);
|
|
// When to pause
|
|
bool goPause = false;
|
|
// Download Details
|
|
string downFile;
|
|
// Updating
|
|
bool filesGot = false;
|
|
bool downloadStatus = false;
|
|
bool doneCalculate = false;
|
|
string formTitle = "Sonic Robo Blast 2 Launcher";
|
|
bool loadedBat = false;
|
|
ProcessStartInfo startinfo = new ProcessStartInfo();
|
|
private ServerQuerier sq;
|
|
private string MSFail;
|
|
|
|
public Launcher(string[] args)
|
|
{
|
|
InitializeComponent();
|
|
settings.GetSettings();
|
|
sq = new ServerQuerier();
|
|
ServerInfoListViewAdder silva = new ServerInfoListViewAdder(sq, this);
|
|
try
|
|
{
|
|
sq.SetMasterServer(settings.msAddress, Convert.ToUInt16(settings.msPort));
|
|
}
|
|
catch (Exception exception)
|
|
{
|
|
MSFail = exception.Message;
|
|
}
|
|
sq.StartListening(silva);
|
|
backgroundWorkerQueryServers.RunWorkerAsync();
|
|
foreach (string arg in args)
|
|
{
|
|
if (arg == "-debug")
|
|
{
|
|
debug.Show();
|
|
break;
|
|
}
|
|
}
|
|
RandomBanner();
|
|
}
|
|
|
|
public string getMD5(string filename)
|
|
{
|
|
StringBuilder sb = new StringBuilder();
|
|
FileInfo f = new FileInfo(filename);
|
|
FileStream fs = f.OpenRead();
|
|
MD5 md5 = new MD5CryptoServiceProvider();
|
|
byte[] hash = md5.ComputeHash(fs);
|
|
fs.Close();
|
|
foreach (byte hex in hash)
|
|
sb.Append(hex.ToString("x2"));
|
|
string md5sum = sb.ToString();
|
|
return md5sum;
|
|
}
|
|
|
|
public void PlayIt()
|
|
{
|
|
SoundPlayer player = new SoundPlayer(Properties.Resources.Kotaku);
|
|
player.Play();
|
|
}
|
|
|
|
public void RandomBanner()
|
|
{
|
|
Random random = new Random();
|
|
int rand = random.Next(0, 4);
|
|
//this.bannerRandom.BackgroundImage = global::SRB2Updater.Properties.Resources.Banner;
|
|
switch (rand)
|
|
{
|
|
case 0:
|
|
bannerRandom.BackgroundImage = global::SRB2Updater.Properties.Resources.Banner;
|
|
break;
|
|
case 1:
|
|
bannerRandom.BackgroundImage = global::SRB2Updater.Properties.Resources.Banner2;
|
|
break;
|
|
case 2:
|
|
bannerRandom.BackgroundImage = global::SRB2Updater.Properties.Resources.Banner3;
|
|
break;
|
|
case 3:
|
|
bannerRandom.BackgroundImage = global::SRB2Updater.Properties.Resources.Banner4;
|
|
break;
|
|
default:
|
|
bannerRandom.BackgroundImage = global::SRB2Updater.Properties.Resources.Banner;
|
|
break;
|
|
}
|
|
|
|
debug.strRandom = Convert.ToString(rand);
|
|
}
|
|
|
|
private void updateList(bool doCalculate)
|
|
{
|
|
if (filesGot == false)
|
|
{
|
|
|
|
XmlDataDocument xmlDatadoc = new XmlDataDocument();
|
|
xmlDatadoc.DataSet.ReadXml("http://update.srb2.org/files_beta/files_beta.xml");
|
|
DataSet ds = new DataSet("Files DataSet");
|
|
ds = xmlDatadoc.DataSet;
|
|
fileList.DataSource = ds.DefaultViewManager;
|
|
fileList.DataMember = "File";
|
|
filesGot = true;
|
|
}
|
|
if (downloadStatus == false)
|
|
{
|
|
foreach (DataGridViewRow fileRow in fileList.Rows)
|
|
{
|
|
if (!File.Exists(fileRow.Cells["filename"].Value.ToString()) && fileRow.Cells["filename"].Value.ToString() != "srb2update.update")
|
|
{
|
|
// fileRow.DefaultCellStyle.BackColor = System.Drawing.Color.FromArgb(((int)(((byte)(192)))), ((int)(((byte)(255)))), ((int)(((byte)(192)))));
|
|
fileRow.Cells["localmd5"].Value = "not_found";
|
|
} else {
|
|
if (fileRow.Cells["filename"].Value.ToString() == "srb2update.update")
|
|
fileRow.Cells["localmd5"].Value = getMD5("srb2update.exe");
|
|
else
|
|
fileRow.Cells["localmd5"].Value = getMD5(fileRow.Cells["filename"].Value.ToString());
|
|
}
|
|
if (fileRow.Cells["localmd5"].Value.ToString() != fileRow.Cells["md5"].Value.ToString())
|
|
{
|
|
// if (fileRow.Cells["localmd5"].Value.ToString() != "not_found")
|
|
// fileRow.DefaultCellStyle.BackColor = System.Drawing.Color.FromArgb(((int)(((byte)(230)))), ((int)(((byte)(224)))), ((int)(((byte)(206)))));
|
|
fileRow.Cells["status"].Value = "Queued";
|
|
|
|
}
|
|
else
|
|
{
|
|
fileRow.Cells["status"].Value = "Up to date";
|
|
}
|
|
}
|
|
if (doCalculate)
|
|
{
|
|
thrTotal = new Thread(new ParameterizedThreadStart(CalculateTotalSize));
|
|
thrTotal.Start(0);
|
|
}
|
|
if (doneCalculate)
|
|
{
|
|
foreach (DataGridViewRow fileRow in fileList.Rows)
|
|
{
|
|
if (fileRow.Cells["localmd5"].Value.ToString() != fileRow.Cells["md5"].Value.ToString())
|
|
{
|
|
if (fileRow.Cells["optional"].Value.ToString() == "1" && !update_optional.Checked)
|
|
fileRow.Cells["Status"].Value = "Skipped (Optional)";
|
|
else
|
|
{
|
|
downFile = fileRow.Cells["filename"].Value.ToString();
|
|
thrDownload = new Thread(new ParameterizedThreadStart(Download));
|
|
thrDownload.Start(0);
|
|
fileRow.Cells["Status"].Value = "Downloading...";
|
|
downloadStatus = true;
|
|
break;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
fileRow.Cells["Status"].Value = "Up to date";
|
|
}
|
|
CurrentProgress = 0;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
private void UpdateProgress(Int64 BytesRead, Int64 TotalBytes)
|
|
{
|
|
// Calculate the download progress in percentages
|
|
PercentProgress = Convert.ToInt32((BytesRead * 100) / TotalBytes);
|
|
// Make progress on the progress bar
|
|
progress_currentFile.Value = PercentProgress;
|
|
// Display the current progress on the form
|
|
lblProgress.Text = downFile + " - " + (BytesRead / 1024) + "KB of " + (TotalBytes / 1024) + "KB (" + PercentProgress + "%)";
|
|
this.Text = formTitle + " :: Downloading " + downFile + " (" + PercentProgress + "%)";
|
|
debug.strPercent = PercentProgress.ToString() + "%";
|
|
if (BytesRead >= TotalBytes - 1)
|
|
updateList(false);
|
|
}
|
|
|
|
private void UpdateOverallProgress(Int64 BytesRead)
|
|
{
|
|
// Calculate progress change and add to OverallProgress...
|
|
OverallProgress += BytesRead - CurrentProgress;
|
|
// Calculate the download progress in percentages
|
|
if (TotalSize < 1)
|
|
TotalSize = 1;
|
|
OverallPercentProgress = Convert.ToInt32((OverallProgress * 100) / TotalSize);
|
|
// Make progress on the progress bar
|
|
if (OverallPercentProgress > 100)
|
|
OverallPercentProgress = 100;
|
|
progress_overall.Value = OverallPercentProgress;
|
|
if (OverallProgress >= TotalSize)
|
|
{
|
|
lblProgress.Text = "Done";
|
|
btnCheckFiles.Enabled = true;
|
|
}
|
|
CurrentProgress = BytesRead;
|
|
debug.strCurrent = Convert.ToString(CurrentProgress) + " bytes";
|
|
debug.strOverall = Convert.ToString(OverallProgress) + " bytes";
|
|
debug.strOverallPercentage = Convert.ToString(OverallPercentProgress) + "%";
|
|
debug.strRead = Convert.ToString(BytesRead) + " bytes";
|
|
debug.strTotal = Convert.ToString(TotalSize) + " bytes";
|
|
}
|
|
|
|
private void CalculateTotalSize(object startpoint)
|
|
{
|
|
foreach (DataGridViewRow fileRow in fileList.Rows)
|
|
{
|
|
if ((fileRow.Cells["optional"].Value.ToString() == "0" || update_optional.Checked) && fileRow.Cells["localmd5"].Value.ToString() != fileRow.Cells["md5"].Value.ToString())
|
|
{
|
|
try
|
|
{
|
|
// Create a request to the file we are downloading
|
|
webRequest = (HttpWebRequest)WebRequest.Create("http://update.srb2.org/files_beta/" + fileRow.Cells["filename"].Value.ToString());
|
|
// Set the starting point of the request
|
|
webRequest.AddRange(0);
|
|
|
|
// Set default authentication for retrieving the file
|
|
webRequest.Credentials = CredentialCache.DefaultCredentials;
|
|
// Retrieve the response from the server
|
|
webResponse = (HttpWebResponse)webRequest.GetResponse();
|
|
// Ask the server for the file size and store it
|
|
Int64 fileSize = webResponse.ContentLength;
|
|
TotalSize = TotalSize + fileSize;
|
|
}
|
|
finally
|
|
{
|
|
// When the above code has ended, close the streams
|
|
webResponse.Close();
|
|
}
|
|
}
|
|
}
|
|
doneCalculate = true;
|
|
updateList(false);
|
|
}
|
|
|
|
private void Download(object startpoint)
|
|
{
|
|
try
|
|
{
|
|
string filename = Convert.ToString(startpoint);
|
|
// Create a request to the file we are downloading
|
|
webRequest = (HttpWebRequest)WebRequest.Create("http://update.srb2.org/files_beta/" + downFile);
|
|
// Set the starting point of the request
|
|
webRequest.AddRange(0);
|
|
|
|
// Set default authentication for retrieving the file
|
|
webRequest.Credentials = CredentialCache.DefaultCredentials;
|
|
// Retrieve the response from the server
|
|
webResponse = (HttpWebResponse)webRequest.GetResponse();
|
|
// Ask the server for the file size and store it
|
|
Int64 fileSize = webResponse.ContentLength;
|
|
|
|
// Open the URL for download
|
|
strResponse = webResponse.GetResponseStream();
|
|
|
|
// Create a new file stream where we will be saving the data (local drive)
|
|
strLocal = new FileStream(downFile, FileMode.Create, FileAccess.Write, FileShare.None);
|
|
// It will store the current number of bytes we retrieved from the server
|
|
int bytesSize = 0;
|
|
// A buffer for storing and writing the data retrieved from the server
|
|
byte[] downBuffer = new byte[2048];
|
|
|
|
// Loop through the buffer until the buffer is empty
|
|
while ((bytesSize = strResponse.Read(downBuffer, 0, downBuffer.Length)) > 0)
|
|
{
|
|
// Write the data from the buffer to the local hard drive
|
|
strLocal.Write(downBuffer, 0, bytesSize);
|
|
// Invoke the method that updates the form's label and progress bar
|
|
this.Invoke(new UpdateProgessCallback(this.UpdateProgress), new object[] { strLocal.Length, fileSize });
|
|
this.Invoke(new OverallProgessCallback(this.UpdateOverallProgress), new object[] { strLocal.Length });
|
|
|
|
if (goPause == true)
|
|
{
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
finally
|
|
{
|
|
// When the above code has ended, close the streams
|
|
strResponse.Close();
|
|
strLocal.Close();
|
|
// And update the row!
|
|
downloadStatus = false;
|
|
if (downFile == "srb2update.update" && loadedBat != true)
|
|
{
|
|
MessageBox.Show("The updater will now restart to apply a patch.", "Self Update", MessageBoxButtons.OK);
|
|
CreateUpdaterBat();
|
|
startinfo.WindowStyle = ProcessWindowStyle.Hidden;
|
|
startinfo.FileName = "srb2update.bat";
|
|
System.Diagnostics.Process.Start(startinfo);
|
|
downloadStatus = false;
|
|
Environment.Exit(0);
|
|
} else
|
|
updateList(false);
|
|
}
|
|
}
|
|
|
|
private void CreateUpdaterBat()
|
|
{
|
|
File.WriteAllText("srb2update.bat", "ping 127.0.0.1\ncopy srb2update.update srb2update.exe\ndel srb2update.update\nsrb2update.exe\nexit");
|
|
}
|
|
|
|
|
|
private void update_Load(object sender, EventArgs e)
|
|
{
|
|
lblProgress.Text = "Getting File List...";
|
|
if (File.Exists("srb2update.bat"))
|
|
File.Delete("srb2update.bat");
|
|
TotalSize = 0;
|
|
CurrentProgress = 0;
|
|
OverallPercentProgress = 0;
|
|
OverallProgress = 0;
|
|
btnCheckFiles.Enabled = false;
|
|
updateList(true);
|
|
}
|
|
|
|
private void btnOptions_Click(object sender, EventArgs e)
|
|
{
|
|
new Options(settings).ShowDialog();
|
|
}
|
|
|
|
private class ServerInfoListViewAdder : ServerQuerier.ServerInfoReceiveHandler
|
|
{
|
|
private delegate ListViewItem AddToListCallback(ListViewItem lvi);
|
|
private Launcher form1;
|
|
private Dictionary<byte, string> dicGametypes = new Dictionary<byte, string>();
|
|
private static Dictionary<ServerQuerier.ServerInfoVer, List<String>> dicDefaultFiles =
|
|
new Dictionary<ServerQuerier.ServerInfoVer, List<String>>();
|
|
|
|
static ServerInfoListViewAdder()
|
|
{
|
|
dicDefaultFiles.Add(
|
|
ServerQuerier.ServerInfoVer.SIV_PREME,
|
|
new List<String>(
|
|
new string[] {
|
|
"srb2.srb", "sonic.plr", "tails.plr", "knux.plr",
|
|
"auto.wpn", "bomb.wpn", "home.wpn", "rail.wpn", "infn.wpn",
|
|
"drill.dta", "soar.dta", "music.dta"
|
|
})
|
|
);
|
|
|
|
dicDefaultFiles.Add(
|
|
ServerQuerier.ServerInfoVer.SIV_ME,
|
|
new List<String>(
|
|
new string[] {
|
|
"srb2.wad", "sonic.plr", "tails.plr", "knux.plr",
|
|
"rings.wpn", "drill.dta", "soar.dta", "music.dta"
|
|
})
|
|
);
|
|
}
|
|
|
|
|
|
public ServerInfoListViewAdder(ServerQuerier sq, Launcher form1)
|
|
: base(sq)
|
|
{
|
|
this.form1 = form1;
|
|
|
|
// Gametypes.
|
|
dicGametypes.Add(0, "Co-op");
|
|
dicGametypes.Add(1, "Match");
|
|
dicGametypes.Add(2, "Race");
|
|
dicGametypes.Add(3, "Tag");
|
|
dicGametypes.Add(4, "CTF");
|
|
dicGametypes.Add(5, "Chaos");
|
|
|
|
// Don't think these are actually used.
|
|
dicGametypes.Add(42, "Team Match");
|
|
dicGametypes.Add(43, "Time-Only Race");
|
|
}
|
|
|
|
public override void ProcessServerInfo(ServerQuerier.SRB2ServerInfo srb2si)
|
|
{
|
|
ListView lv = form1.listViewServers;
|
|
|
|
// Build a list item.
|
|
ListViewItem lvi = new ListViewItem(srb2si.strName);
|
|
|
|
// So we can get address and whatever else we might need.
|
|
lvi.Tag = srb2si;
|
|
|
|
// Gametype string, or number if not recognised.
|
|
if (dicGametypes.ContainsKey(srb2si.byGametype))
|
|
lvi.SubItems.Add(dicGametypes[srb2si.byGametype]);
|
|
else
|
|
lvi.SubItems.Add(Convert.ToString(srb2si.byGametype));
|
|
|
|
lvi.SubItems.Add(Convert.ToString(srb2si.uiTime));
|
|
lvi.SubItems.Add(srb2si.byPlayers + "/" + srb2si.byMaxplayers);
|
|
lvi.SubItems.Add(srb2si.strVersion);
|
|
|
|
// Make the tooltip.
|
|
BuildTooltip(lvi, form1.settings.ShowDefaultWads);
|
|
|
|
// Is the game full?
|
|
if (srb2si.byPlayers >= srb2si.byMaxplayers)
|
|
lvi.ForeColor = Color.DimGray;
|
|
// Modified?
|
|
else if (srb2si.bModified)
|
|
lvi.ForeColor = Color.Red;
|
|
|
|
// Thread-safe goodness.
|
|
if (lv.InvokeRequired)
|
|
{
|
|
// Call ourselves in the context of the form's thread.
|
|
AddToListCallback addtolistcallback = new AddToListCallback(lv.Items.Add);
|
|
lv.Invoke(addtolistcallback, new object[] { lvi });
|
|
}
|
|
else
|
|
{
|
|
// Add it!
|
|
lv.Items.Add(lvi);
|
|
}
|
|
|
|
}
|
|
|
|
public override void HandleException(Exception e)
|
|
{
|
|
|
|
}
|
|
|
|
public static void BuildTooltip(ListViewItem lvi, bool bShowDefaultWads)
|
|
{
|
|
string strWads = String.Empty;
|
|
ServerQuerier.SRB2ServerInfo srb2si = (ServerQuerier.SRB2ServerInfo)lvi.Tag;
|
|
|
|
foreach (ServerQuerier.AddedWad aw in srb2si.listFiles)
|
|
{
|
|
List<string> listDefaultFiles = dicDefaultFiles[srb2si.siv];
|
|
|
|
if (bShowDefaultWads || !listDefaultFiles.Contains(aw.strFilename))
|
|
{
|
|
strWads += String.Format("\n{0} ({1:f1} KB)", aw.strFilename, Convert.ToSingle(aw.uiSize) / 1024);
|
|
if (aw.bImportant)
|
|
{
|
|
if (aw.downloadtype == ServerQuerier.DownloadTypes.DT_TOOBIG)
|
|
strWads += " (too big to download)";
|
|
else if (aw.downloadtype == ServerQuerier.DownloadTypes.DT_DISABLED)
|
|
strWads += " (downloading disabled)";
|
|
}
|
|
else strWads += " (unimportant)";
|
|
}
|
|
}
|
|
|
|
lvi.ToolTipText = "Current map: " + srb2si.strMapName + "\n";
|
|
if (strWads != String.Empty)
|
|
lvi.ToolTipText += "Wads added:" + strWads;
|
|
else lvi.ToolTipText += "No wads added";
|
|
}
|
|
}
|
|
|
|
private void backgroundWorkerQueryServers_DoWork(object sender, DoWorkEventArgs e)
|
|
{
|
|
MSClient msclient = new MSClient();
|
|
|
|
try
|
|
{
|
|
List<MSServerEntry> listServers = msclient.GetServerList(settings.msAddress, Convert.ToUInt16(settings.msPort));
|
|
|
|
|
|
// Query each of the individual servers asynchronously.
|
|
foreach (MSServerEntry msse in listServers)
|
|
{
|
|
sq.Query(msse.strAddress, msse.unPort);
|
|
}
|
|
}
|
|
catch (System.Net.Sockets.SocketException sockexception)
|
|
{
|
|
MSFail = sockexception.Message;
|
|
}
|
|
catch (Exception exception)
|
|
{
|
|
MSFail = exception.Message;
|
|
}
|
|
}
|
|
|
|
private void btnRefresh_Click(object sender, EventArgs e)
|
|
{
|
|
if (!backgroundWorkerQueryServers.IsBusy)
|
|
{
|
|
// Clear the server list.
|
|
listViewServers.Items.Clear();
|
|
|
|
// Disable the Connect button.
|
|
btnConnect.Enabled = false;
|
|
|
|
// Query the MS and the individual servers in another thread.
|
|
backgroundWorkerQueryServers.RunWorkerAsync();
|
|
}
|
|
}
|
|
|
|
private void btnConnect_Click(object sender, EventArgs e)
|
|
{
|
|
if (listViewServers.SelectedItems.Count > 0)
|
|
{
|
|
ConnectToServerFromListItem(listViewServers.SelectedItems[0]);
|
|
}
|
|
}
|
|
|
|
private void ConnectToServerFromListItem(ListViewItem lvi)
|
|
{
|
|
ServerQuerier.SRB2ServerInfo srb2si = (ServerQuerier.SRB2ServerInfo)lvi.Tag;
|
|
|
|
// Prompt to get a binary if we need one.
|
|
if (!settings.HasBinaryForVersion(srb2si.strVersion) &&
|
|
MessageBox.Show("To join this game, you must register an executable file for version " + srb2si.strVersion + ". Would you like to do so?", Text, MessageBoxButtons.YesNo, MessageBoxIcon.Exclamation) == DialogResult.Yes &&
|
|
openFileDialog1.ShowDialog() == DialogResult.OK)
|
|
{
|
|
settings.SetBinary(srb2si.strVersion, openFileDialog1.FileName);
|
|
settings.SaveSettings();
|
|
}
|
|
|
|
// Go!
|
|
ConnectToServer(srb2si.strAddress, srb2si.unPort, srb2si.strVersion);
|
|
}
|
|
|
|
private void ConnectToServer(string strAddress, ushort unPort, string strVersion)
|
|
{
|
|
// Make sure we now have a binary.
|
|
if (settings.HasBinaryForVersion(strVersion))
|
|
{
|
|
try
|
|
{
|
|
string strBinary = settings.GetBinary(strVersion);
|
|
string strDirectory = System.IO.Path.GetDirectoryName(strBinary);
|
|
if (strDirectory != String.Empty)
|
|
System.IO.Directory.SetCurrentDirectory(strDirectory);
|
|
System.Diagnostics.Process.Start(strBinary, System.String.Format("-connect {0}:{1} {2}", strAddress, unPort, settings.Params)).Close();
|
|
if (settings.CloseOnStart)
|
|
Environment.Exit(0);
|
|
}
|
|
catch (Exception exception)
|
|
{
|
|
MessageBox.Show("Unable to start SRB2: " + exception.Message + ".", "SRB2 MS Launcher", MessageBoxButtons.OK, MessageBoxIcon.Error);
|
|
}
|
|
}
|
|
}
|
|
|
|
private class ListViewSorter : System.Collections.IComparer
|
|
{
|
|
private int iColumn;
|
|
public int Column { get { return iColumn; } }
|
|
public SortOrder so;
|
|
|
|
public ListViewSorter(int iColumn)
|
|
{
|
|
this.iColumn = iColumn;
|
|
so = SortOrder.Ascending;
|
|
}
|
|
|
|
public int Compare(object x, object y)
|
|
{
|
|
ListViewItem lviX = (ListViewItem)x;
|
|
ListViewItem lviY = (ListViewItem)y;
|
|
|
|
return ((so == SortOrder.Ascending) ? 1 : -1) * String.Compare(lviX.SubItems[iColumn].Text, lviY.SubItems[iColumn].Text);
|
|
}
|
|
|
|
public void ToggleSortOrder()
|
|
{
|
|
if (so != SortOrder.Ascending)
|
|
so = SortOrder.Ascending;
|
|
else
|
|
so = SortOrder.Descending;
|
|
}
|
|
}
|
|
|
|
private void listViewServers_ColumnClick(object sender, ColumnClickEventArgs e)
|
|
{
|
|
if (listViewServers.ListViewItemSorter != null &&
|
|
((ListViewSorter)listViewServers.ListViewItemSorter).Column == e.Column)
|
|
{
|
|
((ListViewSorter)listViewServers.ListViewItemSorter).ToggleSortOrder();
|
|
listViewServers.Sort();
|
|
}
|
|
else
|
|
{
|
|
listViewServers.ListViewItemSorter = new ListViewSorter(e.Column);
|
|
}
|
|
}
|
|
|
|
private void listViewServers_SelectedIndexChanged(object sender, EventArgs e)
|
|
{
|
|
btnConnect.Enabled = (listViewServers.SelectedItems.Count > 0);
|
|
}
|
|
|
|
private void listViewServers_ItemActivate(object sender, EventArgs e)
|
|
{
|
|
ConnectToServerFromListItem(listViewServers.SelectedItems[0]);
|
|
}
|
|
|
|
private void Launcher_FormClosed(object sender, FormClosedEventArgs e)
|
|
{
|
|
Environment.Exit(0);
|
|
}
|
|
|
|
private Bunny sequence = new Bunny();
|
|
|
|
private void Launcher_KeyUp(object sender, KeyEventArgs e)
|
|
{
|
|
if (sequence.IsCompletedBy(e.KeyCode))
|
|
{
|
|
PlayIt();
|
|
}
|
|
debug.strKonami = Convert.ToString(sequence.Position);
|
|
}
|
|
|
|
private void btnStartSRB2_Click(object sender, EventArgs e)
|
|
{
|
|
System.Diagnostics.Process.Start("srb2win.exe", System.String.Format("{0}", settings.Params)).Close();
|
|
if(settings.CloseOnStart)
|
|
Environment.Exit(0);
|
|
}
|
|
}
|
|
}
|