diff --git a/ClassicalSharp/2D/Screens/ChatScreen.cs b/ClassicalSharp/2D/Screens/ChatScreen.cs
index 05bf7cf51..f8fcf34ad 100644
--- a/ClassicalSharp/2D/Screens/ChatScreen.cs
+++ b/ClassicalSharp/2D/Screens/ChatScreen.cs
@@ -127,14 +127,14 @@ namespace ClassicalSharp.Gui.Screens {
int lastDownloadStatus = int.MinValue;
StringBuffer lastDownload = new StringBuffer(48);
void CheckOtherStatuses() {
- Request item = game.AsyncDownloader.CurrentItem;
+ Request item = game.Downloader.CurrentItem;
if (item == null || !(item.Identifier == "terrain" || item.Identifier == "texturePack")) {
if (status.Textures[1].IsValid) status.SetText(1, null);
lastDownloadStatus = int.MinValue;
return;
}
- int progress = game.AsyncDownloader.CurrentItemProgress;
+ int progress = game.Downloader.CurrentItemProgress;
if (progress == lastDownloadStatus) return;
lastDownloadStatus = progress;
SetFetchStatus(progress);
diff --git a/ClassicalSharp/Entities/Components/ShadowComponent.cs b/ClassicalSharp/Entities/Components/ShadowComponent.cs
index 1ac3b711c..c4d0ef751 100644
--- a/ClassicalSharp/Entities/Components/ShadowComponent.cs
+++ b/ClassicalSharp/Entities/Components/ShadowComponent.cs
@@ -221,7 +221,7 @@ namespace ClassicalSharp.Entities {
row[x] = dist < half * half ? inPix : outPix;
}
}
- shadowTex = gfx.CreateTexture(fastBmp, true, false);
+ shadowTex = gfx.CreateTexture(fastBmp, false, false);
}
}
}
diff --git a/ClassicalSharp/Entities/EntityList.cs b/ClassicalSharp/Entities/EntityList.cs
index 5b762da74..21820a4dc 100644
--- a/ClassicalSharp/Entities/EntityList.cs
+++ b/ClassicalSharp/Entities/EntityList.cs
@@ -111,6 +111,7 @@ namespace ClassicalSharp.Entities {
if (List[i] == null) continue;
List[i].ContextLost();
}
+ game.Graphics.DeleteTexture(ref ShadowComponent.shadowTex);
}
void ContextRecreated() {
diff --git a/ClassicalSharp/Entities/Player.cs b/ClassicalSharp/Entities/Player.cs
index 03573ad8e..875969a80 100644
--- a/ClassicalSharp/Entities/Player.cs
+++ b/ClassicalSharp/Entities/Player.cs
@@ -112,7 +112,7 @@ namespace ClassicalSharp.Entities {
if (!fetchedSkin && Model.UsesSkin) {
Player first = FirstOtherWithSameSkinAndFetchedSkin();
if (first == null) {
- game.AsyncDownloader.DownloadSkin(SkinName, SkinName);
+ game.Downloader.AsyncGetSkin(SkinName, SkinName);
} else {
ApplySkin(first);
}
@@ -120,7 +120,7 @@ namespace ClassicalSharp.Entities {
}
Request item;
- if (!game.AsyncDownloader.TryGetItem(SkinName, out item)) return;
+ if (!game.Downloader.TryGetItem(SkinName, out item)) return;
if (item == null || item.Data == null) { SetSkinAll(true); return; }
Bitmap bmp = (Bitmap)item.Data;
diff --git a/ClassicalSharp/Game/Game.Init.cs b/ClassicalSharp/Game/Game.Init.cs
index 1b6dd707f..3f1044c32 100644
--- a/ClassicalSharp/Game/Game.Init.cs
+++ b/ClassicalSharp/Game/Game.Init.cs
@@ -73,7 +73,7 @@ namespace ClassicalSharp {
BlockInfo.Init();
ModelCache = new ModelCache(this);
ModelCache.InitCache();
- AsyncDownloader = new AsyncDownloader(Drawer2D); Components.Add(AsyncDownloader);
+ Downloader = new AsyncDownloader(Drawer2D); Components.Add(Downloader);
Lighting = new BasicLighting(); Components.Add(Lighting);
Drawer2D.UseBitmappedChat = ClassicMode || !Options.GetBool(OptionsKey.UseChatFont, false);
@@ -225,7 +225,7 @@ namespace ClassicalSharp {
const double defTicks = 1.0 / 20;
const double netTicks = 1.0 / 60;
- AddScheduledTask(30, AsyncDownloader.PurgeOldEntriesTask);
+ AddScheduledTask(30, Downloader.PurgeOldEntriesTask);
AddScheduledTask(netTicks, Server.Tick);
entTask = AddScheduledTask(defTicks, Entities.Tick);
diff --git a/ClassicalSharp/Game/Game.Properties.cs b/ClassicalSharp/Game/Game.Properties.cs
index 7d70a7414..af79aa4f9 100644
--- a/ClassicalSharp/Game/Game.Properties.cs
+++ b/ClassicalSharp/Game/Game.Properties.cs
@@ -164,7 +164,7 @@ namespace ClassicalSharp {
public int Vertices;
public FrustumCulling Culling;
- public AsyncDownloader AsyncDownloader;
+ public AsyncDownloader Downloader;
/// How sensitive the client is to changes in the player's mouse position.
public int MouseSensitivity = 30;
diff --git a/ClassicalSharp/Network/IServerConnection.cs b/ClassicalSharp/Network/IServerConnection.cs
index 6db5371fa..d18d3b582 100644
--- a/ClassicalSharp/Network/IServerConnection.cs
+++ b/ClassicalSharp/Network/IServerConnection.cs
@@ -65,7 +65,7 @@ namespace ClassicalSharp {
protected void WarningScreenTick(Overlay warning) {
string identifier = warning.Metadata;
Request item;
- if (!game.AsyncDownloader.TryGetItem(identifier, out item) || item.Data == null) return;
+ if (!game.Downloader.TryGetItem(identifier, out item) || item.Data == null) return;
long contentLength = (long)item.Data;
if (contentLength <= 0) return;
@@ -78,7 +78,7 @@ namespace ClassicalSharp {
protected internal void RetrieveTexturePack(string url) {
if (!game.AcceptedUrls.HasEntry(url) && !game.DeniedUrls.HasEntry(url)) {
- game.AsyncDownloader.RetrieveContentLength(url, true, "CL_" + url);
+ game.Downloader.AsyncGetContentLength(url, true, "CL_" + url);
string address = url;
if (url.StartsWith("https://")) address = url.Substring(8);
if (url.StartsWith("http://")) address = url.Substring(7);
@@ -120,20 +120,18 @@ namespace ClassicalSharp {
TexturePack.ExtractCurrent(game, url);
if (url.Contains(".zip")) {
- game.AsyncDownloader.DownloadData(url, true, "texturePack",
- lastModified, etag);
+ game.Downloader.AsyncGetData(url, true, "texturePack", lastModified, etag);
} else {
- game.AsyncDownloader.DownloadImage(url, true, "terrain",
- lastModified, etag);
+ game.Downloader.AsyncGetImage(url, true, "terrain", lastModified, etag);
}
}
protected void CheckAsyncResources() {
Request item;
- if (game.AsyncDownloader.TryGetItem("terrain", out item)) {
+ if (game.Downloader.TryGetItem("terrain", out item)) {
TexturePack.ExtractTerrainPng(game, item);
}
- if (game.AsyncDownloader.TryGetItem("texturePack", out item)) {
+ if (game.Downloader.TryGetItem("texturePack", out item)) {
TexturePack.ExtractTexturePack(game, item);
}
}
diff --git a/ClassicalSharp/Network/Protocols/WoM.cs b/ClassicalSharp/Network/Protocols/WoM.cs
index 9d44e6e9b..0786b83f2 100644
--- a/ClassicalSharp/Network/Protocols/WoM.cs
+++ b/ClassicalSharp/Network/Protocols/WoM.cs
@@ -17,7 +17,7 @@ namespace ClassicalSharp.Network.Protocols {
public override void Tick() {
Request item;
- game.AsyncDownloader.TryGetItem(womEnvIdentifier, out item);
+ game.Downloader.TryGetItem(womEnvIdentifier, out item);
if (item != null && item.Data != null) {
ParseWomConfig((string)item.Data);
}
@@ -37,7 +37,7 @@ namespace ClassicalSharp.Network.Protocols {
// new world if the async 'get request' didn't complete before the new world was loaded.
womCounter++;
womEnvIdentifier = "womenv_" + womCounter;
- game.AsyncDownloader.DownloadPage(url, true, womEnvIdentifier);
+ game.Downloader.AsyncGetString(url, true, womEnvIdentifier);
sendWomId = true;
}
diff --git a/ClassicalSharp/Network/Utils/AsyncDownloader.cs b/ClassicalSharp/Network/Utils/AsyncDownloader.cs
index 67a8f0b5e..74d92cc13 100644
--- a/ClassicalSharp/Network/Utils/AsyncDownloader.cs
+++ b/ClassicalSharp/Network/Utils/AsyncDownloader.cs
@@ -33,6 +33,7 @@ namespace ClassicalSharp.Network {
public int CurrentItemProgress = -3;
public IDrawer2D Drawer;
public CookieContainer Cookies;
+ public bool KeepAlive;
public AsyncDownloader(IDrawer2D drawer) { this.drawer = drawer; }
#if !LAUNCHER
@@ -63,59 +64,73 @@ namespace ClassicalSharp.Network {
/// Asynchronously downloads a skin. If 'skinName' points to the url then the skin is
/// downloaded from that url, otherwise it is downloaded from the url 'defaultSkinServer'/'skinName'.png
/// Identifier is skin_'skinName'.
- public void DownloadSkin(string identifier, string skinName) {
- string strippedSkinName = Utils.StripColours(skinName);
- string url = Utils.IsUrlPrefix(skinName, 0) ? skinName :
- skinServer + strippedSkinName + ".png";
+ public void AsyncGetSkin(string identifier, string skinName) {
+ string url = Utils.IsUrlPrefix(skinName, 0) ? skinName
+ : skinServer + Utils.StripColours(skinName) + ".png";
+
AddRequest(url, false, identifier, RequestType.Bitmap,
- DateTime.MinValue , null);
+ DateTime.MinValue, null, null);
}
#endif
/// Asynchronously downloads a bitmap image from the specified url.
- public void DownloadImage(string url, bool priority, string identifier) {
+ public void AsyncGetImage(string url, bool priority, string identifier) {
AddRequest(url, priority, identifier, RequestType.Bitmap,
- DateTime.MinValue, null);
+ DateTime.MinValue, null, null);
}
/// Asynchronously downloads a string from the specified url.
- public void DownloadPage(string url, bool priority, string identifier) {
+ public void AsyncGetString(string url, bool priority, string identifier) {
AddRequest(url, priority, identifier, RequestType.String,
- DateTime.MinValue, null);
+ DateTime.MinValue, null, null);
}
/// Asynchronously downloads a byte array.
- public void DownloadData(string url, bool priority, string identifier) {
+ public void AsyncGetData(string url, bool priority, string identifier) {
AddRequest(url, priority, identifier, RequestType.ByteArray,
- DateTime.MinValue, null);
+ DateTime.MinValue, null, null);
}
/// Asynchronously downloads a bitmap image.
- public void DownloadImage(string url, bool priority, string identifier,
+ public void AsyncGetImage(string url, bool priority, string identifier,
DateTime lastModified, string etag) {
AddRequest(url, priority, identifier, RequestType.Bitmap,
- lastModified, etag);
+ lastModified, etag, null);
}
/// Asynchronously downloads a byte array.
- public void DownloadData(string url, bool priority, string identifier,
+ public void AsyncGetData(string url, bool priority, string identifier,
DateTime lastModified, string etag) {
AddRequest(url, priority, identifier, RequestType.ByteArray,
- lastModified, etag);
+ lastModified, etag, null);
}
#if !LAUNCHER
/// Asynchronously retrieves the content length of the body response.
- public void RetrieveContentLength(string url, bool priority, string identifier) {
+ public void AsyncGetContentLength(string url, bool priority, string identifier) {
AddRequest(url, priority, identifier, RequestType.ContentLength,
- DateTime.MinValue, null);
+ DateTime.MinValue, null, null);
+ }
+#else
+ /// Asynchronously retrieves the content length of the body response.
+ public void AsyncPostString(string url, bool priority, string identifier, string contents) {
+ AddRequest(url, priority, identifier, RequestType.String,
+ DateTime.MinValue, null, contents);
}
#endif
void AddRequest(string url, bool priority, string identifier,
- RequestType type, DateTime lastModified, string etag) {
+ RequestType type, DateTime lastModified, string etag, object data) {
lock (pendingLocker) {
- Request request = new Request(url, identifier, type, lastModified, etag);
+ Request request = new Request();
+ request.Url = url;
+ request.Identifier = identifier;
+ request.Type = type;
+ request.LastModified = lastModified;
+ request.ETag = etag;
+ request.Data = data;
+
+ request.TimeAdded = DateTime.UtcNow;
if (priority) {
pending.Insert(0, request);
} else {
@@ -208,7 +223,6 @@ namespace ClassicalSharp.Network {
string url = request.Url;
Utils.LogDebug("Downloading {0} from: {1}", request.Type, url);
HttpStatusCode status = HttpStatusCode.OK;
- request.Data = null;
try {
HttpWebRequest req = MakeRequest(request);
@@ -228,6 +242,7 @@ namespace ClassicalSharp.Network {
status = ((HttpWebResponse)webEx.Response).StatusCode;
webEx.Response.Close();
}
+ request.WebEx = webEx;
}
if (status != HttpStatusCode.OK) {
@@ -285,19 +300,31 @@ namespace ClassicalSharp.Network {
req.Proxy = null;
req.UserAgent = Program.AppName;
req.CookieContainer = Cookies;
+ req.KeepAlive = KeepAlive;
- if (request.LastModified != DateTime.MinValue)
+ if (request.LastModified != DateTime.MinValue) {
req.IfModifiedSince = request.LastModified;
- if (request.ETag != null)
+ }
+ if (request.ETag != null) {
req.Headers["If-None-Match"] = request.ETag;
+ }
+
+ if (request.Data != null) {
+ req.Method = "POST";
+ req.ContentType = "application/x-www-form-urlencoded; charset=UTF-8;";
+ byte[] encodedData = Encoding.UTF8.GetBytes((string)request.Data);
+ req.ContentLength = encodedData.Length;
+ using (Stream stream = req.GetRequestStream()) {
+ stream.Write(encodedData, 0, encodedData.Length);
+ }
+ }
return req;
}
static byte[] buffer = new byte[4096 * 8];
MemoryStream DownloadBytes(HttpWebResponse response) {
int length = (int)response.ContentLength;
- MemoryStream dst = length > 0 ?
- new MemoryStream(length) : new MemoryStream();
+ MemoryStream dst = length > 0 ? new MemoryStream(length) : new MemoryStream();
CurrentItemProgress = length > 0 ? 0 : -1;
using (Stream src = response.GetResponseStream()) {
@@ -335,14 +362,7 @@ namespace ClassicalSharp.Network {
/// ETag of the item most recently cached. (if any)
public string ETag;
- public Request(string url, string identifier, RequestType type, DateTime lastModified, string etag) {
- Url = url;
- Identifier = identifier;
- Type = type;
- TimeAdded = DateTime.UtcNow;
- LastModified = lastModified;
- ETag = etag;
- }
+ public WebException WebEx;
public void Dispose() {
Bitmap bmp = Data as Bitmap;
diff --git a/ClassicalSharp/Singleplayer/Server.cs b/ClassicalSharp/Singleplayer/Server.cs
index e82c38a13..8f4705516 100644
--- a/ClassicalSharp/Singleplayer/Server.cs
+++ b/ClassicalSharp/Singleplayer/Server.cs
@@ -31,8 +31,7 @@ namespace ClassicalSharp.Singleplayer {
BlockInfo.CanPlace[i] = true;
BlockInfo.CanDelete[i] = true;
}
- game.AsyncDownloader.DownloadSkin(game.LocalPlayer.SkinName,
- game.LocalPlayer.SkinName);
+ game.Downloader.AsyncGetSkin(game.LocalPlayer.SkinName, game.LocalPlayer.SkinName);
game.Events.RaiseBlockPermissionsChanged();
int seed = new Random().Next();
diff --git a/Launcher2/Gui/Screens/MainScreen.Classicube.cs b/Launcher2/Gui/Screens/MainScreen.Classicube.cs
index c9b7e8e49..97547d87a 100644
--- a/Launcher2/Gui/Screens/MainScreen.Classicube.cs
+++ b/Launcher2/Gui/Screens/MainScreen.Classicube.cs
@@ -6,9 +6,14 @@ using ClassicalSharp;
using Launcher.Gui.Widgets;
using Launcher.Web;
-namespace Launcher.Gui.Screens {
+namespace Launcher.Gui.Screens {
public sealed partial class MainScreen : InputScreen {
+ GetCSRFTokenTask getTask;
+ SignInTask postTask;
+ FetchServersTask fetchTask;
+ bool signingIn = false;
+
public override void Tick() {
base.Tick();
if (game.checkTask != null && game.checkTask.Completed && !updateDone) {
@@ -17,25 +22,71 @@ namespace Launcher.Gui.Screens {
else FailedUpdateCheck(game.checkTask);
updateDone = true;
}
-
if (!signingIn) return;
- ClassicubeSession session = game.Session;
- string status = session.Status;
- if (status != lastStatus)
- SetStatus(status);
- if (session.Working) return;
- if (session.Exception != null) {
- DisplayWebException(session.Exception, session.Status);
- } else if (HasServers) {
- game.SetScreen(new ServersScreen(game));
- return;
+ if (getTask != null) {
+ LoginGetTick();
+ } else if (postTask != null) {
+ LoginPostTick();
+ } else if (fetchTask != null) {
+ FetchTick();
+ }
+ }
+
+ void LoginGetTick() {
+ getTask.Tick();
+ if (!getTask.Completed) return;
+
+ if (getTask.Success) {
+ postTask = new SignInTask();
+ postTask.Username = Get(0);
+ postTask.Password = Get(1);
+ postTask.Token = getTask.Token;
+ postTask.RunAsync(game);
+ } else {
+ DisplayWebException(getTask.WebEx, "sign in");
}
- signingIn = false;
+ getTask = null;
game.RedrawBackground();
Resize();
}
+
+ void LoginPostTick() {
+ postTask.Tick();
+ if (!postTask.Completed) return;
+
+ if (postTask.Error != null) {
+ SetStatus("&c" + postTask.Error);
+ } else if (postTask.Success) {
+ game.Username = postTask.Username;
+ fetchTask = new FetchServersTask();
+ fetchTask.RunAsync(game);
+ SetStatus("&eRetrieving servers list..");
+ } else {
+ DisplayWebException(postTask.WebEx, "sign in");
+ }
+
+ postTask = null;
+ game.RedrawBackground();
+ Resize();
+ }
+
+ void FetchTick() {
+ fetchTask.Tick();
+ if (!fetchTask.Completed) return;
+
+ if (fetchTask.Success) {
+ game.Servers = fetchTask.Servers;
+ game.SetScreen(new ServersScreen(game));
+ } else {
+ DisplayWebException(fetchTask.WebEx, "retrieving servers list");
+ game.RedrawBackground();
+ Resize();
+ }
+
+ fetchTask = null;
+ }
string lastStatus;
void SetStatus(string text) {
@@ -47,12 +98,7 @@ namespace Launcher.Gui.Screens {
RedrawWidget(widget);
game.Dirty = true;
}
-
- bool HasServers {
- get { return game.Session.Servers != null && game.Session.Servers.Count != 0; }
- }
-
- bool signingIn;
+
void LoginAsync(int mouseX, int mouseY) {
if (String.IsNullOrEmpty(Get(0))) {
SetStatus("&eUsername required"); return;
@@ -60,7 +106,9 @@ namespace Launcher.Gui.Screens {
if (String.IsNullOrEmpty(Get(1))) {
SetStatus("&ePassword required"); return;
}
- if (signingIn) return;
+ if (getTask != null) return;
+
+ game.Username = Get(0);
UpdateSignInInfo(Get(0), Get(1));
CheckboxWidget skip = widgets[view.sslIndex] as CheckboxWidget;
@@ -71,9 +119,11 @@ namespace Launcher.Gui.Screens {
ServicePointManager.ServerCertificateValidationCallback = null;
}
- game.Session.LoginAsync(Get(0), Get(1));
+ getTask = new GetCSRFTokenTask();
+ getTask.RunAsync(game);
game.RedrawBackground();
Resize();
+
SetStatus("&eSigning in..");
signingIn = true;
}
@@ -82,6 +132,8 @@ namespace Launcher.Gui.Screens {
ErrorHandler.LogError(action, ex);
bool sslCertError = ex.Status == WebExceptionStatus.TrustFailure ||
(ex.Status == WebExceptionStatus.SendFailure && OpenTK.Configuration.RunningOnMono);
+ signingIn = false;
+
if (ex.Status == WebExceptionStatus.Timeout) {
string text = "&cTimed out when connecting to classicube.net.";
SetStatus(text);
@@ -162,8 +214,7 @@ namespace Launcher.Gui.Screens {
void UpdateSignInInfo(string user, string password) {
// If the client has changed some settings in the meantime, make sure we keep the changes
- if (!Options.Load())
- return;
+ if (!Options.Load()) return;
Options.Set("launcher-cc-username", user);
Options.Set("launcher-cc-password", Secure.Encode(password, user));
diff --git a/Launcher2/Gui/Screens/ServersScreen.cs b/Launcher2/Gui/Screens/ServersScreen.cs
index b129c3725..7d7aa2914 100644
--- a/Launcher2/Gui/Screens/ServersScreen.cs
+++ b/Launcher2/Gui/Screens/ServersScreen.cs
@@ -2,6 +2,7 @@
using System;
using System.Drawing;
using ClassicalSharp;
+using Launcher.Web;
using Launcher.Gui.Views;
using Launcher.Gui.Widgets;
using OpenTK.Input;
@@ -11,6 +12,7 @@ namespace Launcher.Gui.Screens {
const int tableX = 10, tableY = 50;
ServersView view;
+ FetchServersTask fetchTask;
public ServersScreen(LauncherWindow game) : base(game) {
enterIndex = 3;
@@ -20,7 +22,7 @@ namespace Launcher.Gui.Screens {
public override void Tick() {
base.Tick();
- if (fetchingList) CheckFetchStatus();
+ if (fetchTask != null) CheckFetchStatus();
TableWidget table = (TableWidget)widgets[view.tableIndex];
if (!game.Window.Mouse[MouseButton.Left]) {
@@ -134,12 +136,10 @@ namespace Launcher.Gui.Screens {
game.ConnectToServer(table.servers, Get(view.hashIndex));
}
- bool fetchingList = false;
void RefreshList(int mouseX, int mouseY) {
- if (fetchingList) return;
- fetchingList = true;
- game.Session.FetchServersAsync();
-
+ if (fetchTask != null) return;
+ fetchTask = new FetchServersTask();
+ fetchTask.RunAsync(game);
view.RefreshText = "&eWorking..";
Resize();
}
@@ -187,10 +187,12 @@ namespace Launcher.Gui.Screens {
}
void CheckFetchStatus() {
- if (!game.Session.Done) return;
- fetchingList = false;
-
- view.RefreshText = game.Session.Exception == null ? "Refresh" : "&cFailed";
+ fetchTask.Tick();
+ if (!fetchTask.Completed) return;
+ if (fetchTask.Success) game.Servers = fetchTask.Servers;
+
+ view.RefreshText = fetchTask.Success ? "Refresh" : "&cFailed";
+ fetchTask = null;
Resize();
// needed to ensure 'highlighted server hash' is over right entry after refresh
diff --git a/Launcher2/Gui/Screens/UpdatesScreen.cs b/Launcher2/Gui/Screens/UpdatesScreen.cs
index 6bd3dc240..aa53c69e7 100644
--- a/Launcher2/Gui/Screens/UpdatesScreen.cs
+++ b/Launcher2/Gui/Screens/UpdatesScreen.cs
@@ -34,7 +34,7 @@ namespace Launcher.Gui.Screens {
SuccessfulUpdateCheck(game.checkTask);
}
checkTask = new UpdateCheckTask();
- checkTask.Init(game);
+ checkTask.RunAsync(game);
}
Build dev, stable;
diff --git a/Launcher2/Gui/Views/ServersView.cs b/Launcher2/Gui/Views/ServersView.cs
index 0d4f0e7ec..2b8492afe 100644
--- a/Launcher2/Gui/Views/ServersView.cs
+++ b/Launcher2/Gui/Views/ServersView.cs
@@ -79,7 +79,7 @@ namespace Launcher.Gui.Views {
TableWidget widget;
if (widgets[tableIndex] != null) {
widget = (TableWidget)widgets[tableIndex];
- if (widget.servers != game.Session.Servers) ResetTable(widget);
+ if (widget.servers != game.Servers) ResetTable(widget);
} else {
widget = new TableWidget(game);
ResetTable(widget);
@@ -91,7 +91,7 @@ namespace Launcher.Gui.Views {
}
void ResetTable(TableWidget widget) {
- widget.SetEntries(game.Session.Servers);
+ widget.SetEntries(game.Servers);
widget.SetDrawData(drawer, tableFont, textFont,
Anchor.LeftOrTop, Anchor.LeftOrTop, tableX, tableY);
widget.SortDefault();
diff --git a/Launcher2/Launcher2.csproj b/Launcher2/Launcher2.csproj
index ac1bc004e..44f6a5e0a 100644
--- a/Launcher2/Launcher2.csproj
+++ b/Launcher2/Launcher2.csproj
@@ -145,15 +145,13 @@
+
-
-
-
@@ -173,7 +171,6 @@
-
\ No newline at end of file
diff --git a/Launcher2/LauncherWindow.cs b/Launcher2/LauncherWindow.cs
index e7aa81a96..68cb8ae9d 100644
--- a/Launcher2/LauncherWindow.cs
+++ b/Launcher2/LauncherWindow.cs
@@ -37,7 +37,7 @@ namespace Launcher {
public Rectangle DirtyArea;
/// Currently active logged in session with classicube.net.
- public ClassicubeSession Session = new ClassicubeSession();
+ public string Username;
/// Queue used to download resources asynchronously.
public AsyncDownloader Downloader;
@@ -55,6 +55,8 @@ namespace Launcher {
public bool ShouldExit;
public bool ShouldUpdate;
+ public List Servers = new List();
+
public string FontName = "Arial";
public bool Minimised {
@@ -136,7 +138,7 @@ namespace Launcher {
ServerListEntry entry = publicServers[i];
if (entry.Hash != hash) continue;
- data = new ClientStartData(Session.Username, entry.Mppass,
+ data = new ClientStartData(Username, entry.Mppass,
entry.IPAddress, entry.Port, entry.Name);
Client.Start(data, true, ref ShouldExit);
return true;
@@ -144,7 +146,14 @@ namespace Launcher {
// Fallback to private server handling
try {
- data = Session.GetConnectInfo(hash);
+ // TODO: Rewrite to be async
+ FetchServerTask task = new FetchServerTask(Username, hash);
+ task.RunAsync(this);
+
+ while (!task.Completed) { task.Tick(); Thread.Sleep(10); }
+ if (task.WebEx != null) throw task.WebEx;
+
+ data = task.Info;
} catch (WebException ex) {
ErrorHandler.LogError("retrieving server information", ex);
return false;
@@ -165,12 +174,15 @@ namespace Launcher {
platformDrawer.info = Window.WindowInfo;
platformDrawer.Init();
- fetcher = new ResourceFetcher();
- fetcher.CheckResourceExistence();
Downloader = new AsyncDownloader(Drawer);
Downloader.Init("");
+ Downloader.Cookies = new CookieContainer();
+ Downloader.KeepAlive = true;
+
+ fetcher = new ResourceFetcher();
+ fetcher.CheckResourceExistence();
checkTask = new UpdateCheckTask();
- checkTask.Init(this);
+ checkTask.RunAsync(this);
if (!fetcher.AllResourcesExist) {
SetScreen(new ResourcesScreen(this));
diff --git a/Launcher2/Patcher/ResourceFetcher.cs b/Launcher2/Patcher/ResourceFetcher.cs
index bd5b0966c..cd82f6123 100644
--- a/Launcher2/Patcher/ResourceFetcher.cs
+++ b/Launcher2/Patcher/ResourceFetcher.cs
@@ -15,7 +15,7 @@ namespace Launcher.Patcher {
public List FilesToDownload = new List();
public void QueueItem(string url, string identifier) {
- downloader.DownloadData(url, false, identifier);
+ downloader.AsyncGetData(url, false, identifier);
FilesToDownload.Add(identifier);
}
@@ -63,7 +63,7 @@ namespace Launcher.Patcher {
}
public void AddDownload(string url, string identifier) {
- downloader.DownloadData(url, false, identifier);
+ downloader.AsyncGetData(url, false, identifier);
}
diff --git a/Launcher2/Updater/Applier.cs b/Launcher2/Updater/Applier.cs
index 9aedbb7bd..c9936de3d 100644
--- a/Launcher2/Updater/Applier.cs
+++ b/Launcher2/Updater/Applier.cs
@@ -4,21 +4,21 @@ using System.Diagnostics;
using System.IO;
using System.Net;
using System.Runtime.InteropServices;
-using System.Threading;
using ClassicalSharp;
using ClassicalSharp.Textures;
-using Launcher.Web;
namespace Launcher.Updater {
public static class Applier {
public static DateTime PatchTime;
+ public const string UpdatesUri = "http://cs.classicube.net/";
public static void FetchUpdate(string dir) {
WebRequest.DefaultWebProxy = null;
+ // TODO: Rewrite to be async
using (WebClient client = new WebClient()) {
- byte[] zipData = client.DownloadData(UpdateCheckTask.UpdatesUri + dir);
+ byte[] zipData = client.DownloadData(UpdatesUri + dir);
MakeUpdatesFolder(zipData);
}
}
diff --git a/Launcher2/WebService/ClassiCubeSession.cs b/Launcher2/WebService/ClassiCubeSession.cs
deleted file mode 100644
index 9a0377f09..000000000
--- a/Launcher2/WebService/ClassiCubeSession.cs
+++ /dev/null
@@ -1,161 +0,0 @@
-// ClassicalSharp copyright 2014-2016 UnknownShadow200 | Licensed under MIT
-using System;
-using System.Collections.Generic;
-using System.Net;
-using System.Threading;
-using JsonObject = System.Collections.Generic.Dictionary;
-
-namespace Launcher.Web {
-
- public class ServerListEntry {
- public string Hash, Name, Players, MaxPlayers;
- public string Uptime, IPAddress, Port, Mppass, Software;
- public bool Featured;
- }
-
- public sealed class ClassicubeSession : IWebTask {
-
- const string classicubeNetUri = "https://www.classicube.net/",
- loginUri = "https://www.classicube.net/api/login/",
- listUri = "https://www.classicube.net/api/servers",
- serverUri = "https://www.classicube.net/api/server/";
-
- public List Servers = new List();
-
- public void LoginAsync(string user, string password) {
- Username = user;
- Status = "&eSigning in..";
- Servers = new List();
-
- BeginWorking();
- Thread thread = new Thread(LoginWorker, 256 * 1024);
- thread.Name = "Launcher.CCLoginAsync";
- thread.Start(password);
- }
-
- public void FetchServersAsync() {
- BeginWorking();
- Thread thread = new Thread(FetchServersWorker, 256 * 1024);
- thread.Name = "Launcher.CCFetchAsync";
- thread.Start();
- }
-
- 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, "&c" + ex.Message); return;
- }
-
- FetchServersWorker();
- if (!Success) Servers = new List();
- }
-
- void FetchServersWorker() {
- // Retrieve list of public servers
- Status = "&eRetrieving public servers list..";
- try {
- Servers = GetPublicServers();
- } catch (WebException ex) {
- Finish(false, ex, "retrieving servers list"); return;
- }
- Finish(true, null, "&eFetched list");
- }
-
-
- void Login(string user, string password) {
- Username = user;
-
- // Step 1: GET csrf token from login page.
- DateTime start = DateTime.UtcNow;
- string getResponse = Get(loginUri, classicubeNetUri);
- int index = 0; bool success = true;
- JsonObject data = (JsonObject)Json.ParseValue(getResponse, ref index, ref success);
- string token = (string)data["token"];
- DateTime end = DateTime.UtcNow;
- Log("cc login took " + (end - start).TotalMilliseconds);
-
- // Step 2: POST to login page with csrf token.
- string loginData = String.Format(
- "username={0}&password={1}&token={2}",
- Uri.EscapeDataString(user),
- Uri.EscapeDataString(password),
- Uri.EscapeDataString(token)
- );
-
- start = DateTime.UtcNow;
- string response = Post(loginUri, loginUri, loginData);
- index = 0; success = true;
- data = (JsonObject)Json.ParseValue(response, ref index, ref success);
- end = DateTime.UtcNow;
- Log("cc login took " + (end - start).TotalMilliseconds);
-
- string err = GetLoginError(data);
- if (err != null) throw new InvalidOperationException(err);
- Username = (string)data["username"];
- }
-
- static string GetLoginError(JsonObject obj) {
- List