mirror of
https://github.com/ClassiCube/ClassiCube.git
synced 2025-09-18 12:05:14 -04:00
Treat .zip as texture packs in EnvMapAppearance packets, use builds.json for determing latest builds.
This commit is contained in:
parent
3a15ef9024
commit
59d0b2da74
@ -82,10 +82,11 @@ namespace ClassicalSharp {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void MakeSelectionTexture() {
|
void MakeSelectionTexture() {
|
||||||
int size = (int)selBlockSize;
|
int hSize = (int)selBlockSize;
|
||||||
int y = game.Height - size;
|
int vSize = (int)Math.Floor( 23 * 2 * game.GuiScale );
|
||||||
|
int y = game.Height - vSize;
|
||||||
TextureRec rec = new TextureRec( 0, 22/256f, 24/256f, 24/256f );
|
TextureRec rec = new TextureRec( 0, 22/256f, 24/256f, 24/256f );
|
||||||
selTex = new Texture( game.GuiTexId, 0, y, size, size, rec );
|
selTex = new Texture( game.GuiTexId, 0, y, hSize, vSize, rec );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -322,7 +322,9 @@ namespace ClassicalSharp {
|
|||||||
if( !game.AcceptedUrls.HasAccepted( url ) )
|
if( !game.AcceptedUrls.HasAccepted( url ) )
|
||||||
game.AcceptedUrls.AddAccepted( url );
|
game.AcceptedUrls.AddAccepted( url );
|
||||||
|
|
||||||
if( usingTexturePack )
|
// NOTE: This is entirely against the original CPE specification, but we
|
||||||
|
// do it here as a convenience until EnvMapAppearance v2 is more widely adopted.
|
||||||
|
if( usingTexturePack || url.EndsWith( ".zip" ) )
|
||||||
game.AsyncDownloader.DownloadData( url, true, "texturePack", lastModified );
|
game.AsyncDownloader.DownloadData( url, true, "texturePack", lastModified );
|
||||||
else
|
else
|
||||||
game.AsyncDownloader.DownloadImage( url, true, "terrain", lastModified );
|
game.AsyncDownloader.DownloadImage( url, true, "terrain", lastModified );
|
||||||
|
@ -18,7 +18,7 @@ namespace Launcher2 {
|
|||||||
titleFont = new Font( "Arial", 16, FontStyle.Bold );
|
titleFont = new Font( "Arial", 16, FontStyle.Bold );
|
||||||
infoFont = new Font( "Arial", 14, FontStyle.Regular );
|
infoFont = new Font( "Arial", 14, FontStyle.Regular );
|
||||||
buttonFont = titleFont;
|
buttonFont = titleFont;
|
||||||
widgets = new LauncherWidget[16];
|
widgets = new LauncherWidget[17];
|
||||||
}
|
}
|
||||||
|
|
||||||
UpdateCheckTask checkTask;
|
UpdateCheckTask checkTask;
|
||||||
@ -28,18 +28,20 @@ namespace Launcher2 {
|
|||||||
Resize();
|
Resize();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
Build dev, stable;
|
||||||
public override void Tick() {
|
public override void Tick() {
|
||||||
if( checkTask != null && !checkTask.Working ) {
|
if( checkTask != null && !checkTask.Working ) {
|
||||||
if( checkTask.Exception != null ) {
|
if( checkTask.Exception != null ) {
|
||||||
updateCheckFailed = true;
|
updateCheckFailed = true;
|
||||||
} else {
|
} else {
|
||||||
lastStable = DateTime.Parse( checkTask.LatestStableDate,
|
dev = checkTask.LatestDev;
|
||||||
null, DateTimeStyles.AssumeUniversal );
|
lastDev = dev.TimeBuilt;
|
||||||
lastDev = DateTime.Parse( checkTask.LatestDevDate,
|
validDev = dev.DirectXSize > 50000 && dev.OpenGLSize > 50000;
|
||||||
null, DateTimeStyles.AssumeUniversal );
|
|
||||||
|
|
||||||
validStable = Int32.Parse( checkTask.LatestStableSize ) > 50000;
|
stable = checkTask.LatestStable;
|
||||||
validDev = Int32.Parse( checkTask.LatestDevSize ) > 50000;
|
lastStable = stable.TimeBuilt;
|
||||||
|
validStable = stable.DirectXSize > 50000 && stable.OpenGLSize > 50000;
|
||||||
}
|
}
|
||||||
checkTask = null;
|
checkTask = null;
|
||||||
game.MakeBackground();
|
game.MakeBackground();
|
||||||
@ -64,22 +66,24 @@ namespace Launcher2 {
|
|||||||
widgetIndex = 0;
|
widgetIndex = 0;
|
||||||
|
|
||||||
MakeLabelAt( "Your build:", titleFont, Anchor.Centre, Anchor.Centre, -55, -120 );
|
MakeLabelAt( "Your build:", titleFont, Anchor.Centre, Anchor.Centre, -55, -120 );
|
||||||
string yourBuild = File.GetLastWriteTimeUtc( "ClassicalSharp.exe" ).ToString( dateFormat );
|
string yourBuild = File.GetLastWriteTime( "ClassicalSharp.exe" ).ToString( dateFormat );
|
||||||
MakeLabelAt( yourBuild, infoFont, Anchor.Centre, Anchor.Centre, 100, -120 );
|
MakeLabelAt( yourBuild, infoFont, Anchor.Centre, Anchor.Centre, 100, -120 );
|
||||||
|
|
||||||
MakeLabelAt( "Latest stable:", titleFont, Anchor.Centre, Anchor.Centre, -70, -80 );
|
MakeLabelAt( "Latest stable:", titleFont, Anchor.Centre, Anchor.Centre, -70, -80 );
|
||||||
string latestStable = GetDateString( lastStable, validStable );
|
string latestStable = GetDateString( lastStable, validStable );
|
||||||
MakeLabelAt( latestStable, infoFont, Anchor.Centre, Anchor.Centre, 100, -80 );
|
MakeLabelAt( latestStable, infoFont, Anchor.Centre, Anchor.Centre, 100, -80 );
|
||||||
MakeButtonAt( "Update to stable", 180, 30, titleFont, Anchor.Centre, 0, -40,
|
MakeButtonAt( "Update to D3D9 stable", 260, 30, titleFont, Anchor.Centre, 0, -40,
|
||||||
(x, y) => UpdateBuild( lastStable, validStable, "latest.Release.zip" ) );
|
(x, y) => UpdateBuild( lastStable, validStable, true, true ) );
|
||||||
|
MakeButtonAt( "Update to OpenGL stable", 260, 30, titleFont, Anchor.Centre, 0, 0,
|
||||||
|
(x, y) => UpdateBuild( lastStable, validStable, true, false ) );
|
||||||
|
|
||||||
MakeLabelAt( "Latest dev:", titleFont, Anchor.Centre, Anchor.Centre, -60, 40 );
|
MakeLabelAt( "Latest dev:", titleFont, Anchor.Centre, Anchor.Centre, -60, 40 );
|
||||||
string latestDev = GetDateString( lastDev, validDev );
|
string latestDev = GetDateString( lastDev, validDev );
|
||||||
MakeLabelAt( latestDev, infoFont, Anchor.Centre, Anchor.Centre, 100, 40 );
|
MakeLabelAt( latestDev, infoFont, Anchor.Centre, Anchor.Centre, 100, 40 );
|
||||||
MakeButtonAt( "Update to OpenGL dev", 240, 30, titleFont, Anchor.Centre, 0, 80,
|
MakeButtonAt( "Update to D3D9 dev", 240, 30, titleFont, Anchor.Centre, 0, 80,
|
||||||
(x, y) => UpdateBuild( lastDev, validDev, "latest.zip" ) );
|
(x, y) => UpdateBuild( lastDev, validDev, false, true ) );
|
||||||
MakeButtonAt( "Update to D3D9 dev", 240, 30, titleFont, Anchor.Centre, 0, 120,
|
MakeButtonAt( "Update to OpenGL dev", 240, 30, titleFont, Anchor.Centre, 0, 120,
|
||||||
(x, y) => UpdateBuild( lastDev, validDev, "latest.DirectX.zip" ) );
|
(x, y) => UpdateBuild( lastDev, validDev, false, false ) );
|
||||||
|
|
||||||
MakeButtonAt( "Back", 80, 35, titleFont, Anchor.Centre,
|
MakeButtonAt( "Back", 80, 35, titleFont, Anchor.Centre,
|
||||||
0, 200, (x, y) => game.SetScreen( new MainScreen( game ) ) );
|
0, 200, (x, y) => game.SetScreen( new MainScreen( game ) ) );
|
||||||
@ -90,11 +94,15 @@ namespace Launcher2 {
|
|||||||
if( !valid ) return "Build corrupted";
|
if( !valid ) return "Build corrupted";
|
||||||
if( last == DateTime.MinValue ) return "Checking..";
|
if( last == DateTime.MinValue ) return "Checking..";
|
||||||
|
|
||||||
return last.ToUniversalTime().ToString( dateFormat );
|
return last.ToString( dateFormat );
|
||||||
}
|
}
|
||||||
|
|
||||||
void UpdateBuild( DateTime last, bool valid, string dir ) {
|
void UpdateBuild( DateTime last, bool valid, bool release, bool dx ) {
|
||||||
if( last == DateTime.MinValue || !valid ) return;
|
if( last == DateTime.MinValue || !valid ) return;
|
||||||
|
|
||||||
|
Build build = release ? stable : dev;
|
||||||
|
string dir = dx ? build.DirectXPath : build.OpenGLPath;
|
||||||
|
Console.WriteLine( "FETCH! " + dir );
|
||||||
Patcher.Update( dir );
|
Patcher.Update( dir );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -43,6 +43,7 @@
|
|||||||
<CheckForOverflowUnderflow>False</CheckForOverflowUnderflow>
|
<CheckForOverflowUnderflow>False</CheckForOverflowUnderflow>
|
||||||
<DefineConstants>TRACE</DefineConstants>
|
<DefineConstants>TRACE</DefineConstants>
|
||||||
<BaseIntermediateOutputPath>obj\</BaseIntermediateOutputPath>
|
<BaseIntermediateOutputPath>obj\</BaseIntermediateOutputPath>
|
||||||
|
<StartAction>Project</StartAction>
|
||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<Reference Include="SharpWave">
|
<Reference Include="SharpWave">
|
||||||
|
@ -162,7 +162,7 @@ namespace Launcher2 {
|
|||||||
static int GetLastIndexOfNumber( string json, int index ) {
|
static int GetLastIndexOfNumber( string json, int index ) {
|
||||||
int lastIndex = index;
|
int lastIndex = index;
|
||||||
for( ; lastIndex < json.Length; lastIndex++ ) {
|
for( ; lastIndex < json.Length; lastIndex++ ) {
|
||||||
if( "0123456789+-".IndexOf( json[lastIndex] ) == -1 )
|
if( "0123456789+-.".IndexOf( json[lastIndex] ) == -1 )
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
return lastIndex - 1;
|
return lastIndex - 1;
|
||||||
|
@ -2,6 +2,7 @@
|
|||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Net;
|
using System.Net;
|
||||||
using System.Threading;
|
using System.Threading;
|
||||||
|
using JsonObject = System.Collections.Generic.Dictionary<string, object>;
|
||||||
|
|
||||||
namespace Launcher2 {
|
namespace Launcher2 {
|
||||||
|
|
||||||
@ -56,8 +57,7 @@ namespace Launcher2 {
|
|||||||
var swGet = System.Diagnostics.Stopwatch.StartNew();
|
var swGet = System.Diagnostics.Stopwatch.StartNew();
|
||||||
string getResponse = GetHtmlAll( loginUri, classicubeNetUri );
|
string getResponse = GetHtmlAll( loginUri, classicubeNetUri );
|
||||||
int index = 0; bool success = true;
|
int index = 0; bool success = true;
|
||||||
Dictionary<string, object> data =
|
JsonObject data = (JsonObject)Json.ParseValue( getResponse, ref index, ref success );
|
||||||
(Dictionary<string, object>)Json.ParseValue( getResponse, ref index, ref success );
|
|
||||||
string token = (string)data["token"];
|
string token = (string)data["token"];
|
||||||
|
|
||||||
// Step 2: POST to login page with csrf token.
|
// Step 2: POST to login page with csrf token.
|
||||||
@ -72,7 +72,7 @@ namespace Launcher2 {
|
|||||||
var sw = System.Diagnostics.Stopwatch.StartNew();
|
var sw = System.Diagnostics.Stopwatch.StartNew();
|
||||||
string response = PostHtmlAll( loginUri, loginUri, loginData );
|
string response = PostHtmlAll( loginUri, loginUri, loginData );
|
||||||
index = 0; success = true;
|
index = 0; success = true;
|
||||||
data = (Dictionary<string, object>)Json.ParseValue( response, ref index, ref success );
|
data = (JsonObject)Json.ParseValue( response, ref index, ref success );
|
||||||
|
|
||||||
List<object> errors = (List<object>)data["errors"];
|
List<object> errors = (List<object>)data["errors"];
|
||||||
if( errors.Count > 0 || (data.ContainsKey( "username" ) && data["username"] == null) )
|
if( errors.Count > 0 || (data.ContainsKey( "username" ) && data["username"] == null) )
|
||||||
@ -88,13 +88,12 @@ namespace Launcher2 {
|
|||||||
string response = GetHtmlAll( uri, classicubeNetUri );
|
string response = GetHtmlAll( uri, classicubeNetUri );
|
||||||
|
|
||||||
int index = 0; bool success = true;
|
int index = 0; bool success = true;
|
||||||
Dictionary<string, object> root =
|
JsonObject root = (JsonObject)Json.ParseValue( response, ref index, ref success );
|
||||||
(Dictionary<string, object>)Json.ParseValue( response, ref index, ref success );
|
|
||||||
List<object> list = (List<object>)root["servers"];
|
List<object> list = (List<object>)root["servers"];
|
||||||
|
|
||||||
Dictionary<string, object> pairs = (Dictionary<string, object>)list[0];
|
JsonObject obj = (JsonObject)list[0];
|
||||||
return new ClientStartData( Username, (string)pairs["mppass"],
|
return new ClientStartData( Username, (string)obj["mppass"],
|
||||||
(string)pairs["ip"], (string)pairs["port"] );
|
(string)obj["ip"], (string)obj["port"] );
|
||||||
}
|
}
|
||||||
|
|
||||||
public List<ServerListEntry> GetPublicServers() {
|
public List<ServerListEntry> GetPublicServers() {
|
||||||
@ -102,17 +101,16 @@ namespace Launcher2 {
|
|||||||
List<ServerListEntry> servers = new List<ServerListEntry>();
|
List<ServerListEntry> servers = new List<ServerListEntry>();
|
||||||
string response = GetHtmlAll( publicServersUri, classicubeNetUri );
|
string response = GetHtmlAll( publicServersUri, classicubeNetUri );
|
||||||
int index = 0; bool success = true;
|
int index = 0; bool success = true;
|
||||||
Dictionary<string, object> root =
|
JsonObject root = (JsonObject)Json.ParseValue( response, ref index, ref success );
|
||||||
(Dictionary<string, object>)Json.ParseValue( response, ref index, ref success );
|
|
||||||
List<object> list = (List<object>)root["servers"];
|
List<object> list = (List<object>)root["servers"];
|
||||||
|
|
||||||
foreach( object server in list ) {
|
foreach( object server in list ) {
|
||||||
Dictionary<string, object> pairs = (Dictionary<string, object>)server;
|
JsonObject obj = (JsonObject)server;
|
||||||
servers.Add( new ServerListEntry(
|
servers.Add( new ServerListEntry(
|
||||||
(string)pairs["hash"], (string)pairs["name"],
|
(string)obj["hash"], (string)obj["name"],
|
||||||
(string)pairs["players"], (string)pairs["maxplayers"],
|
(string)obj["players"], (string)obj["maxplayers"],
|
||||||
(string)pairs["uptime"], (string)pairs["mppass"],
|
(string)obj["uptime"], (string)obj["mppass"],
|
||||||
(string)pairs["ip"], (string)pairs["port"] ) );
|
(string)obj["ip"], (string)obj["port"] ) );
|
||||||
}
|
}
|
||||||
Log( "cc servers took " + sw.ElapsedMilliseconds );
|
Log( "cc servers took " + sw.ElapsedMilliseconds );
|
||||||
sw.Stop();
|
sw.Stop();
|
||||||
|
@ -1,22 +1,28 @@
|
|||||||
using System;
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
using System.Net;
|
using System.Net;
|
||||||
using System.Threading;
|
using System.Threading;
|
||||||
|
using JsonObject = System.Collections.Generic.Dictionary<string, object>;
|
||||||
|
|
||||||
namespace Launcher2 {
|
namespace Launcher2 {
|
||||||
|
|
||||||
|
public class Build {
|
||||||
|
public DateTime TimeBuilt;
|
||||||
|
public string DirectXPath, OpenGLPath;
|
||||||
|
public int DirectXSize, OpenGLSize;
|
||||||
|
}
|
||||||
|
|
||||||
public sealed class UpdateCheckTask : IWebTask {
|
public sealed class UpdateCheckTask : IWebTask {
|
||||||
|
|
||||||
public const string UpdatesUri = "http://cs.classicube.net/";
|
public const string UpdatesUri = "http://cs.classicube.net/";
|
||||||
StringComparison ordinal = StringComparison.Ordinal;
|
public const string BuildsUri = "http://cs.classicube.net/builds.json";
|
||||||
|
public Build LatestDev, LatestStable;
|
||||||
public string LatestStableDate, LatestStableSize;
|
|
||||||
public string LatestDevDate, LatestDevSize;
|
|
||||||
|
|
||||||
public void CheckForUpdatesAsync() {
|
public void CheckForUpdatesAsync() {
|
||||||
Working = true;
|
Working = true;
|
||||||
Exception = null;
|
Exception = null;
|
||||||
LatestStableDate = null; LatestStableSize = null;
|
LatestDev = null;
|
||||||
LatestDevDate = null; LatestDevSize = null;
|
LatestStable = null;
|
||||||
|
|
||||||
Thread thread = new Thread( UpdateWorker, 256 * 1024 );
|
Thread thread = new Thread( UpdateWorker, 256 * 1024 );
|
||||||
thread.Name = "Launcher.UpdateCheck";
|
thread.Name = "Launcher.UpdateCheck";
|
||||||
@ -33,46 +39,35 @@ namespace Launcher2 {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void CheckUpdates() {
|
void CheckUpdates() {
|
||||||
var response = GetHtml( UpdatesUri, UpdatesUri );
|
string response = GetHtmlAll( BuildsUri, UpdatesUri );
|
||||||
foreach( string line in response ) {
|
int index = 0; bool success = true;
|
||||||
if( line.StartsWith( @"<a href=""latest.", ordinal ) ) {
|
JsonObject data = (JsonObject)Json.ParseValue( response, ref index, ref success );
|
||||||
int index = 0;
|
|
||||||
string text = line.Substring( @"<a href=""".Length );
|
|
||||||
|
|
||||||
string buildName = ReadToken( text, ref index );
|
JsonObject devBuild = (JsonObject)data["latest"];
|
||||||
string date = ReadToken( text, ref index );
|
JsonObject releaseBuilds = (JsonObject)data["releases"];
|
||||||
string time = ReadToken( text, ref index );
|
LatestDev = MakeBuild( devBuild, false );
|
||||||
string buildSize = ReadToken( text, ref index );
|
Build[] stableBuilds = new Build[releaseBuilds.Count];
|
||||||
|
|
||||||
if( buildName.Contains( "latest.zip" ) ) {
|
int i = 0;
|
||||||
LatestDevDate = date + " " + time;
|
foreach( KeyValuePair<string, object> pair in releaseBuilds )
|
||||||
LatestDevSize = buildSize;
|
stableBuilds[i++] = MakeBuild( (JsonObject)pair.Value, true );
|
||||||
} else if( buildName.Contains( "latest.Release.zip" ) ) {
|
Array.Sort<Build>( stableBuilds,
|
||||||
LatestStableDate = date + " " + time;
|
(a, b) => b.TimeBuilt.CompareTo( a.TimeBuilt ) );
|
||||||
LatestStableSize = buildSize;
|
LatestStable = stableBuilds[0];
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
string ReadToken( string value, ref int index ) {
|
static readonly DateTime epoch = new DateTime( 1970, 1, 1, 0, 0, 0, DateTimeKind.Utc );
|
||||||
int start = index;
|
Build MakeBuild( JsonObject obj, bool release ) {
|
||||||
int wordEnd = -1;
|
Build build = new Build();
|
||||||
for( ; index < value.Length; index++ ) {
|
string timeKey = release ? "release_ts" : "ts";
|
||||||
if( value[index] == ' ' ) {
|
double rawTime = Double.Parse( (string)obj[timeKey] );
|
||||||
// found end of this word
|
build.TimeBuilt = epoch.AddSeconds( rawTime ).ToLocalTime();
|
||||||
if( wordEnd == -1 )
|
|
||||||
wordEnd = index;
|
|
||||||
} else {
|
|
||||||
// found start of next word
|
|
||||||
if( wordEnd != -1 )
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if( wordEnd == -1 )
|
build.DirectXSize = Int32.Parse( (string)obj["dx_size"] );
|
||||||
wordEnd = value.Length;
|
build.DirectXPath = (string)obj["dx_file"];
|
||||||
return value.Substring( start, wordEnd - start );
|
build.OpenGLSize = Int32.Parse( (string)obj["ogl_size"] );
|
||||||
|
build.OpenGLPath = (string)obj["ogl_file"];
|
||||||
|
return build;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
Loading…
x
Reference in New Issue
Block a user