mirror of
https://github.com/ClassiCube/ClassiCube.git
synced 2025-09-16 02:56:09 -04:00
Cleanup WeatherRenderer somewhat, add (non-working) update screen to new launcher.
This commit is contained in:
parent
120c630c51
commit
d1818f6e23
@ -15,13 +15,15 @@ namespace ClassicalSharp {
|
||||
map = game.Map;
|
||||
graphics = game.Graphics;
|
||||
info = game.BlockInfo;
|
||||
weatherVb = graphics.CreateDynamicVb( VertexFormat.Pos3fTex2fCol4b, 12 * 9 * 9 );
|
||||
weatherVb = graphics.CreateDynamicVb( VertexFormat.Pos3fTex2fCol4b, vertices.Length );
|
||||
}
|
||||
|
||||
int weatherVb;
|
||||
short[] heightmap;
|
||||
float vOffset;
|
||||
VertexPos3fTex2fCol4b[] vertices = new VertexPos3fTex2fCol4b[8 * 9 * 9];
|
||||
const int extent = 4;
|
||||
VertexPos3fTex2fCol4b[] vertices = new VertexPos3fTex2fCol4b[8 * (extent * 2 + 1) * (extent * 2 + 1)];
|
||||
|
||||
public void Render( double deltaTime ) {
|
||||
Weather weather = map.Weather;
|
||||
if( weather == Weather.Sunny ) return;
|
||||
@ -36,8 +38,8 @@ namespace ClassicalSharp {
|
||||
graphics.AlphaBlending = true;
|
||||
graphics.DepthWrite = false;
|
||||
FastColour col = FastColour.White;
|
||||
for( int dx = -4; dx <= 4; dx++ ) {
|
||||
for( int dz = -4; dz <= 4; dz++ ) {
|
||||
for( int dx = -extent; dx <= extent; dx++ ) {
|
||||
for( int dz = -extent; dz <= extent; dz++ ) {
|
||||
int rainY = Math.Max( pos.Y, GetRainHeight( pos.X + dx, pos.Z + dz ) + 1 );
|
||||
int height = Math.Min( 6 - ( rainY - pos.Y ), 6 );
|
||||
if( height <= 0 ) continue;
|
||||
@ -46,6 +48,7 @@ namespace ClassicalSharp {
|
||||
MakeRainForSquare( pos.X + dx, rainY, height, pos.Z + dz, col, ref index );
|
||||
}
|
||||
}
|
||||
|
||||
// fixes crashing on nVidia cards in OpenGL builds.
|
||||
if( index > 0 ) {
|
||||
graphics.BeginVbBatch( VertexFormat.Pos3fTex2fCol4b );
|
||||
|
@ -87,8 +87,8 @@ namespace Launcher2 {
|
||||
|
||||
void Draw() {
|
||||
widgetIndex = 0;
|
||||
MakeTextAt( "Username", titleFont, -180, -100 );
|
||||
MakeTextAt( "Password", titleFont, -180, -50 );
|
||||
MakeLabelAt( "Username", titleFont, Anchor.Centre, Anchor.Centre, -180, -100 );
|
||||
MakeLabelAt( "Password", titleFont, Anchor.Centre, Anchor.Centre, -180, -50 );
|
||||
|
||||
MakeInput( Get(), 300, Anchor.Centre, false, 30, -100, 32 );
|
||||
MakeInput( Get(), 300, Anchor.Centre, true, 30, -50, 32 );
|
||||
@ -97,8 +97,8 @@ namespace Launcher2 {
|
||||
-75, 0, StartClient );
|
||||
MakeButtonAt( "Back", 80, 35, titleFont, Anchor.Centre,
|
||||
140, 0, (x, y) => game.SetScreen( new MainScreen( game ) ) );
|
||||
string text = widgets[6] == null ? "" : ((LauncherLabelWidget)widgets[6]).Text;
|
||||
MakeTextAt( text, inputFont, 0, 50 );
|
||||
string text = widgets[6] == null ? "" : widgets[6].Text;
|
||||
MakeLabelAt( text, inputFont, Anchor.Centre, Anchor.Centre, 0, 50 );
|
||||
|
||||
if( HasServers && !signingIn )
|
||||
MakeButtonAt( "Servers", 90, 35, titleFont, Anchor.Centre,
|
||||
@ -118,12 +118,6 @@ namespace Launcher2 {
|
||||
}
|
||||
}
|
||||
|
||||
void MakeTextAt( string text, Font font, int x, int y ) {
|
||||
LauncherLabelWidget widget = new LauncherLabelWidget( game, text );
|
||||
widget.DrawAt( drawer, text, font, Anchor.Centre, Anchor.Centre, x, y );
|
||||
widgets[widgetIndex++] = widget;
|
||||
}
|
||||
|
||||
bool HasServers {
|
||||
get {
|
||||
return !(game.Session.Servers == null || game.Session.Servers.Count == 0 );
|
||||
|
@ -69,10 +69,10 @@ namespace Launcher2 {
|
||||
void Draw() {
|
||||
widgetIndex = 0;
|
||||
|
||||
MakeTextAt( titleFont, "Search", -200, 10 );
|
||||
MakeLabelAt( "Search", titleFont, Anchor.Centre, Anchor.Centre, -200, 10 );
|
||||
MakeInput( Get(), 270, Anchor.LeftOrTop, false, -25, 5, 32 );
|
||||
|
||||
MakeTextAt( inputFont, "../play/", -210, 55 );
|
||||
MakeLabelAt( "../play/", inputFont, Anchor.Centre, Anchor.Centre, -210, 55 );
|
||||
MakeInput( Get(), 320, Anchor.LeftOrTop, false, -20, 50, 32 );
|
||||
((LauncherInputWidget)widgets[3]).ClipboardFilter = HashFilter;
|
||||
|
||||
@ -83,12 +83,6 @@ namespace Launcher2 {
|
||||
MakeTableWidget();
|
||||
}
|
||||
|
||||
void MakeTextAt( Font font, string text, int x, int y ) {
|
||||
LauncherLabelWidget widget = new LauncherLabelWidget( game, text );
|
||||
widget.DrawAt( drawer, text, font, Anchor.Centre, Anchor.LeftOrTop, x, y );
|
||||
widgets[widgetIndex++] = widget;
|
||||
}
|
||||
|
||||
void MakeTableWidget() {
|
||||
if( widgets[tableIndex] != null ) {
|
||||
LauncherTableWidget table = (LauncherTableWidget)widgets[tableIndex];
|
||||
|
@ -73,17 +73,18 @@ namespace Launcher2 {
|
||||
|
||||
void Draw() {
|
||||
widgetIndex = 0;
|
||||
MakeTextAt( "Username", -180, -100 );
|
||||
MakeTextAt( "Address", -180, -50 );
|
||||
MakeTextAt( "Mppass", -180, 0 );
|
||||
MakeLabelAt( "Username", titleFont, Anchor.Centre, Anchor.Centre, -180, -100 );
|
||||
MakeLabelAt( "Address", titleFont, Anchor.Centre, Anchor.Centre, -180, -50 );
|
||||
MakeLabelAt( "Mppass", titleFont, Anchor.Centre, Anchor.Centre, -180, 0 );
|
||||
|
||||
MakeInput( Get(), 300, Anchor.Centre, false, 30, -100, 32 );
|
||||
MakeInput( Get(), 300, Anchor.Centre, false, 30, -50, 64 );
|
||||
MakeInput( Get(), 300, Anchor.Centre, false, 30, 0, 32 );
|
||||
|
||||
MakeButtonAt( "Connect", 110, 35, -65, 50, StartClient );
|
||||
MakeButtonAt( "Back", 80, 35, 140, 50, (x, y) => game.SetScreen( new MainScreen( game ) ) );
|
||||
MakeTextAt( "", 0, 100 );
|
||||
MakeButtonAt( "Connect", 110, 35, titleFont, Anchor.Centre, -65, 50, StartClient );
|
||||
MakeButtonAt( "Back", 80, 35, titleFont, Anchor.Centre,
|
||||
140, 50, (x, y) => game.SetScreen( new MainScreen( game ) ) );
|
||||
MakeLabelAt( "", titleFont, Anchor.Centre, Anchor.Centre, 0, 100 );
|
||||
}
|
||||
|
||||
void SetStatus( string text ) {
|
||||
@ -96,23 +97,6 @@ namespace Launcher2 {
|
||||
}
|
||||
}
|
||||
|
||||
void MakeTextAt( string text, int x, int y ) {
|
||||
LauncherLabelWidget widget = new LauncherLabelWidget( game, text );
|
||||
widget.DrawAt( drawer, text, titleFont, Anchor.Centre, Anchor.Centre, x, y );
|
||||
widgets[widgetIndex++] = widget;
|
||||
}
|
||||
|
||||
void MakeButtonAt( string text, int width, int height,
|
||||
int x, int y, Action<int, int> onClick ) {
|
||||
LauncherButtonWidget widget = new LauncherButtonWidget( game );
|
||||
widget.Text = text;
|
||||
widget.OnClick = onClick;
|
||||
|
||||
widget.Active = false;
|
||||
widget.DrawAt( drawer, text, titleFont, Anchor.Centre, Anchor.Centre, width, height, x, y );
|
||||
widgets[widgetIndex++] = widget;
|
||||
}
|
||||
|
||||
void StartClient( int mouseX, int mouseY ) {
|
||||
SetStatus( "" );
|
||||
|
||||
|
@ -14,6 +14,7 @@ namespace Launcher2 {
|
||||
}
|
||||
|
||||
public override void Init() {
|
||||
buttonFont = titleFont;
|
||||
game.Window.Mouse.Move += MouseMove;
|
||||
game.Window.Mouse.ButtonDown += MouseButtonDown;
|
||||
|
||||
@ -84,7 +85,7 @@ namespace Launcher2 {
|
||||
|
||||
protected string Get( int index ) {
|
||||
LauncherWidget widget = widgets[index];
|
||||
return widget == null ? "" : ((LauncherInputWidget)widget).Text;
|
||||
return widget == null ? "" : widget.Text;
|
||||
}
|
||||
|
||||
protected void Set( int index, string text ) {
|
||||
@ -92,24 +93,6 @@ namespace Launcher2 {
|
||||
.Redraw( drawer, text, inputFont );
|
||||
}
|
||||
|
||||
protected override void UnselectWidget( LauncherWidget widget ) {
|
||||
LauncherButtonWidget button = widget as LauncherButtonWidget;
|
||||
if( button != null ) {
|
||||
button.Active = false;
|
||||
button.Redraw( drawer, button.Text, titleFont );
|
||||
Dirty = true;
|
||||
}
|
||||
}
|
||||
|
||||
protected override void SelectWidget( LauncherWidget widget ) {
|
||||
LauncherButtonWidget button = widget as LauncherButtonWidget;
|
||||
if( button != null ) {
|
||||
button.Active = true;
|
||||
button.Redraw( drawer, button.Text, titleFont );
|
||||
Dirty = true;
|
||||
}
|
||||
}
|
||||
|
||||
protected LauncherInputWidget lastInput;
|
||||
protected void InputClick( int mouseX, int mouseY ) {
|
||||
LauncherInputWidget input = (LauncherInputWidget)selectedWidget;
|
||||
|
@ -56,12 +56,26 @@ namespace Launcher2 {
|
||||
selectedWidget = null;
|
||||
}
|
||||
|
||||
protected Font buttonFont;
|
||||
|
||||
/// <summary> Called when the user has moved their mouse away from a previously selected widget. </summary>
|
||||
protected virtual void UnselectWidget( LauncherWidget widget ) {
|
||||
LauncherButtonWidget button = widget as LauncherButtonWidget;
|
||||
if( button != null ) {
|
||||
button.Active = false;
|
||||
button.Redraw( drawer, button.Text, buttonFont );
|
||||
Dirty = true;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary> Called when user has moved their mouse over a given widget. </summary>
|
||||
protected virtual void SelectWidget( LauncherWidget widget ) {
|
||||
LauncherButtonWidget button = widget as LauncherButtonWidget;
|
||||
if( button != null ) {
|
||||
button.Active = true;
|
||||
button.Redraw( drawer, button.Text, buttonFont );
|
||||
Dirty = true;
|
||||
}
|
||||
}
|
||||
|
||||
protected LauncherWidget lastClicked;
|
||||
@ -126,5 +140,17 @@ namespace Launcher2 {
|
||||
widget.DrawAt( drawer, text, font, Anchor.Centre, verAnchor, width, height, x, y );
|
||||
widgets[widgetIndex++] = widget;
|
||||
}
|
||||
|
||||
protected void MakeLabelAt( string text, Font font, Anchor horAnchor, Anchor verAnchor, int x, int y) {
|
||||
if( widgets[widgetIndex] != null ) {
|
||||
LauncherLabelWidget input = (LauncherLabelWidget)widgets[widgetIndex];
|
||||
input.DrawAt( drawer, text, font, horAnchor, verAnchor, x, y );
|
||||
} else {
|
||||
LauncherLabelWidget widget = new LauncherLabelWidget( game, text );
|
||||
widget.DrawAt( drawer, text, font, horAnchor, verAnchor, x, y );
|
||||
widgets[widgetIndex] = widget;
|
||||
}
|
||||
widgetIndex++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -70,6 +70,10 @@ namespace Launcher2 {
|
||||
MakeButtonAt( "Singleplayer", Anchor.Centre, Anchor.Centre,
|
||||
buttonWidth, buttonHeight, 0, 0,
|
||||
(x, y) => Client.Start( "default.zip" ) );
|
||||
|
||||
MakeButtonAt( "Check for updates", Anchor.Centre, Anchor.Centre,
|
||||
buttonWidth, buttonHeight, 0, 100,
|
||||
(x, y) => game.SetScreen( new UpdatesScreen( game ) ) );
|
||||
}
|
||||
|
||||
const int buttonWidth = 220, buttonHeight = 35, sideButtonWidth = 150;
|
||||
|
@ -15,6 +15,7 @@ namespace Launcher2 {
|
||||
textFont = new Font( "Arial", 16, FontStyle.Bold );
|
||||
infoFont = new Font( "Arial", 14, FontStyle.Regular );
|
||||
statusFont = new Font( "Arial", 13, FontStyle.Italic );
|
||||
buttonFont = textFont;
|
||||
widgets = new LauncherWidget[4];
|
||||
}
|
||||
|
||||
@ -41,24 +42,6 @@ namespace Launcher2 {
|
||||
Dirty = true;
|
||||
}
|
||||
|
||||
protected override void UnselectWidget( LauncherWidget widget ) {
|
||||
LauncherButtonWidget button = widget as LauncherButtonWidget;
|
||||
if( button != null ) {
|
||||
button.Active = false;
|
||||
button.Redraw( drawer, button.Text, textFont );
|
||||
Dirty = true;
|
||||
}
|
||||
}
|
||||
|
||||
protected override void SelectWidget( LauncherWidget widget ) {
|
||||
LauncherButtonWidget button = widget as LauncherButtonWidget;
|
||||
if( button != null ) {
|
||||
button.Active = true;
|
||||
button.Redraw( drawer, button.Text, textFont );
|
||||
Dirty = true;
|
||||
}
|
||||
}
|
||||
|
||||
ResourceFetcher fetcher;
|
||||
void DownloadResources( int mouseX, int mouseY ) {
|
||||
if( game.Downloader == null )
|
||||
@ -85,10 +68,9 @@ namespace Launcher2 {
|
||||
drawer.DrawRect( backCol, game.Width / 2 - 175,
|
||||
game.Height / 2 - 70, 175 * 2, 70 * 2 );
|
||||
|
||||
string text = widgets[0] == null ?
|
||||
String.Format( format, ResourceFetcher.EstimateDownloadSize().ToString( "F2" ) )
|
||||
: ((LauncherLabelWidget)widgets[0]).Text;
|
||||
MakeTextAt( statusFont, text, 0, 5 );
|
||||
string text = widgets[0] != null ? widgets[0].Text
|
||||
: String.Format( format, ResourceFetcher.EstimateDownloadSize() );
|
||||
MakeLabelAt( text, statusFont, Anchor.Centre, Anchor.Centre, 0, 5 );
|
||||
|
||||
// Clear the entire previous widgets state.
|
||||
for( int i = 1; i < widgets.Length; i++ ) {
|
||||
@ -98,7 +80,7 @@ namespace Launcher2 {
|
||||
}
|
||||
|
||||
if( fetcher == null ) {
|
||||
MakeTextAt( infoFont, mainText, 0, -30 );
|
||||
MakeLabelAt( mainText, infoFont, Anchor.Centre, Anchor.Centre, 0, -30 );
|
||||
MakeButtonAt( "Yes", 60, 30, textFont, Anchor.Centre,
|
||||
-50, 40, DownloadResources );
|
||||
|
||||
@ -120,12 +102,6 @@ namespace Launcher2 {
|
||||
}
|
||||
}
|
||||
|
||||
void MakeTextAt( Font font, string text, int x, int y ) {
|
||||
LauncherLabelWidget widget = new LauncherLabelWidget( game, text );
|
||||
widget.DrawAt( drawer, text, font, Anchor.Centre, Anchor.Centre, x, y );
|
||||
widgets[widgetIndex++] = widget;
|
||||
}
|
||||
|
||||
public override void Dispose() {
|
||||
game.Window.Mouse.Move -= MouseMove;
|
||||
game.Window.Mouse.ButtonDown -= MouseButtonDown;
|
||||
|
113
Launcher2/Gui/Screens/UpdatesScreen.cs
Normal file
113
Launcher2/Gui/Screens/UpdatesScreen.cs
Normal file
@ -0,0 +1,113 @@
|
||||
using System;
|
||||
using System.Drawing;
|
||||
using System.Globalization;
|
||||
using System.IO;
|
||||
using System.Net;
|
||||
using ClassicalSharp;
|
||||
|
||||
namespace Launcher2 {
|
||||
|
||||
public sealed class UpdatesScreen : LauncherScreen {
|
||||
|
||||
Font titleFont, infoFont;
|
||||
public UpdatesScreen( LauncherWindow game ) : base( game ) {
|
||||
game.Window.Mouse.Move += MouseMove;
|
||||
game.Window.Mouse.ButtonDown += MouseButtonDown;
|
||||
|
||||
titleFont = new Font( "Arial", 16, FontStyle.Bold );
|
||||
infoFont = new Font( "Arial", 14, FontStyle.Regular );
|
||||
buttonFont = titleFont;
|
||||
widgets = new LauncherWidget[16];
|
||||
}
|
||||
|
||||
UpdateCheckTask checkTask;
|
||||
public override void Init() {
|
||||
checkTask = new UpdateCheckTask();
|
||||
checkTask.CheckForUpdatesAsync();
|
||||
Resize();
|
||||
}
|
||||
|
||||
public override void Tick() {
|
||||
if( checkTask != null && !checkTask.Working ) {
|
||||
if( checkTask.Exception != null ) {
|
||||
updateCheckFailed = true;
|
||||
} else {
|
||||
lastStable = DateTime.Parse( checkTask.LatestStableDate,
|
||||
null, DateTimeStyles.AssumeUniversal );
|
||||
lastDev = DateTime.Parse( checkTask.LatestDevDate,
|
||||
null, DateTimeStyles.AssumeUniversal );
|
||||
|
||||
validStable = Int32.Parse( checkTask.LatestStableSize ) > 50000;
|
||||
validDev = Int32.Parse( checkTask.LatestDevSize ) > 50000;
|
||||
}
|
||||
checkTask = null;
|
||||
game.MakeBackground();
|
||||
Resize();
|
||||
}
|
||||
}
|
||||
|
||||
public override void Resize() {
|
||||
using( drawer ) {
|
||||
drawer.SetBitmap( game.Framebuffer );
|
||||
Draw();
|
||||
}
|
||||
Dirty = true;
|
||||
}
|
||||
|
||||
const string dateFormat = "dd-MM-yyyy HH:mm";
|
||||
DateTime lastStable, lastDev;
|
||||
bool validStable = true, validDev = true;
|
||||
bool updateCheckFailed;
|
||||
|
||||
void Draw() {
|
||||
widgetIndex = 0;
|
||||
|
||||
MakeLabelAt( "Your build:", titleFont, Anchor.Centre, Anchor.Centre, -55, -120 );
|
||||
string yourBuild = File.GetLastWriteTimeUtc( "ClassicalSharp.exe" ).ToString( dateFormat );
|
||||
MakeLabelAt( yourBuild, infoFont, Anchor.Centre, Anchor.Centre, 100, -120 );
|
||||
|
||||
MakeLabelAt( "Latest stable:", titleFont, Anchor.Centre, Anchor.Centre, -70, -80 );
|
||||
string latestStable = GetDateString( lastStable, validStable );
|
||||
MakeLabelAt( latestStable, infoFont, Anchor.Centre, Anchor.Centre, 100, -80 );
|
||||
MakeButtonAt( "Update to stable", 180, 30, titleFont, Anchor.Centre, 0, -40,
|
||||
(x, y) => UpdateBuild( lastDev, validDev, "latest.Release.zip" ) );
|
||||
|
||||
MakeLabelAt( "Latest OpenGL dev:", titleFont, Anchor.Centre, Anchor.Centre, -100, 0 );
|
||||
string latestDev = GetDateString( lastDev, validDev );
|
||||
MakeLabelAt( latestDev, infoFont, Anchor.Centre, Anchor.Centre, 100, 0 );
|
||||
MakeButtonAt( "Update to OpenGL dev", 240, 30, titleFont, Anchor.Centre, 0, 40,
|
||||
(x, y) => UpdateBuild( lastDev, validDev, "latest.zip" ) );
|
||||
|
||||
MakeLabelAt( "Latest D3D9 dev:", titleFont, Anchor.Centre, Anchor.Centre, -85, 80 );
|
||||
MakeLabelAt( latestDev, infoFont, Anchor.Centre, Anchor.Centre, 100, 80 );
|
||||
MakeButtonAt( "Update to D3D9 dev", 230, 30, titleFont, Anchor.Centre, 0, 120,
|
||||
(x, y) => UpdateBuild( lastDev, validDev, "latest.DirectX.zip" ) );
|
||||
|
||||
MakeButtonAt( "Back", 80, 35, titleFont, Anchor.Centre,
|
||||
0, 200, (x, y) => game.SetScreen( new MainScreen( game ) ) );
|
||||
}
|
||||
|
||||
string GetDateString( DateTime last, bool valid ) {
|
||||
if( updateCheckFailed ) return "Update check failed";
|
||||
if( !valid ) return "Build corrupted";
|
||||
if( last == DateTime.MinValue ) return "Checking..";
|
||||
return last.ToString( dateFormat );
|
||||
}
|
||||
|
||||
void UpdateBuild( DateTime last, bool valid, string dir ) {
|
||||
if( last == DateTime.MinValue || !valid ) return;
|
||||
|
||||
using( WebClient client = new WebClient() ) {
|
||||
client.DownloadFile( UpdateCheckTask.UpdatesUri + dir, "update.zip" );
|
||||
}
|
||||
}
|
||||
|
||||
public override void Dispose() {
|
||||
game.Window.Mouse.Move -= MouseMove;
|
||||
game.Window.Mouse.ButtonDown -= MouseButtonDown;
|
||||
|
||||
titleFont.Dispose();
|
||||
infoFont.Dispose();
|
||||
}
|
||||
}
|
||||
}
|
@ -7,7 +7,6 @@ namespace Launcher2 {
|
||||
public sealed class LauncherButtonWidget : LauncherWidget {
|
||||
|
||||
public int ButtonWidth, ButtonHeight;
|
||||
public string Text;
|
||||
public bool Shadow = true;
|
||||
public bool Active = false;
|
||||
|
||||
|
@ -9,7 +9,6 @@ namespace Launcher2 {
|
||||
public sealed class LauncherInputWidget : LauncherWidget {
|
||||
|
||||
public int ButtonWidth, ButtonHeight;
|
||||
public string Text;
|
||||
|
||||
/// <summary> Whether the input widget currently is focused through a mouse click or tab. </summary>
|
||||
public bool Active;
|
||||
|
@ -7,8 +7,6 @@ namespace Launcher2 {
|
||||
/// <summary> Widget that represents text that cannot be modified by the user. </summary>
|
||||
public sealed class LauncherLabelWidget : LauncherWidget {
|
||||
|
||||
public string Text;
|
||||
|
||||
public LauncherLabelWidget( LauncherWindow window, string text ) : base( window ) {
|
||||
Text = text;
|
||||
}
|
||||
|
@ -9,6 +9,8 @@ namespace Launcher2 {
|
||||
public LauncherWindow Window;
|
||||
public Action<int, int> OnClick;
|
||||
|
||||
public string Text;
|
||||
|
||||
public LauncherWidget( LauncherWindow window ) {
|
||||
Window = window;
|
||||
}
|
||||
|
@ -4,7 +4,7 @@
|
||||
<ProjectGuid>{3E84ACC1-27B4-401B-A359-6AAE4DF6C9B5}</ProjectGuid>
|
||||
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
|
||||
<Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
|
||||
<OutputType>WinExe</OutputType>
|
||||
<OutputType>Exe</OutputType>
|
||||
<RootNamespace>Launcher2</RootNamespace>
|
||||
<AssemblyName>Launcher2</AssemblyName>
|
||||
<TargetFrameworkVersion>v2.0</TargetFrameworkVersion>
|
||||
@ -58,6 +58,7 @@
|
||||
<Compile Include="Gui\Screens\LauncherScreen.cs" />
|
||||
<Compile Include="Gui\Screens\MainScreen.cs" />
|
||||
<Compile Include="Gui\Screens\ResourcesScreen.cs" />
|
||||
<Compile Include="Gui\Screens\UpdatesScreen.cs" />
|
||||
<Compile Include="Gui\TableWidget\LauncherTableWidget.cs" />
|
||||
<Compile Include="Gui\TableWidget\LauncherTableWidget.Input.cs" />
|
||||
<Compile Include="Gui\Widgets\LauncherButtonWidget.cs" />
|
||||
@ -76,8 +77,9 @@
|
||||
<Compile Include="Utils\ClientStartData.cs" />
|
||||
<Compile Include="Utils\Secure.cs" />
|
||||
<Compile Include="WebService\ClassiCubeSession.cs" />
|
||||
<Compile Include="WebService\GameSession.cs" />
|
||||
<Compile Include="WebService\IWebTask.cs" />
|
||||
<Compile Include="WebService\ServerListEntry.cs" />
|
||||
<Compile Include="WebService\UpdateCheckTask.cs" />
|
||||
<Compile Include="WebService\WebUtility.cs" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
|
@ -55,9 +55,10 @@ namespace Launcher2 {
|
||||
return File.Exists( "default.zip" );
|
||||
}
|
||||
|
||||
public static float EstimateDownloadSize() {
|
||||
return (291 + 4621 + 7) / 1024f;
|
||||
// clasic.jar + 1.6.2.jar + terrain-patch.png
|
||||
public static string EstimateDownloadSize() {
|
||||
float size = (291 + 4621 + 7) / 1024f;
|
||||
// classic.jar + 1.6.2.jar + terrain-patch.png
|
||||
return size.ToString( "F2" );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1,9 +1,11 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Net;
|
||||
using System.Threading;
|
||||
|
||||
namespace Launcher2 {
|
||||
|
||||
public class ClassicubeSession : GameSession {
|
||||
public sealed class ClassicubeSession : IWebTask {
|
||||
|
||||
const string classicubeNetUri = "https://www.classicube.net/",
|
||||
loginUri = "https://www.classicube.net/acc/login",
|
||||
@ -13,7 +15,43 @@ namespace Launcher2 {
|
||||
const string loggedInAs = @"<a href=""/acc"" class=""button"">";
|
||||
StringComparison ordinal = StringComparison.Ordinal;
|
||||
|
||||
public override void Login( string user, string password ) {
|
||||
public List<ServerListEntry> Servers = new List<ServerListEntry>();
|
||||
|
||||
public void LoginAsync( string user, string password ) {
|
||||
Username = user;
|
||||
Working = true;
|
||||
Exception = null;
|
||||
Status = "&eSigning in..";
|
||||
Servers = new List<ServerListEntry>();
|
||||
|
||||
Thread thread = new Thread( LoginWorker, 256 * 1024 );
|
||||
thread.Name = "Launcher.CCLoginAsync";
|
||||
thread.Start( password );
|
||||
}
|
||||
|
||||
void LoginWorker( object password ) {
|
||||
// Sign in to classicube.net
|
||||
try {
|
||||
Login( Username, (string)password );
|
||||
} catch( WebException ex ) {
|
||||
Finish( false, ex, "sign in" ); return;
|
||||
} catch( InvalidOperationException ex ) {
|
||||
Finish( false, null, "&eFailed to sign in: " +
|
||||
Environment.NewLine + ex.Message ); return;
|
||||
}
|
||||
|
||||
// Retrieve list of public servers
|
||||
Status = "&eRetrieving public servers list..";
|
||||
try {
|
||||
Servers = GetPublicServers();
|
||||
} catch( WebException ex ) {
|
||||
Servers = new List<ServerListEntry>();
|
||||
Finish( false, ex, "retrieving servers list" ); return;
|
||||
}
|
||||
Finish( true, null, "&eSigned in" );
|
||||
}
|
||||
|
||||
void Login( string user, string password ) {
|
||||
Username = user;
|
||||
// Step 1: GET csrf token from login page.
|
||||
var swGet = System.Diagnostics.Stopwatch.StartNew();
|
||||
@ -52,7 +90,7 @@ namespace Launcher2 {
|
||||
}
|
||||
}
|
||||
|
||||
public override ClientStartData GetConnectInfo( string hash ) {
|
||||
public ClientStartData GetConnectInfo( string hash ) {
|
||||
string uri = playUri + hash;
|
||||
var response = GetHtml( uri, classicubeNetUri );
|
||||
ClientStartData data = new ClientStartData();
|
||||
@ -61,7 +99,7 @@ namespace Launcher2 {
|
||||
foreach( string line in response ) {
|
||||
int index = 0;
|
||||
// Look for <param name="x" value="x"> tags
|
||||
if( ( index = line.IndexOf( "<param", ordinal ) ) > 0 ) {
|
||||
if( (index = line.IndexOf( "<param", ordinal )) > 0 ) {
|
||||
int nameStart = index + 13;
|
||||
int nameEnd = line.IndexOf( '"', nameStart );
|
||||
string paramName = line.Substring( nameStart, nameEnd - nameStart );
|
||||
@ -85,7 +123,7 @@ namespace Launcher2 {
|
||||
return line.Substring( valueStart, valueEnd - valueStart );
|
||||
}
|
||||
|
||||
public override List<ServerListEntry> GetPublicServers() {
|
||||
public List<ServerListEntry> GetPublicServers() {
|
||||
var sw = System.Diagnostics.Stopwatch.StartNew();
|
||||
var response = GetHtml( publicServersUri, classicubeNetUri );
|
||||
List<ServerListEntry> servers = new List<ServerListEntry>();
|
||||
|
@ -3,59 +3,30 @@ using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Net;
|
||||
using System.Text;
|
||||
using System.Threading;
|
||||
|
||||
namespace Launcher2 {
|
||||
|
||||
public abstract class GameSession {
|
||||
|
||||
public string Username;
|
||||
/// <summary> Represents a task that performs a series of GET or POST requests asynchronously. </summary>
|
||||
public abstract class IWebTask {
|
||||
|
||||
public virtual void ResetSession() {
|
||||
Username = null;
|
||||
cookies = new CookieContainer();
|
||||
}
|
||||
|
||||
/// <summary> Whether this web task is still performing GET or POST requests asynchronously. </summary>
|
||||
public bool Working;
|
||||
|
||||
/// <summary> Handled exception that was generated by the last GET or POST request. </summary>
|
||||
public WebException Exception;
|
||||
|
||||
/// <summary> Current status of this web task (e.g. downloading page X) </summary>
|
||||
public string Status;
|
||||
public List<ServerListEntry> Servers = new List<ServerListEntry>();
|
||||
|
||||
public void LoginAsync( string user, string password ) {
|
||||
Username = user;
|
||||
Working = true;
|
||||
Exception = null;
|
||||
Status = "&eSigning in..";
|
||||
Servers = new List<ServerListEntry>();
|
||||
/// <summary> Username used when performing GET or POST requests, can be left null. </summary>
|
||||
public string Username;
|
||||
|
||||
Thread thread = new Thread( LoginWorker, 256 * 1024 );
|
||||
thread.Name = "Launcher.LoginAsync";
|
||||
thread.Start( password );
|
||||
}
|
||||
|
||||
void LoginWorker( object password ) {
|
||||
// Sign in to classicube.net
|
||||
try {
|
||||
Login( Username, (string)password );
|
||||
} catch( WebException ex ) {
|
||||
Finish( false, ex, "sign in" ); return;
|
||||
} catch( InvalidOperationException ex ) {
|
||||
Finish( false, null, "&eFailed to sign in: " +
|
||||
Environment.NewLine + ex.Message ); return;
|
||||
}
|
||||
|
||||
// Retrieve list of public servers
|
||||
Status = "&eRetrieving public servers list..";
|
||||
try {
|
||||
Servers = GetPublicServers();
|
||||
} catch( WebException ex ) {
|
||||
Servers = new List<ServerListEntry>();
|
||||
Finish( false, ex, "retrieving servers list" ); return;
|
||||
}
|
||||
Finish( true, null, "&eSigned in" );
|
||||
}
|
||||
|
||||
void Finish( bool success, WebException ex, string status ) {
|
||||
protected void Finish( bool success, WebException ex, string status ) {
|
||||
if( !success )
|
||||
Username = null;
|
||||
Working = false;
|
||||
@ -64,13 +35,7 @@ namespace Launcher2 {
|
||||
Status = status;
|
||||
}
|
||||
|
||||
public abstract void Login( string user, string password );
|
||||
|
||||
public abstract ClientStartData GetConnectInfo( string hash );
|
||||
|
||||
public abstract List<ServerListEntry> GetPublicServers();
|
||||
|
||||
CookieContainer cookies = new CookieContainer();
|
||||
protected CookieContainer cookies = new CookieContainer();
|
||||
|
||||
protected HttpWebResponse MakeRequest( string uri, string referer, string data ) {
|
||||
HttpWebRequest request = (HttpWebRequest)WebRequest.Create( uri );
|
78
Launcher2/WebService/UpdateCheckTask.cs
Normal file
78
Launcher2/WebService/UpdateCheckTask.cs
Normal file
@ -0,0 +1,78 @@
|
||||
using System;
|
||||
using System.Net;
|
||||
using System.Threading;
|
||||
|
||||
namespace Launcher2 {
|
||||
|
||||
public sealed class UpdateCheckTask : IWebTask {
|
||||
|
||||
public const string UpdatesUri = "http://cs.classicube.net/";
|
||||
StringComparison ordinal = StringComparison.Ordinal;
|
||||
|
||||
public string LatestStableDate, LatestStableSize;
|
||||
public string LatestDevDate, LatestDevSize;
|
||||
|
||||
public void CheckForUpdatesAsync() {
|
||||
Working = true;
|
||||
Exception = null;
|
||||
LatestStableDate = null; LatestStableSize = null;
|
||||
LatestDevDate = null; LatestDevSize = null;
|
||||
|
||||
Thread thread = new Thread( UpdateWorker, 256 * 1024 );
|
||||
thread.Name = "Launcher.UpdateCheck";
|
||||
thread.Start();
|
||||
}
|
||||
|
||||
void UpdateWorker() {
|
||||
try {
|
||||
CheckUpdates();
|
||||
} catch( WebException ex ) {
|
||||
Finish( false, ex, null ); return;
|
||||
}
|
||||
Finish( true, null, null );
|
||||
}
|
||||
|
||||
void CheckUpdates() {
|
||||
var response = GetHtml( UpdatesUri, UpdatesUri );
|
||||
foreach( string line in response ) {
|
||||
Console.WriteLine( line );
|
||||
if( line.StartsWith( "latest.", ordinal ) ) {
|
||||
int index = 0;
|
||||
string buildName = ReadToken( line, ref index );
|
||||
string date = ReadToken( line, ref index );
|
||||
string time = ReadToken( line, ref index );
|
||||
string buildSize = ReadToken( line, ref index );
|
||||
|
||||
|
||||
if( line.StartsWith( "latest.zip", ordinal ) ) {
|
||||
LatestDevDate = date + " " + time;
|
||||
LatestDevSize = buildSize;
|
||||
} else if( line.StartsWith( "latest.Release.zip", ordinal ) ) {
|
||||
LatestStableDate = date + " " + time;
|
||||
LatestStableSize = buildSize;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
string ReadToken( string value, ref int index ) {
|
||||
int start = index;
|
||||
int wordEnd = -1;
|
||||
for( ; index < value.Length; index++ ) {
|
||||
if( value[index] == ' ' ) {
|
||||
// found end of this word
|
||||
if( wordEnd == -1 )
|
||||
wordEnd = index;
|
||||
} else {
|
||||
// found start of next word
|
||||
if( wordEnd != -1 )
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if( wordEnd == -1 )
|
||||
wordEnd = value.Length;
|
||||
return value.Substring( start, wordEnd - start );
|
||||
}
|
||||
}
|
||||
}
|
Loading…
x
Reference in New Issue
Block a user