mirror of
https://github.com/ClassiCube/ClassiCube.git
synced 2025-09-13 17:47:12 -04:00
Significantly refactor launcher. Public servers list and 'minecraft.net/classicube.net server' tabs are merged into one tab. As both the minecraft.net and classicube.net tabs essentially shared the exact same functionality, this functionality is encapsulated in a new 'GameState' class.
This commit is contained in:
parent
536845393c
commit
f88405330c
@ -36,7 +36,9 @@
|
|||||||
<AllowUnsafeBlocks>False</AllowUnsafeBlocks>
|
<AllowUnsafeBlocks>False</AllowUnsafeBlocks>
|
||||||
<NoStdLib>False</NoStdLib>
|
<NoStdLib>False</NoStdLib>
|
||||||
<WarningLevel>4</WarningLevel>
|
<WarningLevel>4</WarningLevel>
|
||||||
<TreatWarningsAsErrors>false</TreatWarningsAsErrors>
|
<TreatWarningsAsErrors>False</TreatWarningsAsErrors>
|
||||||
|
<NoWin32Manifest>False</NoWin32Manifest>
|
||||||
|
<IntermediateOutputPath>obj\$(Configuration)\</IntermediateOutputPath>
|
||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
<PropertyGroup Condition=" '$(Platform)' == 'AnyCPU' ">
|
<PropertyGroup Condition=" '$(Platform)' == 'AnyCPU' ">
|
||||||
<PlatformTarget>AnyCPU</PlatformTarget>
|
<PlatformTarget>AnyCPU</PlatformTarget>
|
||||||
@ -52,6 +54,7 @@
|
|||||||
<Optimize>False</Optimize>
|
<Optimize>False</Optimize>
|
||||||
<CheckForOverflowUnderflow>True</CheckForOverflowUnderflow>
|
<CheckForOverflowUnderflow>True</CheckForOverflowUnderflow>
|
||||||
<DefineConstants>DEBUG;TRACE</DefineConstants>
|
<DefineConstants>DEBUG;TRACE</DefineConstants>
|
||||||
|
<BaseIntermediateOutputPath>obj\</BaseIntermediateOutputPath>
|
||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
<PropertyGroup Condition=" '$(Configuration)' == 'Release' ">
|
<PropertyGroup Condition=" '$(Configuration)' == 'Release' ">
|
||||||
<OutputPath>..\output\release\</OutputPath>
|
<OutputPath>..\output\release\</OutputPath>
|
||||||
@ -77,6 +80,7 @@
|
|||||||
<Compile Include="MainForm.Designer.cs">
|
<Compile Include="MainForm.Designer.cs">
|
||||||
<DependentUpon>MainForm.cs</DependentUpon>
|
<DependentUpon>MainForm.cs</DependentUpon>
|
||||||
</Compile>
|
</Compile>
|
||||||
|
<Compile Include="MainForm.GameState.cs" />
|
||||||
<Compile Include="MinecraftSession.cs" />
|
<Compile Include="MinecraftSession.cs" />
|
||||||
<Compile Include="Program.cs" />
|
<Compile Include="Program.cs" />
|
||||||
<Compile Include="Properties\AssemblyInfo.cs" />
|
<Compile Include="Properties\AssemblyInfo.cs" />
|
||||||
|
1482
Launcher/MainForm.Designer.cs
generated
1482
Launcher/MainForm.Designer.cs
generated
File diff suppressed because it is too large
Load Diff
184
Launcher/MainForm.GameState.cs
Normal file
184
Launcher/MainForm.GameState.cs
Normal file
@ -0,0 +1,184 @@
|
|||||||
|
using System;
|
||||||
|
using System.Collections;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Drawing;
|
||||||
|
using System.Net;
|
||||||
|
using System.Threading;
|
||||||
|
using System.Windows.Forms;
|
||||||
|
|
||||||
|
namespace Launcher {
|
||||||
|
|
||||||
|
public delegate void Action<T1, T2>( T1 arg1, T2 arg2 );
|
||||||
|
|
||||||
|
internal class GameState {
|
||||||
|
public ProgressBar Progress;
|
||||||
|
public Label Status;
|
||||||
|
public TextBox Username, Password;
|
||||||
|
public List<ServerListEntry> Servers;
|
||||||
|
public string HostServer;
|
||||||
|
public GameSession Session;
|
||||||
|
public Button SignInButton;
|
||||||
|
public TabControl Tab;
|
||||||
|
public TabPage ServersTab;
|
||||||
|
public ListView ServersTable;
|
||||||
|
public TextBox Hash;
|
||||||
|
public Predicate<ServerListEntry> Filter;
|
||||||
|
public MainForm form;
|
||||||
|
|
||||||
|
public void DoSignIn() {
|
||||||
|
if( String.IsNullOrEmpty( Username.Text ) ) {
|
||||||
|
MessageBox.Show( "Please enter a username." );
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if( String.IsNullOrEmpty( Password.Text ) ) {
|
||||||
|
MessageBox.Show( "Please enter a password." );
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if( Session.Username != null ) {
|
||||||
|
Session.ResetSession();
|
||||||
|
ServersTable.Items.Clear();
|
||||||
|
Servers.Clear();
|
||||||
|
}
|
||||||
|
SignInButton.Enabled = false;
|
||||||
|
Tab.TabPages.Remove( ServersTab );
|
||||||
|
Thread loginThread = new Thread( LoginAsync );
|
||||||
|
loginThread.Name = "Launcher.LoginAsync_" + HostServer;
|
||||||
|
loginThread.IsBackground = true;
|
||||||
|
loginThread.Start();
|
||||||
|
}
|
||||||
|
|
||||||
|
void LoginAsync() {
|
||||||
|
SetStatus( 0, "Signing in.." );
|
||||||
|
try {
|
||||||
|
Session.Login( Username.Text, Password.Text );
|
||||||
|
} catch( WebException ex ) {
|
||||||
|
Session.Username = null;
|
||||||
|
LoginEnd( false );
|
||||||
|
DisplayWebException( ex, "sign in", SetStatus );
|
||||||
|
return;
|
||||||
|
} catch( InvalidOperationException ex ) {
|
||||||
|
Session.Username = null;
|
||||||
|
LoginEnd( false );
|
||||||
|
string text = "Failed to sign in: " + Environment.NewLine + ex.Message;
|
||||||
|
SetStatus( 0, text );
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
SetStatus( 50, "Retrieving public servers list.." );
|
||||||
|
try {
|
||||||
|
Servers = Session.GetPublicServers();
|
||||||
|
} catch( WebException ex ) {
|
||||||
|
Servers = new List<ServerListEntry>();
|
||||||
|
LoginEnd( false );
|
||||||
|
DisplayWebException( ex, "retrieve servers list", SetStatus );
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
SetStatus( 100, "Done" );
|
||||||
|
LoginEnd( true );
|
||||||
|
}
|
||||||
|
|
||||||
|
public void LoginEnd( bool success ) {
|
||||||
|
if( form.InvokeRequired ) {
|
||||||
|
form.Invoke( (Action<bool>)LoginEnd, success );
|
||||||
|
} else {
|
||||||
|
GC.Collect();
|
||||||
|
if( success ) {
|
||||||
|
Tab.TabPages.Add( ServersTab );
|
||||||
|
FilterList();
|
||||||
|
}
|
||||||
|
SignInButton.Enabled = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void SetStatus( int percentage, string text ) {
|
||||||
|
if( form.InvokeRequired ) {
|
||||||
|
form.Invoke( (Action<int, string>)SetStatus, percentage, text );
|
||||||
|
} else {
|
||||||
|
Progress.Value = percentage;
|
||||||
|
Status.Text = text;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void ConnectToServer() {
|
||||||
|
GameStartData data = null;
|
||||||
|
try {
|
||||||
|
data = Session.GetConnectInfo( Hash.Text );
|
||||||
|
} catch( WebException ex ) {
|
||||||
|
DisplayWebException( ex, "retrieve server info",
|
||||||
|
(p, text) => MessageBox.Show( text ) );
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
MainForm.StartClient( data, true );
|
||||||
|
}
|
||||||
|
|
||||||
|
public void FilterList() {
|
||||||
|
ServersTable.Items.Clear();
|
||||||
|
if( Servers.Count == 0 ) return;
|
||||||
|
IComparer sorter = ServersTable.ListViewItemSorter;
|
||||||
|
ServersTable.ListViewItemSorter = null;
|
||||||
|
|
||||||
|
for( int i = 0; i < Servers.Count; i++ ) {
|
||||||
|
ServerListEntry entry = Servers[i];
|
||||||
|
if( Filter( entry ) ) {
|
||||||
|
string[] row = { entry.Name, entry.Players, entry.MaximumPlayers, entry.Uptime, entry.Hash };
|
||||||
|
ServersTable.Items.Add( new ListViewItem( row ) );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if( sorter != null ) {
|
||||||
|
ServersTable.ListViewItemSorter = sorter;
|
||||||
|
ServersTable.Sort();
|
||||||
|
}
|
||||||
|
ServersTable.EndUpdate();
|
||||||
|
}
|
||||||
|
|
||||||
|
public void HashChanged() {
|
||||||
|
string hash = Hash.Text;
|
||||||
|
ListView.SelectedIndexCollection selected = ServersTable.SelectedIndices;
|
||||||
|
if( selected.Count > 0 ) {
|
||||||
|
ServersTable.Items[selected[0]].Selected = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
int count = ServersTable.Items.Count;
|
||||||
|
for( int i = 0; i < count; i++ ) {
|
||||||
|
ListViewItem entry = ServersTable.Items[i];
|
||||||
|
if( hash == entry.SubItems[4].Text ) {
|
||||||
|
entry.Selected = true;
|
||||||
|
ServersTable.EnsureVisible( i );
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void ServerTableClick() {
|
||||||
|
Point mousePos = ServersTable.PointToClient( MainForm.MousePosition );
|
||||||
|
ListViewHitTestInfo hitTest = ServersTable.HitTest( mousePos );
|
||||||
|
if( hitTest != null && hitTest.Item != null ) {
|
||||||
|
Hash.Text = hitTest.Item.SubItems[4].Text;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void DisplayWebException( WebException ex, string action, Action<int, string> target ) {
|
||||||
|
string host = HostServer;
|
||||||
|
if( ex.Status == WebExceptionStatus.Timeout ) {
|
||||||
|
string text = "Failed to " + action + ":" +
|
||||||
|
Environment.NewLine + "Timed out while connecting to " + host + ", it may be down.";
|
||||||
|
target( 0, text );
|
||||||
|
} else if( ex.Status == WebExceptionStatus.ProtocolError ) {
|
||||||
|
HttpWebResponse response = (HttpWebResponse)ex.Response;
|
||||||
|
int errorCode = (int)response.StatusCode;
|
||||||
|
string description = response.StatusDescription;
|
||||||
|
string text = "Failed to " + action + ":" +
|
||||||
|
Environment.NewLine + host + " returned: (" + errorCode + ") " + description;
|
||||||
|
target( 0, text );
|
||||||
|
} else if( ex.Status == WebExceptionStatus.NameResolutionFailure ) {
|
||||||
|
string text = "Failed to " + action + ":" +
|
||||||
|
Environment.NewLine + "Unable to resolve " + host + ", you may not be connected to the internet.";
|
||||||
|
target( 0, text );
|
||||||
|
} else {
|
||||||
|
string text = "Failed to " + action + ":" + Environment.NewLine + ex.Status;
|
||||||
|
target( 0, text );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -1,13 +1,10 @@
|
|||||||
using System;
|
using System;
|
||||||
using System.Collections;
|
using System.ComponentModel;
|
||||||
using System.Collections.Generic;
|
using System.Diagnostics;
|
||||||
using System.ComponentModel;
|
using System.Drawing;
|
||||||
using System.Diagnostics;
|
using System.Net;
|
||||||
using System.Drawing;
|
using System.Net.Sockets;
|
||||||
using System.Net;
|
using System.Windows.Forms;
|
||||||
using System.Net.Sockets;
|
|
||||||
using System.Threading;
|
|
||||||
using System.Windows.Forms;
|
|
||||||
|
|
||||||
namespace Launcher {
|
namespace Launcher {
|
||||||
|
|
||||||
@ -19,15 +16,32 @@ namespace Launcher {
|
|||||||
InitializeComponent();
|
InitializeComponent();
|
||||||
AdjustTabs();
|
AdjustTabs();
|
||||||
SetTooltips();
|
SetTooltips();
|
||||||
tblMCServers.HandleCreated += tblMCServersHandleCreated;
|
|
||||||
tblCCServers.HandleCreated += tblCCServersHandleCreated;
|
|
||||||
// hide tabs at start
|
// hide tabs at start
|
||||||
tabMC.TabPages.Remove( tabMCServers );
|
tabMC.TabPages.Remove( tabMCServers );
|
||||||
tabMC.TabPages.Remove( tabMCServer );
|
|
||||||
tabCC.TabPages.Remove( tabCCServers );
|
tabCC.TabPages.Remove( tabCCServers );
|
||||||
tabCC.TabPages.Remove( tabCCServer );
|
|
||||||
Shown += DisplayResourcesDialog;
|
Shown += DisplayResourcesDialog;
|
||||||
|
|
||||||
|
mc = new GameState() { Progress = prgMCStatus, Status = lblMCStatus,
|
||||||
|
Username = txtMCUser, Password = txtMCPassword, HostServer = "minecraft.net",
|
||||||
|
Session = new MinecraftSession(), SignInButton = btnMCSignIn, Tab = tabMC,
|
||||||
|
ServersTab = tabMCServers, ServersTable = tblMCServers, Hash = txtMCHash,
|
||||||
|
form = this };
|
||||||
|
cc = new GameState() { Progress = prgCCStatus, Status = lblCCStatus,
|
||||||
|
Username = txtCCUser, Password = txtCCPassword, HostServer = "classicube.net",
|
||||||
|
Session = new ClassicubeSession(), SignInButton = btnCCSignIn, Tab = tabCC,
|
||||||
|
ServersTab = tabCCServers, ServersTable = tblCCServers, Hash = txtCCHash,
|
||||||
|
form = this };
|
||||||
|
|
||||||
|
mc.Filter = e =>
|
||||||
|
// NOTE: using ToLower().Contains() allocates too many unecessary strings.
|
||||||
|
e.Name.IndexOf( txtMCSearch.Text, StringComparison.OrdinalIgnoreCase ) >= 0
|
||||||
|
&& ( cbMCHideEmpty.Checked ? e.Players[0] != '0' : true )
|
||||||
|
&& ( cbMCHideInvalid.Checked ? Int32.Parse( e.Players ) < 600 : true );
|
||||||
|
cc.Filter = e =>
|
||||||
|
e.Name.IndexOf( txtCCSearch.Text, StringComparison.OrdinalIgnoreCase ) >= 0
|
||||||
|
&& ( cbCCHideEmpty.Checked ? e.Players[0] != '0' : true );
|
||||||
}
|
}
|
||||||
|
GameState mc, cc;
|
||||||
|
|
||||||
void DisplayResourcesDialog( object sender, EventArgs e ) {
|
void DisplayResourcesDialog( object sender, EventArgs e ) {
|
||||||
// TODO: async fetching
|
// TODO: async fetching
|
||||||
@ -36,14 +50,12 @@ namespace Launcher {
|
|||||||
DialogResult result = MessageBox.Show(
|
DialogResult result = MessageBox.Show(
|
||||||
"Some required resources weren't found. Would you like to download them now?", "Missing resources",
|
"Some required resources weren't found. Would you like to download them now?", "Missing resources",
|
||||||
MessageBoxButtons.OKCancel );
|
MessageBoxButtons.OKCancel );
|
||||||
if( result == DialogResult.OK ) {
|
if( result == DialogResult.OK ) {
|
||||||
fetcher.Run( this );
|
fetcher.Run( this );
|
||||||
Text = AppName;
|
Text = AppName;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
delegate void Action<T1, T2>( T1 arg1, T2 arg2 );
|
|
||||||
|
|
||||||
void SetTooltips() {
|
void SetTooltips() {
|
||||||
toolTip.SetToolTip( lblLanUser, "The username to use when connecting to the local server. " + Environment.NewLine +
|
toolTip.SetToolTip( lblLanUser, "The username to use when connecting to the local server. " + Environment.NewLine +
|
||||||
@ -64,82 +76,21 @@ namespace Launcher {
|
|||||||
void AdjustTabs() {
|
void AdjustTabs() {
|
||||||
tabs.Width = ClientSize.Width + 6;
|
tabs.Width = ClientSize.Width + 6;
|
||||||
tabs.Height = ClientSize.Height + 3;
|
tabs.Height = ClientSize.Height + 3;
|
||||||
tabMC.Width = tabCC.Width = tabs.SelectedTab.Size.Width + 10;
|
tabMC.Width = tabCC.Width = tabs.Width;
|
||||||
tabMC.Height = tabCC.Height = tabs.SelectedTab.Size.Height + 10;
|
tabMC.Height = tabCC.Height = tabs.SelectedTab.Size.Height + 10;
|
||||||
|
|
||||||
if( tblMCServers.IsHandleCreated ) {
|
if( tblMCServers.IsHandleCreated ) {
|
||||||
AdjustTablePos( tblMCServers );
|
AdjustTablePos( tblMCServers, btnMCConnect );
|
||||||
}
|
}
|
||||||
if( tblCCServers.IsHandleCreated ) {
|
if( tblCCServers.IsHandleCreated ) {
|
||||||
AdjustTablePos( tblCCServers );
|
AdjustTablePos( tblCCServers, btnCCConnect );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void tblMCServersHandleCreated( object sender, EventArgs e ) {
|
void AdjustTablePos( Control control, Control connectButton ) {
|
||||||
AdjustTablePos( tblMCServers );
|
|
||||||
}
|
|
||||||
|
|
||||||
void tblCCServersHandleCreated( object sender, EventArgs e ) {
|
|
||||||
AdjustTablePos( tblCCServers );
|
|
||||||
}
|
|
||||||
|
|
||||||
void AdjustTablePos( Control control ) {
|
|
||||||
Point formLoc = PointToClient( control.Parent.PointToScreen( control.Location ) );
|
Point formLoc = PointToClient( control.Parent.PointToScreen( control.Location ) );
|
||||||
control.Width = ClientSize.Width - formLoc.X;
|
control.Width = ClientSize.Width - formLoc.X;
|
||||||
control.Height = ClientSize.Height - formLoc.Y;
|
control.Height = ClientSize.Height - formLoc.Y - connectButton.Height - 5;
|
||||||
}
|
|
||||||
|
|
||||||
static string missingExeMessage = "Failed to start ClassicalSharp. (classicalsharp.exe was not found)"
|
|
||||||
+ Environment.NewLine + Environment.NewLine +
|
|
||||||
"This application is only the launcher, it is not the actual client. " +
|
|
||||||
"Please place the launcher in the same directory as the client (classicalsharp.exe).";
|
|
||||||
|
|
||||||
static void StartClient( GameStartData data, bool classicubeSkins ) {
|
|
||||||
string skinServer = classicubeSkins ? "http://www.classicube.net/static/skins/" : "http://s3.amazonaws.com/MinecraftSkins/";
|
|
||||||
string args = data.Username + " " + data.Mppass + " " +
|
|
||||||
data.Ip + " " + data.Port + " " + skinServer;
|
|
||||||
Log( "starting..." + args );
|
|
||||||
Process process = null;
|
|
||||||
try {
|
|
||||||
process = Process.Start( "classicalsharp.exe", args );
|
|
||||||
} catch( Win32Exception ex ) {
|
|
||||||
if( ex.Message.Contains( "The system cannot find the file specified" ) ) {
|
|
||||||
MessageBox.Show( missingExeMessage );
|
|
||||||
} else {
|
|
||||||
throw;
|
|
||||||
}
|
|
||||||
} finally {
|
|
||||||
if( process != null ) {
|
|
||||||
process.Dispose();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static void Log( string text ) {
|
|
||||||
System.Diagnostics.Debug.WriteLine( text );
|
|
||||||
}
|
|
||||||
|
|
||||||
static void DisplayWebException( WebException ex, string action, string host, Action<int, string> target ) {
|
|
||||||
if( ex.Status == WebExceptionStatus.Timeout ) {
|
|
||||||
string text = "Failed to " + action + ":" +
|
|
||||||
Environment.NewLine + "Timed out while connecting to " + host + ", it may be down.";
|
|
||||||
target( 0, text );
|
|
||||||
} else if( ex.Status == WebExceptionStatus.ProtocolError ) {
|
|
||||||
HttpWebResponse response = (HttpWebResponse)ex.Response;
|
|
||||||
int errorCode = (int)response.StatusCode;
|
|
||||||
string description = response.StatusDescription;
|
|
||||||
string text = "Failed to " + action + ":" +
|
|
||||||
Environment.NewLine + host + " returned: (" + errorCode + ") " + description;
|
|
||||||
target( 0, text );
|
|
||||||
} else if( ex.Status == WebExceptionStatus.NameResolutionFailure ) {
|
|
||||||
string text = "Failed to " + action + ":" +
|
|
||||||
Environment.NewLine + "Unable to resolve " + host + ", you may not be connected to the internet.";
|
|
||||||
target( 0, text );
|
|
||||||
} else {
|
|
||||||
string text = "Failed to " + action + ":" +
|
|
||||||
Environment.NewLine + ex.Status;
|
|
||||||
target( 0, text );
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#region Local tab
|
#region Local tab
|
||||||
@ -186,12 +137,6 @@ namespace Launcher {
|
|||||||
|
|
||||||
#endregion
|
#endregion
|
||||||
|
|
||||||
|
|
||||||
#region minecraft.net tab
|
|
||||||
|
|
||||||
MinecraftSession mcSession = new MinecraftSession();
|
|
||||||
List<ServerListEntry> mcServers = new List<ServerListEntry>();
|
|
||||||
|
|
||||||
NameComparer mcNameComparer = new NameComparer( 0 );
|
NameComparer mcNameComparer = new NameComparer( 0 );
|
||||||
NumericalComparer mcPlayersComparer = new NumericalComparer( 1 );
|
NumericalComparer mcPlayersComparer = new NumericalComparer( 1 );
|
||||||
NumericalComparer mcMaxPlayersComparer = new NumericalComparer( 2 );
|
NumericalComparer mcMaxPlayersComparer = new NumericalComparer( 2 );
|
||||||
@ -213,165 +158,21 @@ namespace Launcher {
|
|||||||
tblMCServers.Sort();
|
tblMCServers.Sort();
|
||||||
}
|
}
|
||||||
|
|
||||||
void McFilterList() {
|
void txtMCSearchTextChanged( object sender, EventArgs e ) { mc.FilterList(); }
|
||||||
tblMCServers.Items.Clear();
|
|
||||||
if( mcServers.Count == 0 ) return;
|
|
||||||
IComparer sorter = tblMCServers.ListViewItemSorter;
|
|
||||||
tblMCServers.ListViewItemSorter = null;
|
|
||||||
|
|
||||||
tblMCServers.BeginUpdate();
|
|
||||||
Predicate<ServerListEntry> filter = e =>
|
|
||||||
// NOTE: using ToLower().Contains() allocates too many unecessary strings.
|
|
||||||
e.Name.IndexOf( txtMCSearch.Text, StringComparison.OrdinalIgnoreCase ) >= 0
|
|
||||||
&& ( cbMCHideEmpty.Checked ? e.Players[0] != '0' : true )
|
|
||||||
&& ( cbMCHideInvalid.Checked ? Int32.Parse( e.Players ) < 600 : true );
|
|
||||||
|
|
||||||
for( int i = 0; i < mcServers.Count; i++ ) {
|
|
||||||
ServerListEntry entry = mcServers[i];
|
|
||||||
if( filter( entry ) ) {
|
|
||||||
string[] row = { entry.Name, entry.Players, entry.MaximumPlayers, entry.Uptime, entry.Hash };
|
|
||||||
tblMCServers.Items.Add( new ListViewItem( row ) );
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if( sorter != null ) {
|
|
||||||
tblMCServers.ListViewItemSorter = sorter;
|
|
||||||
tblMCServers.Sort();
|
|
||||||
}
|
|
||||||
tblMCServers.EndUpdate();
|
|
||||||
}
|
|
||||||
|
|
||||||
void txtMCSearchTextChanged( object sender, EventArgs e ) {
|
void cbMCHideEmptyCheckedChanged( object sender, EventArgs e ) { mc.FilterList(); }
|
||||||
McFilterList();
|
|
||||||
}
|
|
||||||
|
|
||||||
void cbMCHideEmptyCheckedChanged( object sender, EventArgs e ) {
|
void cbMCHideInvalidCheckedChanged(object sender, EventArgs e ) { mc.FilterList(); }
|
||||||
McFilterList();
|
|
||||||
}
|
|
||||||
|
|
||||||
void cbMCHideInvalidCheckedChanged(object sender, EventArgs e ) {
|
void tblMCServersClick( object sender, EventArgs e ) { mc.ServerTableClick(); }
|
||||||
McFilterList();
|
|
||||||
}
|
|
||||||
|
|
||||||
void tblMCServersDoubleClick( object sender, EventArgs e ) {
|
void txtMCHashTextChanged( object sender, EventArgs e ) { mc.HashChanged(); }
|
||||||
Point mousePos = tblMCServers.PointToClient( MousePosition );
|
|
||||||
ListViewHitTestInfo hitTest = tblMCServers.HitTest( mousePos );
|
|
||||||
if( hitTest != null && hitTest.Item != null ) {
|
|
||||||
txtMCHash.Text = hitTest.Item.SubItems[4].Text;
|
|
||||||
tabMC.SelectedIndex = 2;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void txtMCHashTextChanged( object sender, EventArgs e ) {
|
void btnMCConnectClick( object sender, EventArgs e ) { mc.ConnectToServer(); }
|
||||||
string hash = txtMCHash.Text;
|
|
||||||
lblMCPublicName.Text = "No public name";
|
|
||||||
for( int i = 0; i < mcServers.Count; i++ ) {
|
|
||||||
ServerListEntry entry = mcServers[i];
|
|
||||||
if( hash == entry.Hash ) {
|
|
||||||
lblMCPublicName.Text = entry.Name;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void btnMCConnectClick( object sender, EventArgs e ) {
|
void btnMCSignInClick( object sender, EventArgs e ) { mc.DoSignIn(); }
|
||||||
GameStartData data = null;
|
|
||||||
try {
|
|
||||||
data = mcSession.GetConnectInfo( txtMCHash.Text );
|
|
||||||
} catch( WebException ex ) {
|
|
||||||
DisplayWebException( ex, "retrieve server info", "minecraft.net",
|
|
||||||
(p, text) => MessageBox.Show( text ) );
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
StartClient( data, false );
|
|
||||||
}
|
|
||||||
|
|
||||||
void btnMCSignInClick( object sender, EventArgs e ) {
|
|
||||||
if( String.IsNullOrEmpty( txtMCUser.Text ) ) {
|
|
||||||
MessageBox.Show( "Please enter a username." );
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
if( String.IsNullOrEmpty( txtMCPassword.Text ) ) {
|
|
||||||
MessageBox.Show( "Please enter a password." );
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if( mcSession.Username != null ) {
|
|
||||||
mcSession.ResetSession();
|
|
||||||
tblMCServers.Items.Clear();
|
|
||||||
mcServers.Clear();
|
|
||||||
}
|
|
||||||
btnMCSignIn.Enabled = false;
|
|
||||||
tabMC.TabPages.Remove( tabMCServers );
|
|
||||||
tabMC.TabPages.Remove( tabMCServer );
|
|
||||||
mcLoginThread = new Thread( McLoginAsync );
|
|
||||||
mcLoginThread.Name = "Launcher.McLoginAsync";
|
|
||||||
mcLoginThread.IsBackground = true;
|
|
||||||
mcLoginThread.Start();
|
|
||||||
}
|
|
||||||
|
|
||||||
Thread mcLoginThread;
|
|
||||||
void McLoginAsync() {
|
|
||||||
SetMcStatus( 0, "Signing in.." );
|
|
||||||
try {
|
|
||||||
mcSession.Login( txtMCUser.Text, txtMCPassword.Text );
|
|
||||||
} catch( WebException ex ) {
|
|
||||||
mcSession.Username = null;
|
|
||||||
McLoginEnd( false );
|
|
||||||
DisplayWebException( ex, "sign in", "minecraft.net", SetMcStatus );
|
|
||||||
return;
|
|
||||||
} catch( InvalidOperationException ex ) {
|
|
||||||
SetMcStatus( 0, "Failed to sign in" );
|
|
||||||
mcSession.Username = null;
|
|
||||||
McLoginEnd( false );
|
|
||||||
string text = "Failed to sign in: " + Environment.NewLine + ex.Message;
|
|
||||||
SetMcStatus( 0, text );
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
SetMcStatus( 50, "Retrieving public servers list.." );
|
|
||||||
try {
|
|
||||||
mcServers = mcSession.GetPublicServers();
|
|
||||||
} catch( WebException ex ) {
|
|
||||||
mcServers = new List<ServerListEntry>();
|
|
||||||
McLoginEnd( false );
|
|
||||||
DisplayWebException( ex, "retrieve servers list", "minecraft.net", SetMcStatus );
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
SetMcStatus( 100, "Done" );
|
|
||||||
McLoginEnd( true );
|
|
||||||
}
|
|
||||||
|
|
||||||
void McLoginEnd( bool success ) {
|
|
||||||
if( InvokeRequired ) {
|
|
||||||
Invoke( (Action<bool>)McLoginEnd, success );
|
|
||||||
} else {
|
|
||||||
GC.Collect();
|
|
||||||
if( success ) {
|
|
||||||
tabMC.TabPages.Add( tabMCServers );
|
|
||||||
tabMC.TabPages.Add( tabMCServer );
|
|
||||||
McFilterList();
|
|
||||||
}
|
|
||||||
btnMCSignIn.Enabled = true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void SetMcStatus( int percentage, string text ) {
|
|
||||||
if( InvokeRequired ) {
|
|
||||||
Invoke( (Action<int, string>)SetMcStatus, percentage, text );
|
|
||||||
} else {
|
|
||||||
prgMCStatus.Value = percentage;
|
|
||||||
lblMCStatus.Text = text;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#endregion
|
|
||||||
|
|
||||||
|
|
||||||
#region classicube.net tab
|
|
||||||
|
|
||||||
ClassicubeSession ccSession = new ClassicubeSession();
|
|
||||||
List<ServerListEntry> ccServers = new List<ServerListEntry>();
|
|
||||||
|
|
||||||
NameComparer ccNameComparer = new NameComparer( 0 );
|
NameComparer ccNameComparer = new NameComparer( 0 );
|
||||||
NumericalComparer ccPlayersComparer = new NumericalComparer( 1 );
|
NumericalComparer ccPlayersComparer = new NumericalComparer( 1 );
|
||||||
NumericalComparer ccMaxPlayersComparer = new NumericalComparer( 2 );
|
NumericalComparer ccMaxPlayersComparer = new NumericalComparer( 2 );
|
||||||
@ -391,151 +192,40 @@ namespace Launcher {
|
|||||||
tblCCServers.Sort();
|
tblCCServers.Sort();
|
||||||
}
|
}
|
||||||
|
|
||||||
void CcFilterList() {
|
void txtCCSearchTextChanged( object sender, EventArgs e ) { cc.FilterList(); }
|
||||||
tblCCServers.Items.Clear();
|
|
||||||
if( ccServers.Count == 0 ) return;
|
|
||||||
IComparer sorter = tblCCServers.ListViewItemSorter;
|
|
||||||
tblCCServers.ListViewItemSorter = null;
|
|
||||||
|
|
||||||
tblCCServers.BeginUpdate();
|
|
||||||
Predicate<ServerListEntry> filter = e =>
|
|
||||||
e.Name.IndexOf( txtCCSearch.Text, StringComparison.OrdinalIgnoreCase ) >= 0
|
|
||||||
&& ( cbCCHideEmpty.Checked ? e.Players[0] != '0' : true );
|
|
||||||
|
|
||||||
for( int i = 0; i < ccServers.Count; i++ ) {
|
|
||||||
ServerListEntry entry = ccServers[i];
|
|
||||||
if( filter( entry ) ) {
|
|
||||||
string[] row = { entry.Name, entry.Players, entry.MaximumPlayers, entry.Uptime, entry.Hash };
|
|
||||||
tblCCServers.Items.Add( new ListViewItem( row ) );
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if( sorter != null ) {
|
|
||||||
tblCCServers.ListViewItemSorter = sorter;
|
|
||||||
tblCCServers.Sort();
|
|
||||||
}
|
|
||||||
tblCCServers.EndUpdate();
|
|
||||||
}
|
|
||||||
|
|
||||||
void txtCCSearchTextChanged( object sender, EventArgs e ) {
|
void cbCCHideEmptyCheckedChanged( object sender, EventArgs e ) { cc.FilterList(); }
|
||||||
CcFilterList();
|
|
||||||
}
|
|
||||||
|
|
||||||
void cbCCHideEmptyCheckedChanged( object sender, EventArgs e ) {
|
void tblCCServersClick( object sender, EventArgs e ) { cc.ServerTableClick(); }
|
||||||
CcFilterList();
|
|
||||||
}
|
|
||||||
|
|
||||||
void tblCCServersDoubleClick( object sender, EventArgs e ) {
|
void txtCCHashTextChanged( object sender, EventArgs e ) { cc.HashChanged(); }
|
||||||
Point mousePos = tblCCServers.PointToClient( MousePosition );
|
|
||||||
ListViewHitTestInfo hitTest = tblCCServers.HitTest( mousePos );
|
|
||||||
if( hitTest != null && hitTest.Item != null ) {
|
|
||||||
txtCCHash.Text = hitTest.Item.SubItems[4].Text;
|
|
||||||
tabCC.SelectedIndex = 2;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void txtCCHashTextChanged( object sender, EventArgs e ) {
|
void btnCCConnectClick( object sender, EventArgs e ) { cc.ConnectToServer(); }
|
||||||
string hash = txtCCHash.Text;
|
|
||||||
lblCCPublicName.Text = "No public name";
|
|
||||||
for( int i = 0; i < ccServers.Count; i++ ) {
|
|
||||||
ServerListEntry entry = ccServers[i];
|
|
||||||
if( hash == entry.Hash ) {
|
|
||||||
lblCCPublicName.Text = entry.Name;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void btnCCConnectClick( object sender, EventArgs e ) {
|
void btnCCSignInClick( object sender, EventArgs e ) { cc.DoSignIn(); }
|
||||||
GameStartData data = null;
|
|
||||||
try {
|
|
||||||
data = ccSession.GetConnectInfo( txtCCHash.Text );
|
static string missingExeMessage = "Failed to start ClassicalSharp. (classicalsharp.exe was not found)"
|
||||||
} catch( WebException ex ) {
|
+ Environment.NewLine + Environment.NewLine +
|
||||||
DisplayWebException( ex, "retrieve server info", "classicube.net",
|
"This application is only the launcher, it is not the actual client. " +
|
||||||
(p, text) => MessageBox.Show( text ) );
|
"Please place the launcher in the same directory as the client (classicalsharp.exe).";
|
||||||
return;
|
|
||||||
}
|
internal static void StartClient( GameStartData data, bool classicubeSkins ) {
|
||||||
StartClient( data, true );
|
string skinServer = classicubeSkins ? "http://www.classicube.net/static/skins/" : "http://s3.amazonaws.com/MinecraftSkins/";
|
||||||
}
|
string args = data.Username + " " + data.Mppass + " " +
|
||||||
|
data.Ip + " " + data.Port + " " + skinServer;
|
||||||
void btnCCSignInClick( object sender, EventArgs e ) {
|
System.Diagnostics.Debug.WriteLine( "starting..." + args );
|
||||||
if( String.IsNullOrEmpty( txtCCUser.Text ) ) {
|
Process process = null;
|
||||||
MessageBox.Show( "Please enter a username." );
|
|
||||||
return;
|
try {
|
||||||
}
|
process = Process.Start( "classicalsharp.exe", args );
|
||||||
if( String.IsNullOrEmpty( txtCCPassword.Text ) ) {
|
} catch( Win32Exception ex ) {
|
||||||
MessageBox.Show( "Please enter a password." );
|
if( ex.Message.Contains( "The system cannot find the file specified" ) ) {
|
||||||
return;
|
MessageBox.Show( missingExeMessage );
|
||||||
}
|
} else {
|
||||||
|
throw;
|
||||||
if( ccSession.Username != null ) {
|
}
|
||||||
ccSession.ResetSession();
|
}
|
||||||
tblCCServers.Items.Clear();
|
}
|
||||||
ccServers.Clear();
|
|
||||||
}
|
|
||||||
btnCCSignIn.Enabled = false;
|
|
||||||
tabCC.TabPages.Remove( tabCCServers );
|
|
||||||
tabCC.TabPages.Remove( tabCCServer );
|
|
||||||
ccLoginThread = new Thread( CcLoginAsync );
|
|
||||||
ccLoginThread.Name = "Launcher.CcLoginAsync";
|
|
||||||
ccLoginThread.IsBackground = true;
|
|
||||||
ccLoginThread.Start();
|
|
||||||
}
|
|
||||||
|
|
||||||
Thread ccLoginThread;
|
|
||||||
void CcLoginAsync() {
|
|
||||||
SetCcStatus( 0, "Signing in.." );
|
|
||||||
try {
|
|
||||||
ccSession.Login( txtCCUser.Text, txtCCPassword.Text );
|
|
||||||
} catch( WebException ex ) {
|
|
||||||
ccSession.Username = null;
|
|
||||||
CcLoginEnd( false );
|
|
||||||
DisplayWebException( ex, "sign in", "classicube.net", SetCcStatus );
|
|
||||||
return;
|
|
||||||
} catch( InvalidOperationException ex ) {
|
|
||||||
SetCcStatus( 0, "Failed to sign in" );
|
|
||||||
ccSession.Username = null;
|
|
||||||
CcLoginEnd( false );
|
|
||||||
string text = "Failed to sign in: " + Environment.NewLine + ex.Message;
|
|
||||||
SetCcStatus( 0, text );
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
SetCcStatus( 50, "Retrieving public servers list.." );
|
|
||||||
try {
|
|
||||||
ccServers = ccSession.GetPublicServers();
|
|
||||||
} catch( WebException ex ) {
|
|
||||||
ccServers = new List<ServerListEntry>();
|
|
||||||
CcLoginEnd( false );
|
|
||||||
DisplayWebException( ex, "retrieve servers list", "classicube.net", SetCcStatus );
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
SetCcStatus( 100, "Done" );
|
|
||||||
CcLoginEnd( true );
|
|
||||||
}
|
|
||||||
|
|
||||||
void CcLoginEnd( bool success ) {
|
|
||||||
if( InvokeRequired ) {
|
|
||||||
Invoke( (Action<bool>)CcLoginEnd, success );
|
|
||||||
} else {
|
|
||||||
GC.Collect();
|
|
||||||
if( success ) {
|
|
||||||
tabCC.TabPages.Add( tabCCServers );
|
|
||||||
tabCC.TabPages.Add( tabCCServer );
|
|
||||||
CcFilterList();
|
|
||||||
}
|
|
||||||
btnCCSignIn.Enabled = true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void SetCcStatus( int percentage, string text ) {
|
|
||||||
if( InvokeRequired ) {
|
|
||||||
Invoke( (Action<int, string>)SetCcStatus, percentage, text );
|
|
||||||
} else {
|
|
||||||
prgCCStatus.Value = percentage;
|
|
||||||
lblCCStatus.Text = text;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#endregion
|
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -117,8 +117,7 @@
|
|||||||
<resheader name="writer">
|
<resheader name="writer">
|
||||||
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
||||||
</resheader>
|
</resheader>
|
||||||
<assembly alias="System.Drawing" name="System.Drawing, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a" />
|
<metadata name="toolTip.TrayLocation" type="System.Drawing.Point, System.Drawing, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a">
|
||||||
<data name="toolTip.TrayLocation" type="System.Drawing.Point, System.Drawing">
|
|
||||||
<value>17, 17</value>
|
<value>17, 17</value>
|
||||||
</data>
|
</metadata>
|
||||||
</root>
|
</root>
|
@ -1,6 +1,6 @@
|
|||||||
* Note that the first time you run the launcher, a dialog box will pop up with the message
|
* Note that the first time you run the launcher, a dialog box will pop up with the message
|
||||||
"Some required resources weren't found." Just click OK. (This is because I cannot redistribute
|
"Some required resources weren't found." Just click OK. (This is because I cannot redistribute
|
||||||
the assets of Mine craft Classic with the application as they are the copyrighted property of Mojang)
|
the assets of MineCraft Classic with the application as they are the copyrighted property of Mojang)
|
||||||
|
|
||||||
The launcher is divided into 3 tabs. They are:
|
The launcher is divided into 3 tabs. They are:
|
||||||
1) Local tab
|
1) Local tab
|
||||||
@ -11,18 +11,18 @@ custom skins if you are not connected to the internet, however)
|
|||||||
|
|
||||||
Click "connect" to start the client.
|
Click "connect" to start the client.
|
||||||
|
|
||||||
2) Mine craft.net
|
2) MineCraft.net
|
||||||
### Note: Mojang appears to have deleted all of the unpaid free accounts. Premium accounts should still
|
# Note: Mojang appears to have deleted all of the unpaid free accounts. Premium accounts should still
|
||||||
### work though. The public servers list on minecraft.net is also completely stuffed. There are servers
|
# work though. The public servers list on minecraft.net is also completely stuffed, as most servers
|
||||||
### that appear on the list that are either fake, or don't actually exist anymore.
|
# that appear on the list that are either fake or don't actually exist anymore.
|
||||||
### You are probably better off just using ClassiCube.net.
|
# You are probably better off just using ClassiCube.net.
|
||||||
|
|
||||||
You will need to provide the username and password for your minecraft.net account. Then click sign in.
|
You will need to provide the username and password for your minecraft.net account. Then click sign in.
|
||||||
|
|
||||||
If sign-in was successful, two new tabs should appear beside 'Sign in'.
|
If sign-in was successful, two new tabs should appear beside 'Sign in'.
|
||||||
You can then either:
|
You can then either:
|
||||||
A) Browse the public servers list and double-click on a server (Which will then take you to the 'minecraft.net server' tab with the hash filled in for you)
|
A) Browse the public servers list and click on a cell (Which will then fill in the hash textbox)
|
||||||
B) Directly enter in a hash in the 'minecraft.net server' tab.
|
B) Directly enter in a hash into the hash textbox.
|
||||||
|
|
||||||
Then click "connect". The launcher will then download the necessary information about the server from minecraft.net and start the client.
|
Then click "connect". The launcher will then download the necessary information about the server from minecraft.net and start the client.
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user