mirror of
https://github.com/ClassiCube/ClassiCube.git
synced 2025-09-18 03:55:19 -04:00
Rewrite launcher web tasks to use asyncdownloader
This commit is contained in:
parent
fd5427edb4
commit
2b3fb48f54
@ -127,14 +127,14 @@ namespace ClassicalSharp.Gui.Screens {
|
|||||||
int lastDownloadStatus = int.MinValue;
|
int lastDownloadStatus = int.MinValue;
|
||||||
StringBuffer lastDownload = new StringBuffer(48);
|
StringBuffer lastDownload = new StringBuffer(48);
|
||||||
void CheckOtherStatuses() {
|
void CheckOtherStatuses() {
|
||||||
Request item = game.AsyncDownloader.CurrentItem;
|
Request item = game.Downloader.CurrentItem;
|
||||||
if (item == null || !(item.Identifier == "terrain" || item.Identifier == "texturePack")) {
|
if (item == null || !(item.Identifier == "terrain" || item.Identifier == "texturePack")) {
|
||||||
if (status.Textures[1].IsValid) status.SetText(1, null);
|
if (status.Textures[1].IsValid) status.SetText(1, null);
|
||||||
lastDownloadStatus = int.MinValue;
|
lastDownloadStatus = int.MinValue;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
int progress = game.AsyncDownloader.CurrentItemProgress;
|
int progress = game.Downloader.CurrentItemProgress;
|
||||||
if (progress == lastDownloadStatus) return;
|
if (progress == lastDownloadStatus) return;
|
||||||
lastDownloadStatus = progress;
|
lastDownloadStatus = progress;
|
||||||
SetFetchStatus(progress);
|
SetFetchStatus(progress);
|
||||||
|
@ -221,7 +221,7 @@ namespace ClassicalSharp.Entities {
|
|||||||
row[x] = dist < half * half ? inPix : outPix;
|
row[x] = dist < half * half ? inPix : outPix;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
shadowTex = gfx.CreateTexture(fastBmp, true, false);
|
shadowTex = gfx.CreateTexture(fastBmp, false, false);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -111,6 +111,7 @@ namespace ClassicalSharp.Entities {
|
|||||||
if (List[i] == null) continue;
|
if (List[i] == null) continue;
|
||||||
List[i].ContextLost();
|
List[i].ContextLost();
|
||||||
}
|
}
|
||||||
|
game.Graphics.DeleteTexture(ref ShadowComponent.shadowTex);
|
||||||
}
|
}
|
||||||
|
|
||||||
void ContextRecreated() {
|
void ContextRecreated() {
|
||||||
|
@ -112,7 +112,7 @@ namespace ClassicalSharp.Entities {
|
|||||||
if (!fetchedSkin && Model.UsesSkin) {
|
if (!fetchedSkin && Model.UsesSkin) {
|
||||||
Player first = FirstOtherWithSameSkinAndFetchedSkin();
|
Player first = FirstOtherWithSameSkinAndFetchedSkin();
|
||||||
if (first == null) {
|
if (first == null) {
|
||||||
game.AsyncDownloader.DownloadSkin(SkinName, SkinName);
|
game.Downloader.AsyncGetSkin(SkinName, SkinName);
|
||||||
} else {
|
} else {
|
||||||
ApplySkin(first);
|
ApplySkin(first);
|
||||||
}
|
}
|
||||||
@ -120,7 +120,7 @@ namespace ClassicalSharp.Entities {
|
|||||||
}
|
}
|
||||||
|
|
||||||
Request item;
|
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; }
|
if (item == null || item.Data == null) { SetSkinAll(true); return; }
|
||||||
|
|
||||||
Bitmap bmp = (Bitmap)item.Data;
|
Bitmap bmp = (Bitmap)item.Data;
|
||||||
|
@ -73,7 +73,7 @@ namespace ClassicalSharp {
|
|||||||
BlockInfo.Init();
|
BlockInfo.Init();
|
||||||
ModelCache = new ModelCache(this);
|
ModelCache = new ModelCache(this);
|
||||||
ModelCache.InitCache();
|
ModelCache.InitCache();
|
||||||
AsyncDownloader = new AsyncDownloader(Drawer2D); Components.Add(AsyncDownloader);
|
Downloader = new AsyncDownloader(Drawer2D); Components.Add(Downloader);
|
||||||
Lighting = new BasicLighting(); Components.Add(Lighting);
|
Lighting = new BasicLighting(); Components.Add(Lighting);
|
||||||
|
|
||||||
Drawer2D.UseBitmappedChat = ClassicMode || !Options.GetBool(OptionsKey.UseChatFont, false);
|
Drawer2D.UseBitmappedChat = ClassicMode || !Options.GetBool(OptionsKey.UseChatFont, false);
|
||||||
@ -225,7 +225,7 @@ namespace ClassicalSharp {
|
|||||||
const double defTicks = 1.0 / 20;
|
const double defTicks = 1.0 / 20;
|
||||||
const double netTicks = 1.0 / 60;
|
const double netTicks = 1.0 / 60;
|
||||||
|
|
||||||
AddScheduledTask(30, AsyncDownloader.PurgeOldEntriesTask);
|
AddScheduledTask(30, Downloader.PurgeOldEntriesTask);
|
||||||
AddScheduledTask(netTicks, Server.Tick);
|
AddScheduledTask(netTicks, Server.Tick);
|
||||||
entTask = AddScheduledTask(defTicks, Entities.Tick);
|
entTask = AddScheduledTask(defTicks, Entities.Tick);
|
||||||
|
|
||||||
|
@ -164,7 +164,7 @@ namespace ClassicalSharp {
|
|||||||
|
|
||||||
public int Vertices;
|
public int Vertices;
|
||||||
public FrustumCulling Culling;
|
public FrustumCulling Culling;
|
||||||
public AsyncDownloader AsyncDownloader;
|
public AsyncDownloader Downloader;
|
||||||
|
|
||||||
/// <summary> How sensitive the client is to changes in the player's mouse position. </summary>
|
/// <summary> How sensitive the client is to changes in the player's mouse position. </summary>
|
||||||
public int MouseSensitivity = 30;
|
public int MouseSensitivity = 30;
|
||||||
|
@ -65,7 +65,7 @@ namespace ClassicalSharp {
|
|||||||
protected void WarningScreenTick(Overlay warning) {
|
protected void WarningScreenTick(Overlay warning) {
|
||||||
string identifier = warning.Metadata;
|
string identifier = warning.Metadata;
|
||||||
Request item;
|
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;
|
long contentLength = (long)item.Data;
|
||||||
if (contentLength <= 0) return;
|
if (contentLength <= 0) return;
|
||||||
@ -78,7 +78,7 @@ namespace ClassicalSharp {
|
|||||||
|
|
||||||
protected internal void RetrieveTexturePack(string url) {
|
protected internal void RetrieveTexturePack(string url) {
|
||||||
if (!game.AcceptedUrls.HasEntry(url) && !game.DeniedUrls.HasEntry(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;
|
string address = url;
|
||||||
if (url.StartsWith("https://")) address = url.Substring(8);
|
if (url.StartsWith("https://")) address = url.Substring(8);
|
||||||
if (url.StartsWith("http://")) address = url.Substring(7);
|
if (url.StartsWith("http://")) address = url.Substring(7);
|
||||||
@ -120,20 +120,18 @@ namespace ClassicalSharp {
|
|||||||
|
|
||||||
TexturePack.ExtractCurrent(game, url);
|
TexturePack.ExtractCurrent(game, url);
|
||||||
if (url.Contains(".zip")) {
|
if (url.Contains(".zip")) {
|
||||||
game.AsyncDownloader.DownloadData(url, true, "texturePack",
|
game.Downloader.AsyncGetData(url, true, "texturePack", lastModified, etag);
|
||||||
lastModified, etag);
|
|
||||||
} else {
|
} else {
|
||||||
game.AsyncDownloader.DownloadImage(url, true, "terrain",
|
game.Downloader.AsyncGetImage(url, true, "terrain", lastModified, etag);
|
||||||
lastModified, etag);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
protected void CheckAsyncResources() {
|
protected void CheckAsyncResources() {
|
||||||
Request item;
|
Request item;
|
||||||
if (game.AsyncDownloader.TryGetItem("terrain", out item)) {
|
if (game.Downloader.TryGetItem("terrain", out item)) {
|
||||||
TexturePack.ExtractTerrainPng(game, item);
|
TexturePack.ExtractTerrainPng(game, item);
|
||||||
}
|
}
|
||||||
if (game.AsyncDownloader.TryGetItem("texturePack", out item)) {
|
if (game.Downloader.TryGetItem("texturePack", out item)) {
|
||||||
TexturePack.ExtractTexturePack(game, item);
|
TexturePack.ExtractTexturePack(game, item);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -17,7 +17,7 @@ namespace ClassicalSharp.Network.Protocols {
|
|||||||
|
|
||||||
public override void Tick() {
|
public override void Tick() {
|
||||||
Request item;
|
Request item;
|
||||||
game.AsyncDownloader.TryGetItem(womEnvIdentifier, out item);
|
game.Downloader.TryGetItem(womEnvIdentifier, out item);
|
||||||
if (item != null && item.Data != null) {
|
if (item != null && item.Data != null) {
|
||||||
ParseWomConfig((string)item.Data);
|
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.
|
// new world if the async 'get request' didn't complete before the new world was loaded.
|
||||||
womCounter++;
|
womCounter++;
|
||||||
womEnvIdentifier = "womenv_" + womCounter;
|
womEnvIdentifier = "womenv_" + womCounter;
|
||||||
game.AsyncDownloader.DownloadPage(url, true, womEnvIdentifier);
|
game.Downloader.AsyncGetString(url, true, womEnvIdentifier);
|
||||||
sendWomId = true;
|
sendWomId = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -33,6 +33,7 @@ namespace ClassicalSharp.Network {
|
|||||||
public int CurrentItemProgress = -3;
|
public int CurrentItemProgress = -3;
|
||||||
public IDrawer2D Drawer;
|
public IDrawer2D Drawer;
|
||||||
public CookieContainer Cookies;
|
public CookieContainer Cookies;
|
||||||
|
public bool KeepAlive;
|
||||||
public AsyncDownloader(IDrawer2D drawer) { this.drawer = drawer; }
|
public AsyncDownloader(IDrawer2D drawer) { this.drawer = drawer; }
|
||||||
|
|
||||||
#if !LAUNCHER
|
#if !LAUNCHER
|
||||||
@ -63,59 +64,73 @@ namespace ClassicalSharp.Network {
|
|||||||
/// <summary> Asynchronously downloads a skin. If 'skinName' points to the url then the skin is
|
/// <summary> 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 </summary>
|
/// downloaded from that url, otherwise it is downloaded from the url 'defaultSkinServer'/'skinName'.png </summary>
|
||||||
/// <remarks> Identifier is skin_'skinName'.</remarks>
|
/// <remarks> Identifier is skin_'skinName'.</remarks>
|
||||||
public void DownloadSkin(string identifier, string skinName) {
|
public void AsyncGetSkin(string identifier, string skinName) {
|
||||||
string strippedSkinName = Utils.StripColours(skinName);
|
string url = Utils.IsUrlPrefix(skinName, 0) ? skinName
|
||||||
string url = Utils.IsUrlPrefix(skinName, 0) ? skinName :
|
: skinServer + Utils.StripColours(skinName) + ".png";
|
||||||
skinServer + strippedSkinName + ".png";
|
|
||||||
AddRequest(url, false, identifier, RequestType.Bitmap,
|
AddRequest(url, false, identifier, RequestType.Bitmap,
|
||||||
DateTime.MinValue , null);
|
DateTime.MinValue, null, null);
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/// <summary> Asynchronously downloads a bitmap image from the specified url. </summary>
|
/// <summary> Asynchronously downloads a bitmap image from the specified url. </summary>
|
||||||
public void DownloadImage(string url, bool priority, string identifier) {
|
public void AsyncGetImage(string url, bool priority, string identifier) {
|
||||||
AddRequest(url, priority, identifier, RequestType.Bitmap,
|
AddRequest(url, priority, identifier, RequestType.Bitmap,
|
||||||
DateTime.MinValue, null);
|
DateTime.MinValue, null, null);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary> Asynchronously downloads a string from the specified url. </summary>
|
/// <summary> Asynchronously downloads a string from the specified url. </summary>
|
||||||
public void DownloadPage(string url, bool priority, string identifier) {
|
public void AsyncGetString(string url, bool priority, string identifier) {
|
||||||
AddRequest(url, priority, identifier, RequestType.String,
|
AddRequest(url, priority, identifier, RequestType.String,
|
||||||
DateTime.MinValue, null);
|
DateTime.MinValue, null, null);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary> Asynchronously downloads a byte array. </summary>
|
/// <summary> Asynchronously downloads a byte array. </summary>
|
||||||
public void DownloadData(string url, bool priority, string identifier) {
|
public void AsyncGetData(string url, bool priority, string identifier) {
|
||||||
AddRequest(url, priority, identifier, RequestType.ByteArray,
|
AddRequest(url, priority, identifier, RequestType.ByteArray,
|
||||||
DateTime.MinValue, null);
|
DateTime.MinValue, null, null);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary> Asynchronously downloads a bitmap image. </summary>
|
/// <summary> Asynchronously downloads a bitmap image. </summary>
|
||||||
public void DownloadImage(string url, bool priority, string identifier,
|
public void AsyncGetImage(string url, bool priority, string identifier,
|
||||||
DateTime lastModified, string etag) {
|
DateTime lastModified, string etag) {
|
||||||
AddRequest(url, priority, identifier, RequestType.Bitmap,
|
AddRequest(url, priority, identifier, RequestType.Bitmap,
|
||||||
lastModified, etag);
|
lastModified, etag, null);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary> Asynchronously downloads a byte array. </summary>
|
/// <summary> Asynchronously downloads a byte array. </summary>
|
||||||
public void DownloadData(string url, bool priority, string identifier,
|
public void AsyncGetData(string url, bool priority, string identifier,
|
||||||
DateTime lastModified, string etag) {
|
DateTime lastModified, string etag) {
|
||||||
AddRequest(url, priority, identifier, RequestType.ByteArray,
|
AddRequest(url, priority, identifier, RequestType.ByteArray,
|
||||||
lastModified, etag);
|
lastModified, etag, null);
|
||||||
}
|
}
|
||||||
|
|
||||||
#if !LAUNCHER
|
#if !LAUNCHER
|
||||||
/// <summary> Asynchronously retrieves the content length of the body response. </summary>
|
/// <summary> Asynchronously retrieves the content length of the body response. </summary>
|
||||||
public void RetrieveContentLength(string url, bool priority, string identifier) {
|
public void AsyncGetContentLength(string url, bool priority, string identifier) {
|
||||||
AddRequest(url, priority, identifier, RequestType.ContentLength,
|
AddRequest(url, priority, identifier, RequestType.ContentLength,
|
||||||
DateTime.MinValue, null);
|
DateTime.MinValue, null, null);
|
||||||
|
}
|
||||||
|
#else
|
||||||
|
/// <summary> Asynchronously retrieves the content length of the body response. </summary>
|
||||||
|
public void AsyncPostString(string url, bool priority, string identifier, string contents) {
|
||||||
|
AddRequest(url, priority, identifier, RequestType.String,
|
||||||
|
DateTime.MinValue, null, contents);
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
void AddRequest(string url, bool priority, string identifier,
|
void AddRequest(string url, bool priority, string identifier,
|
||||||
RequestType type, DateTime lastModified, string etag) {
|
RequestType type, DateTime lastModified, string etag, object data) {
|
||||||
lock (pendingLocker) {
|
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) {
|
if (priority) {
|
||||||
pending.Insert(0, request);
|
pending.Insert(0, request);
|
||||||
} else {
|
} else {
|
||||||
@ -208,7 +223,6 @@ namespace ClassicalSharp.Network {
|
|||||||
string url = request.Url;
|
string url = request.Url;
|
||||||
Utils.LogDebug("Downloading {0} from: {1}", request.Type, url);
|
Utils.LogDebug("Downloading {0} from: {1}", request.Type, url);
|
||||||
HttpStatusCode status = HttpStatusCode.OK;
|
HttpStatusCode status = HttpStatusCode.OK;
|
||||||
request.Data = null;
|
|
||||||
|
|
||||||
try {
|
try {
|
||||||
HttpWebRequest req = MakeRequest(request);
|
HttpWebRequest req = MakeRequest(request);
|
||||||
@ -228,6 +242,7 @@ namespace ClassicalSharp.Network {
|
|||||||
status = ((HttpWebResponse)webEx.Response).StatusCode;
|
status = ((HttpWebResponse)webEx.Response).StatusCode;
|
||||||
webEx.Response.Close();
|
webEx.Response.Close();
|
||||||
}
|
}
|
||||||
|
request.WebEx = webEx;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (status != HttpStatusCode.OK) {
|
if (status != HttpStatusCode.OK) {
|
||||||
@ -285,19 +300,31 @@ namespace ClassicalSharp.Network {
|
|||||||
req.Proxy = null;
|
req.Proxy = null;
|
||||||
req.UserAgent = Program.AppName;
|
req.UserAgent = Program.AppName;
|
||||||
req.CookieContainer = Cookies;
|
req.CookieContainer = Cookies;
|
||||||
|
req.KeepAlive = KeepAlive;
|
||||||
|
|
||||||
if (request.LastModified != DateTime.MinValue)
|
if (request.LastModified != DateTime.MinValue) {
|
||||||
req.IfModifiedSince = request.LastModified;
|
req.IfModifiedSince = request.LastModified;
|
||||||
if (request.ETag != null)
|
}
|
||||||
|
if (request.ETag != null) {
|
||||||
req.Headers["If-None-Match"] = request.ETag;
|
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;
|
return req;
|
||||||
}
|
}
|
||||||
|
|
||||||
static byte[] buffer = new byte[4096 * 8];
|
static byte[] buffer = new byte[4096 * 8];
|
||||||
MemoryStream DownloadBytes(HttpWebResponse response) {
|
MemoryStream DownloadBytes(HttpWebResponse response) {
|
||||||
int length = (int)response.ContentLength;
|
int length = (int)response.ContentLength;
|
||||||
MemoryStream dst = length > 0 ?
|
MemoryStream dst = length > 0 ? new MemoryStream(length) : new MemoryStream();
|
||||||
new MemoryStream(length) : new MemoryStream();
|
|
||||||
CurrentItemProgress = length > 0 ? 0 : -1;
|
CurrentItemProgress = length > 0 ? 0 : -1;
|
||||||
|
|
||||||
using (Stream src = response.GetResponseStream()) {
|
using (Stream src = response.GetResponseStream()) {
|
||||||
@ -335,14 +362,7 @@ namespace ClassicalSharp.Network {
|
|||||||
/// <summary> ETag of the item most recently cached. (if any) </summary>
|
/// <summary> ETag of the item most recently cached. (if any) </summary>
|
||||||
public string ETag;
|
public string ETag;
|
||||||
|
|
||||||
public Request(string url, string identifier, RequestType type, DateTime lastModified, string etag) {
|
public WebException WebEx;
|
||||||
Url = url;
|
|
||||||
Identifier = identifier;
|
|
||||||
Type = type;
|
|
||||||
TimeAdded = DateTime.UtcNow;
|
|
||||||
LastModified = lastModified;
|
|
||||||
ETag = etag;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void Dispose() {
|
public void Dispose() {
|
||||||
Bitmap bmp = Data as Bitmap;
|
Bitmap bmp = Data as Bitmap;
|
||||||
|
@ -31,8 +31,7 @@ namespace ClassicalSharp.Singleplayer {
|
|||||||
BlockInfo.CanPlace[i] = true;
|
BlockInfo.CanPlace[i] = true;
|
||||||
BlockInfo.CanDelete[i] = true;
|
BlockInfo.CanDelete[i] = true;
|
||||||
}
|
}
|
||||||
game.AsyncDownloader.DownloadSkin(game.LocalPlayer.SkinName,
|
game.Downloader.AsyncGetSkin(game.LocalPlayer.SkinName, game.LocalPlayer.SkinName);
|
||||||
game.LocalPlayer.SkinName);
|
|
||||||
|
|
||||||
game.Events.RaiseBlockPermissionsChanged();
|
game.Events.RaiseBlockPermissionsChanged();
|
||||||
int seed = new Random().Next();
|
int seed = new Random().Next();
|
||||||
|
@ -6,9 +6,14 @@ using ClassicalSharp;
|
|||||||
using Launcher.Gui.Widgets;
|
using Launcher.Gui.Widgets;
|
||||||
using Launcher.Web;
|
using Launcher.Web;
|
||||||
|
|
||||||
namespace Launcher.Gui.Screens {
|
namespace Launcher.Gui.Screens {
|
||||||
public sealed partial class MainScreen : InputScreen {
|
public sealed partial class MainScreen : InputScreen {
|
||||||
|
|
||||||
|
GetCSRFTokenTask getTask;
|
||||||
|
SignInTask postTask;
|
||||||
|
FetchServersTask fetchTask;
|
||||||
|
bool signingIn = false;
|
||||||
|
|
||||||
public override void Tick() {
|
public override void Tick() {
|
||||||
base.Tick();
|
base.Tick();
|
||||||
if (game.checkTask != null && game.checkTask.Completed && !updateDone) {
|
if (game.checkTask != null && game.checkTask.Completed && !updateDone) {
|
||||||
@ -17,25 +22,71 @@ namespace Launcher.Gui.Screens {
|
|||||||
else FailedUpdateCheck(game.checkTask);
|
else FailedUpdateCheck(game.checkTask);
|
||||||
updateDone = true;
|
updateDone = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!signingIn) return;
|
if (!signingIn) return;
|
||||||
ClassicubeSession session = game.Session;
|
|
||||||
string status = session.Status;
|
|
||||||
if (status != lastStatus)
|
|
||||||
SetStatus(status);
|
|
||||||
|
|
||||||
if (session.Working) return;
|
if (getTask != null) {
|
||||||
if (session.Exception != null) {
|
LoginGetTick();
|
||||||
DisplayWebException(session.Exception, session.Status);
|
} else if (postTask != null) {
|
||||||
} else if (HasServers) {
|
LoginPostTick();
|
||||||
game.SetScreen(new ServersScreen(game));
|
} else if (fetchTask != null) {
|
||||||
return;
|
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();
|
game.RedrawBackground();
|
||||||
Resize();
|
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;
|
string lastStatus;
|
||||||
void SetStatus(string text) {
|
void SetStatus(string text) {
|
||||||
@ -47,12 +98,7 @@ namespace Launcher.Gui.Screens {
|
|||||||
RedrawWidget(widget);
|
RedrawWidget(widget);
|
||||||
game.Dirty = true;
|
game.Dirty = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool HasServers {
|
|
||||||
get { return game.Session.Servers != null && game.Session.Servers.Count != 0; }
|
|
||||||
}
|
|
||||||
|
|
||||||
bool signingIn;
|
|
||||||
void LoginAsync(int mouseX, int mouseY) {
|
void LoginAsync(int mouseX, int mouseY) {
|
||||||
if (String.IsNullOrEmpty(Get(0))) {
|
if (String.IsNullOrEmpty(Get(0))) {
|
||||||
SetStatus("&eUsername required"); return;
|
SetStatus("&eUsername required"); return;
|
||||||
@ -60,7 +106,9 @@ namespace Launcher.Gui.Screens {
|
|||||||
if (String.IsNullOrEmpty(Get(1))) {
|
if (String.IsNullOrEmpty(Get(1))) {
|
||||||
SetStatus("&ePassword required"); return;
|
SetStatus("&ePassword required"); return;
|
||||||
}
|
}
|
||||||
if (signingIn) return;
|
if (getTask != null) return;
|
||||||
|
|
||||||
|
game.Username = Get(0);
|
||||||
UpdateSignInInfo(Get(0), Get(1));
|
UpdateSignInInfo(Get(0), Get(1));
|
||||||
|
|
||||||
CheckboxWidget skip = widgets[view.sslIndex] as CheckboxWidget;
|
CheckboxWidget skip = widgets[view.sslIndex] as CheckboxWidget;
|
||||||
@ -71,9 +119,11 @@ namespace Launcher.Gui.Screens {
|
|||||||
ServicePointManager.ServerCertificateValidationCallback = null;
|
ServicePointManager.ServerCertificateValidationCallback = null;
|
||||||
}
|
}
|
||||||
|
|
||||||
game.Session.LoginAsync(Get(0), Get(1));
|
getTask = new GetCSRFTokenTask();
|
||||||
|
getTask.RunAsync(game);
|
||||||
game.RedrawBackground();
|
game.RedrawBackground();
|
||||||
Resize();
|
Resize();
|
||||||
|
|
||||||
SetStatus("&eSigning in..");
|
SetStatus("&eSigning in..");
|
||||||
signingIn = true;
|
signingIn = true;
|
||||||
}
|
}
|
||||||
@ -82,6 +132,8 @@ namespace Launcher.Gui.Screens {
|
|||||||
ErrorHandler.LogError(action, ex);
|
ErrorHandler.LogError(action, ex);
|
||||||
bool sslCertError = ex.Status == WebExceptionStatus.TrustFailure ||
|
bool sslCertError = ex.Status == WebExceptionStatus.TrustFailure ||
|
||||||
(ex.Status == WebExceptionStatus.SendFailure && OpenTK.Configuration.RunningOnMono);
|
(ex.Status == WebExceptionStatus.SendFailure && OpenTK.Configuration.RunningOnMono);
|
||||||
|
signingIn = false;
|
||||||
|
|
||||||
if (ex.Status == WebExceptionStatus.Timeout) {
|
if (ex.Status == WebExceptionStatus.Timeout) {
|
||||||
string text = "&cTimed out when connecting to classicube.net.";
|
string text = "&cTimed out when connecting to classicube.net.";
|
||||||
SetStatus(text);
|
SetStatus(text);
|
||||||
@ -162,8 +214,7 @@ namespace Launcher.Gui.Screens {
|
|||||||
|
|
||||||
void UpdateSignInInfo(string user, string password) {
|
void UpdateSignInInfo(string user, string password) {
|
||||||
// If the client has changed some settings in the meantime, make sure we keep the changes
|
// If the client has changed some settings in the meantime, make sure we keep the changes
|
||||||
if (!Options.Load())
|
if (!Options.Load()) return;
|
||||||
return;
|
|
||||||
|
|
||||||
Options.Set("launcher-cc-username", user);
|
Options.Set("launcher-cc-username", user);
|
||||||
Options.Set("launcher-cc-password", Secure.Encode(password, user));
|
Options.Set("launcher-cc-password", Secure.Encode(password, user));
|
||||||
|
@ -2,6 +2,7 @@
|
|||||||
using System;
|
using System;
|
||||||
using System.Drawing;
|
using System.Drawing;
|
||||||
using ClassicalSharp;
|
using ClassicalSharp;
|
||||||
|
using Launcher.Web;
|
||||||
using Launcher.Gui.Views;
|
using Launcher.Gui.Views;
|
||||||
using Launcher.Gui.Widgets;
|
using Launcher.Gui.Widgets;
|
||||||
using OpenTK.Input;
|
using OpenTK.Input;
|
||||||
@ -11,6 +12,7 @@ namespace Launcher.Gui.Screens {
|
|||||||
|
|
||||||
const int tableX = 10, tableY = 50;
|
const int tableX = 10, tableY = 50;
|
||||||
ServersView view;
|
ServersView view;
|
||||||
|
FetchServersTask fetchTask;
|
||||||
|
|
||||||
public ServersScreen(LauncherWindow game) : base(game) {
|
public ServersScreen(LauncherWindow game) : base(game) {
|
||||||
enterIndex = 3;
|
enterIndex = 3;
|
||||||
@ -20,7 +22,7 @@ namespace Launcher.Gui.Screens {
|
|||||||
|
|
||||||
public override void Tick() {
|
public override void Tick() {
|
||||||
base.Tick();
|
base.Tick();
|
||||||
if (fetchingList) CheckFetchStatus();
|
if (fetchTask != null) CheckFetchStatus();
|
||||||
|
|
||||||
TableWidget table = (TableWidget)widgets[view.tableIndex];
|
TableWidget table = (TableWidget)widgets[view.tableIndex];
|
||||||
if (!game.Window.Mouse[MouseButton.Left]) {
|
if (!game.Window.Mouse[MouseButton.Left]) {
|
||||||
@ -134,12 +136,10 @@ namespace Launcher.Gui.Screens {
|
|||||||
game.ConnectToServer(table.servers, Get(view.hashIndex));
|
game.ConnectToServer(table.servers, Get(view.hashIndex));
|
||||||
}
|
}
|
||||||
|
|
||||||
bool fetchingList = false;
|
|
||||||
void RefreshList(int mouseX, int mouseY) {
|
void RefreshList(int mouseX, int mouseY) {
|
||||||
if (fetchingList) return;
|
if (fetchTask != null) return;
|
||||||
fetchingList = true;
|
fetchTask = new FetchServersTask();
|
||||||
game.Session.FetchServersAsync();
|
fetchTask.RunAsync(game);
|
||||||
|
|
||||||
view.RefreshText = "&eWorking..";
|
view.RefreshText = "&eWorking..";
|
||||||
Resize();
|
Resize();
|
||||||
}
|
}
|
||||||
@ -187,10 +187,12 @@ namespace Launcher.Gui.Screens {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void CheckFetchStatus() {
|
void CheckFetchStatus() {
|
||||||
if (!game.Session.Done) return;
|
fetchTask.Tick();
|
||||||
fetchingList = false;
|
if (!fetchTask.Completed) return;
|
||||||
|
if (fetchTask.Success) game.Servers = fetchTask.Servers;
|
||||||
view.RefreshText = game.Session.Exception == null ? "Refresh" : "&cFailed";
|
|
||||||
|
view.RefreshText = fetchTask.Success ? "Refresh" : "&cFailed";
|
||||||
|
fetchTask = null;
|
||||||
Resize();
|
Resize();
|
||||||
|
|
||||||
// needed to ensure 'highlighted server hash' is over right entry after refresh
|
// needed to ensure 'highlighted server hash' is over right entry after refresh
|
||||||
|
@ -34,7 +34,7 @@ namespace Launcher.Gui.Screens {
|
|||||||
SuccessfulUpdateCheck(game.checkTask);
|
SuccessfulUpdateCheck(game.checkTask);
|
||||||
}
|
}
|
||||||
checkTask = new UpdateCheckTask();
|
checkTask = new UpdateCheckTask();
|
||||||
checkTask.Init(game);
|
checkTask.RunAsync(game);
|
||||||
}
|
}
|
||||||
|
|
||||||
Build dev, stable;
|
Build dev, stable;
|
||||||
|
@ -79,7 +79,7 @@ namespace Launcher.Gui.Views {
|
|||||||
TableWidget widget;
|
TableWidget widget;
|
||||||
if (widgets[tableIndex] != null) {
|
if (widgets[tableIndex] != null) {
|
||||||
widget = (TableWidget)widgets[tableIndex];
|
widget = (TableWidget)widgets[tableIndex];
|
||||||
if (widget.servers != game.Session.Servers) ResetTable(widget);
|
if (widget.servers != game.Servers) ResetTable(widget);
|
||||||
} else {
|
} else {
|
||||||
widget = new TableWidget(game);
|
widget = new TableWidget(game);
|
||||||
ResetTable(widget);
|
ResetTable(widget);
|
||||||
@ -91,7 +91,7 @@ namespace Launcher.Gui.Views {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void ResetTable(TableWidget widget) {
|
void ResetTable(TableWidget widget) {
|
||||||
widget.SetEntries(game.Session.Servers);
|
widget.SetEntries(game.Servers);
|
||||||
widget.SetDrawData(drawer, tableFont, textFont,
|
widget.SetDrawData(drawer, tableFont, textFont,
|
||||||
Anchor.LeftOrTop, Anchor.LeftOrTop, tableX, tableY);
|
Anchor.LeftOrTop, Anchor.LeftOrTop, tableX, tableY);
|
||||||
widget.SortDefault();
|
widget.SortDefault();
|
||||||
|
@ -145,15 +145,13 @@
|
|||||||
<Compile Include="Patcher\ZipWriter.cs" />
|
<Compile Include="Patcher\ZipWriter.cs" />
|
||||||
<Compile Include="Program.cs" />
|
<Compile Include="Program.cs" />
|
||||||
<Compile Include="Properties\AssemblyInfo.cs" />
|
<Compile Include="Properties\AssemblyInfo.cs" />
|
||||||
|
<Compile Include="WebTasks.cs" />
|
||||||
<Compile Include="Updater\Scripts.cs" />
|
<Compile Include="Updater\Scripts.cs" />
|
||||||
<Compile Include="Updater\Applier.cs" />
|
<Compile Include="Updater\Applier.cs" />
|
||||||
<Compile Include="Utils\Client.cs" />
|
<Compile Include="Utils\Client.cs" />
|
||||||
<Compile Include="Utils\JSON.cs" />
|
<Compile Include="Utils\JSON.cs" />
|
||||||
<Compile Include="Utils\LauncherSkin.cs" />
|
<Compile Include="Utils\LauncherSkin.cs" />
|
||||||
<Compile Include="Utils\Secure.cs" />
|
<Compile Include="Utils\Secure.cs" />
|
||||||
<Compile Include="WebService\ClassiCubeSession.cs" />
|
|
||||||
<Compile Include="WebService\IWebTask.cs" />
|
|
||||||
<Compile Include="WebService\UpdateCheckTask.cs" />
|
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<ProjectReference Include="..\OpenTK\OpenTK.csproj">
|
<ProjectReference Include="..\OpenTK\OpenTK.csproj">
|
||||||
@ -173,7 +171,6 @@
|
|||||||
<Folder Include="Updater" />
|
<Folder Include="Updater" />
|
||||||
<Folder Include="Utils" />
|
<Folder Include="Utils" />
|
||||||
<Folder Include="Patcher" />
|
<Folder Include="Patcher" />
|
||||||
<Folder Include="WebService" />
|
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<Import Project="$(MSBuildBinPath)\Microsoft.CSharp.Targets" />
|
<Import Project="$(MSBuildBinPath)\Microsoft.CSharp.Targets" />
|
||||||
</Project>
|
</Project>
|
@ -37,7 +37,7 @@ namespace Launcher {
|
|||||||
public Rectangle DirtyArea;
|
public Rectangle DirtyArea;
|
||||||
|
|
||||||
/// <summary> Currently active logged in session with classicube.net. </summary>
|
/// <summary> Currently active logged in session with classicube.net. </summary>
|
||||||
public ClassicubeSession Session = new ClassicubeSession();
|
public string Username;
|
||||||
|
|
||||||
/// <summary> Queue used to download resources asynchronously. </summary>
|
/// <summary> Queue used to download resources asynchronously. </summary>
|
||||||
public AsyncDownloader Downloader;
|
public AsyncDownloader Downloader;
|
||||||
@ -55,6 +55,8 @@ namespace Launcher {
|
|||||||
public bool ShouldExit;
|
public bool ShouldExit;
|
||||||
public bool ShouldUpdate;
|
public bool ShouldUpdate;
|
||||||
|
|
||||||
|
public List<ServerListEntry> Servers = new List<ServerListEntry>();
|
||||||
|
|
||||||
public string FontName = "Arial";
|
public string FontName = "Arial";
|
||||||
|
|
||||||
public bool Minimised {
|
public bool Minimised {
|
||||||
@ -136,7 +138,7 @@ namespace Launcher {
|
|||||||
ServerListEntry entry = publicServers[i];
|
ServerListEntry entry = publicServers[i];
|
||||||
if (entry.Hash != hash) continue;
|
if (entry.Hash != hash) continue;
|
||||||
|
|
||||||
data = new ClientStartData(Session.Username, entry.Mppass,
|
data = new ClientStartData(Username, entry.Mppass,
|
||||||
entry.IPAddress, entry.Port, entry.Name);
|
entry.IPAddress, entry.Port, entry.Name);
|
||||||
Client.Start(data, true, ref ShouldExit);
|
Client.Start(data, true, ref ShouldExit);
|
||||||
return true;
|
return true;
|
||||||
@ -144,7 +146,14 @@ namespace Launcher {
|
|||||||
|
|
||||||
// Fallback to private server handling
|
// Fallback to private server handling
|
||||||
try {
|
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) {
|
} catch (WebException ex) {
|
||||||
ErrorHandler.LogError("retrieving server information", ex);
|
ErrorHandler.LogError("retrieving server information", ex);
|
||||||
return false;
|
return false;
|
||||||
@ -165,12 +174,15 @@ namespace Launcher {
|
|||||||
platformDrawer.info = Window.WindowInfo;
|
platformDrawer.info = Window.WindowInfo;
|
||||||
platformDrawer.Init();
|
platformDrawer.Init();
|
||||||
|
|
||||||
fetcher = new ResourceFetcher();
|
|
||||||
fetcher.CheckResourceExistence();
|
|
||||||
Downloader = new AsyncDownloader(Drawer);
|
Downloader = new AsyncDownloader(Drawer);
|
||||||
Downloader.Init("");
|
Downloader.Init("");
|
||||||
|
Downloader.Cookies = new CookieContainer();
|
||||||
|
Downloader.KeepAlive = true;
|
||||||
|
|
||||||
|
fetcher = new ResourceFetcher();
|
||||||
|
fetcher.CheckResourceExistence();
|
||||||
checkTask = new UpdateCheckTask();
|
checkTask = new UpdateCheckTask();
|
||||||
checkTask.Init(this);
|
checkTask.RunAsync(this);
|
||||||
|
|
||||||
if (!fetcher.AllResourcesExist) {
|
if (!fetcher.AllResourcesExist) {
|
||||||
SetScreen(new ResourcesScreen(this));
|
SetScreen(new ResourcesScreen(this));
|
||||||
|
@ -15,7 +15,7 @@ namespace Launcher.Patcher {
|
|||||||
public List<string> FilesToDownload = new List<string>();
|
public List<string> FilesToDownload = new List<string>();
|
||||||
|
|
||||||
public void QueueItem(string url, string identifier) {
|
public void QueueItem(string url, string identifier) {
|
||||||
downloader.DownloadData(url, false, identifier);
|
downloader.AsyncGetData(url, false, identifier);
|
||||||
FilesToDownload.Add(identifier);
|
FilesToDownload.Add(identifier);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -63,7 +63,7 @@ namespace Launcher.Patcher {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public void AddDownload(string url, string identifier) {
|
public void AddDownload(string url, string identifier) {
|
||||||
downloader.DownloadData(url, false, identifier);
|
downloader.AsyncGetData(url, false, identifier);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -4,21 +4,21 @@ using System.Diagnostics;
|
|||||||
using System.IO;
|
using System.IO;
|
||||||
using System.Net;
|
using System.Net;
|
||||||
using System.Runtime.InteropServices;
|
using System.Runtime.InteropServices;
|
||||||
using System.Threading;
|
|
||||||
using ClassicalSharp;
|
using ClassicalSharp;
|
||||||
using ClassicalSharp.Textures;
|
using ClassicalSharp.Textures;
|
||||||
using Launcher.Web;
|
|
||||||
|
|
||||||
namespace Launcher.Updater {
|
namespace Launcher.Updater {
|
||||||
|
|
||||||
public static class Applier {
|
public static class Applier {
|
||||||
|
|
||||||
public static DateTime PatchTime;
|
public static DateTime PatchTime;
|
||||||
|
public const string UpdatesUri = "http://cs.classicube.net/";
|
||||||
|
|
||||||
public static void FetchUpdate(string dir) {
|
public static void FetchUpdate(string dir) {
|
||||||
WebRequest.DefaultWebProxy = null;
|
WebRequest.DefaultWebProxy = null;
|
||||||
|
// TODO: Rewrite to be async
|
||||||
using (WebClient client = new WebClient()) {
|
using (WebClient client = new WebClient()) {
|
||||||
byte[] zipData = client.DownloadData(UpdateCheckTask.UpdatesUri + dir);
|
byte[] zipData = client.DownloadData(UpdatesUri + dir);
|
||||||
MakeUpdatesFolder(zipData);
|
MakeUpdatesFolder(zipData);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -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<string, object>;
|
|
||||||
|
|
||||||
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<ServerListEntry> Servers = new List<ServerListEntry>();
|
|
||||||
|
|
||||||
public void LoginAsync(string user, string password) {
|
|
||||||
Username = user;
|
|
||||||
Status = "&eSigning in..";
|
|
||||||
Servers = new List<ServerListEntry>();
|
|
||||||
|
|
||||||
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<ServerListEntry>();
|
|
||||||
}
|
|
||||||
|
|
||||||
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<object> errors = (List<object>)obj["errors"];
|
|
||||||
if (errors.Count == 0) return null;
|
|
||||||
|
|
||||||
string err = (string)errors[0];
|
|
||||||
if (err == "username" || err == "password") return "Wrong username or password";
|
|
||||||
if (err == "verification") return "Account verification required";
|
|
||||||
return "Unknown error occurred";
|
|
||||||
}
|
|
||||||
|
|
||||||
ServerListEntry ParseEntry(JsonObject obj) {
|
|
||||||
ServerListEntry entry = new ServerListEntry();
|
|
||||||
entry.Hash = (string)obj["hash"];
|
|
||||||
entry.Name = (string)obj["name"];
|
|
||||||
entry.Players = (string)obj["players"];
|
|
||||||
entry.MaxPlayers = (string)obj["maxplayers"];
|
|
||||||
entry.Uptime = (string)obj["uptime"];
|
|
||||||
entry.Mppass = (string)obj["mppass"];
|
|
||||||
entry.IPAddress = (string)obj["ip"];
|
|
||||||
entry.Port = (string)obj["port"];
|
|
||||||
entry.Software = (string)obj["software"];
|
|
||||||
|
|
||||||
if (obj.ContainsKey("featured")) {
|
|
||||||
entry.Featured = (bool)obj["featured"];
|
|
||||||
}
|
|
||||||
return entry;
|
|
||||||
}
|
|
||||||
|
|
||||||
public ClientStartData GetConnectInfo(string hash) {
|
|
||||||
string uri = serverUri + hash;
|
|
||||||
string response = Get(uri, classicubeNetUri);
|
|
||||||
|
|
||||||
int index = 0; bool success = true;
|
|
||||||
JsonObject root = (JsonObject)Json.ParseValue(response, ref index, ref success);
|
|
||||||
List<object> list = (List<object>)root["servers"];
|
|
||||||
|
|
||||||
JsonObject obj = (JsonObject)list[0];
|
|
||||||
ServerListEntry entry = ParseEntry(obj);
|
|
||||||
return new ClientStartData(Username, entry.Mppass, entry.IPAddress, entry.Port, entry.Name);
|
|
||||||
}
|
|
||||||
|
|
||||||
public List<ServerListEntry> GetPublicServers() {
|
|
||||||
DateTime start = DateTime.UtcNow;
|
|
||||||
List<ServerListEntry> servers = new List<ServerListEntry>();
|
|
||||||
string response = Get(listUri, classicubeNetUri);
|
|
||||||
int index = 0; bool success = true;
|
|
||||||
JsonObject root = (JsonObject)Json.ParseValue(response, ref index, ref success);
|
|
||||||
List<object> list = (List<object>)root["servers"];
|
|
||||||
|
|
||||||
for (int i = 0; i < list.Count; i++) {
|
|
||||||
JsonObject obj = (JsonObject)list[i];
|
|
||||||
ServerListEntry entry = ParseEntry(obj);
|
|
||||||
servers.Add(entry);
|
|
||||||
}
|
|
||||||
|
|
||||||
DateTime end = DateTime.UtcNow;
|
|
||||||
Log("cc servers took " + (end - start).TotalMilliseconds);
|
|
||||||
return servers;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,99 +0,0 @@
|
|||||||
// ClassicalSharp copyright 2014-2016 UnknownShadow200 | Licensed under MIT
|
|
||||||
using System;
|
|
||||||
using System.Collections.Generic;
|
|
||||||
using System.IO;
|
|
||||||
using System.Net;
|
|
||||||
using System.Text;
|
|
||||||
using ClassicalSharp;
|
|
||||||
|
|
||||||
namespace Launcher.Web {
|
|
||||||
|
|
||||||
/// <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> Whether this web task has finished. </summary>
|
|
||||||
public bool Done;
|
|
||||||
|
|
||||||
/// <summary> Whether the web task finished with an error or not. </summary>
|
|
||||||
public bool Success;
|
|
||||||
|
|
||||||
/// <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;
|
|
||||||
|
|
||||||
/// <summary> Username used when performing GET or POST requests, can be left null. </summary>
|
|
||||||
public string Username;
|
|
||||||
|
|
||||||
public void BeginWorking() {
|
|
||||||
Working = true;
|
|
||||||
Done = false;
|
|
||||||
Exception = null;
|
|
||||||
}
|
|
||||||
|
|
||||||
protected void Finish(bool success, WebException ex, string status) {
|
|
||||||
if (!success)
|
|
||||||
Username = null;
|
|
||||||
Working = false;
|
|
||||||
Done = true;
|
|
||||||
Success = success;
|
|
||||||
|
|
||||||
Exception = ex;
|
|
||||||
Status = status;
|
|
||||||
}
|
|
||||||
|
|
||||||
protected CookieContainer cookies = new CookieContainer();
|
|
||||||
|
|
||||||
protected HttpWebResponse MakeRequest(string uri, string referer, string data) {
|
|
||||||
WebRequest.DefaultWebProxy = null;
|
|
||||||
HttpWebRequest request = (HttpWebRequest)WebRequest.Create(uri);
|
|
||||||
request.UserAgent = Program.AppName;
|
|
||||||
request.ReadWriteTimeout = 90 * 1000;
|
|
||||||
request.Timeout = 90 * 1000;
|
|
||||||
request.Referer = referer;
|
|
||||||
request.KeepAlive = true;
|
|
||||||
request.CookieContainer = cookies;
|
|
||||||
|
|
||||||
request.AutomaticDecompression = DecompressionMethods.GZip;
|
|
||||||
if (data != null) {
|
|
||||||
request.Method = "POST";
|
|
||||||
request.ContentType = "application/x-www-form-urlencoded; charset=UTF-8;";
|
|
||||||
byte[] encodedData = Encoding.UTF8.GetBytes(data);
|
|
||||||
request.ContentLength = encodedData.Length;
|
|
||||||
using (Stream stream = request.GetRequestStream()) {
|
|
||||||
stream.Write(encodedData, 0, encodedData.Length);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return (HttpWebResponse)request.GetResponse();
|
|
||||||
}
|
|
||||||
|
|
||||||
protected string Get(string uri, string referer) {
|
|
||||||
HttpWebResponse response = MakeRequest(uri, referer, null);
|
|
||||||
return GetResponse(response);
|
|
||||||
}
|
|
||||||
|
|
||||||
protected string Post(string uri, string referer, string data) {
|
|
||||||
HttpWebResponse response = MakeRequest(uri, referer, data);
|
|
||||||
return GetResponse(response);
|
|
||||||
}
|
|
||||||
|
|
||||||
protected string GetResponse(HttpWebResponse response) {
|
|
||||||
using (Stream stream = response.GetResponseStream()) {
|
|
||||||
using (StreamReader reader = new StreamReader(stream)) {
|
|
||||||
return reader.ReadToEnd();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
protected static void Log(string text) { Utils.LogDebug(text); }
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,79 +0,0 @@
|
|||||||
// ClassicalSharp copyright 2014-2016 UnknownShadow200 | Licensed under MIT
|
|
||||||
using ClassicalSharp;
|
|
||||||
using ClassicalSharp.Network;
|
|
||||||
using System;
|
|
||||||
using System.Collections.Generic;
|
|
||||||
using System.Globalization;
|
|
||||||
using JsonObject = System.Collections.Generic.Dictionary<string, object>;
|
|
||||||
|
|
||||||
namespace Launcher.Web {
|
|
||||||
|
|
||||||
public class Build {
|
|
||||||
public DateTime TimeBuilt;
|
|
||||||
public string DirectXPath, OpenGLPath;
|
|
||||||
public int DirectXSize, OpenGLSize;
|
|
||||||
public string Version;
|
|
||||||
}
|
|
||||||
|
|
||||||
public sealed class UpdateCheckTask {
|
|
||||||
|
|
||||||
public const string UpdatesIdentifier = "cc-update";
|
|
||||||
public const string UpdatesUri = "http://cs.classicube.net/";
|
|
||||||
public const string BuildsUri = "http://cs.classicube.net/builds.json";
|
|
||||||
public Build LatestDev, LatestStable;
|
|
||||||
public LauncherWindow Game;
|
|
||||||
public bool Completed = false, Success = false;
|
|
||||||
|
|
||||||
public void Init(LauncherWindow game) {
|
|
||||||
Game = game;
|
|
||||||
Completed = false;
|
|
||||||
Success = false;
|
|
||||||
Game.Downloader.DownloadPage(BuildsUri, false, UpdatesIdentifier);
|
|
||||||
}
|
|
||||||
|
|
||||||
public void Tick() {
|
|
||||||
if (Completed) return;
|
|
||||||
Request req;
|
|
||||||
if (!Game.Downloader.TryGetItem(UpdatesIdentifier, out req)) return;
|
|
||||||
|
|
||||||
Completed = true;
|
|
||||||
Success = req != null && req.Data != null;
|
|
||||||
if (!Success) return;
|
|
||||||
ProcessUpdate((string)req.Data);
|
|
||||||
}
|
|
||||||
|
|
||||||
void ProcessUpdate(string response) {
|
|
||||||
int index = 0; bool success = true;
|
|
||||||
JsonObject data = (JsonObject)Json.ParseValue(response, ref index, ref success);
|
|
||||||
|
|
||||||
JsonObject devBuild = (JsonObject)data["latest"];
|
|
||||||
JsonObject releaseBuilds = (JsonObject)data["releases"];
|
|
||||||
LatestDev = MakeBuild(devBuild, false);
|
|
||||||
|
|
||||||
DateTime releaseTime = DateTime.MinValue;
|
|
||||||
foreach (KeyValuePair<string, object> pair in releaseBuilds) {
|
|
||||||
Build build = MakeBuild((JsonObject)pair.Value, true);
|
|
||||||
if (build.TimeBuilt < releaseTime) continue;
|
|
||||||
|
|
||||||
LatestStable = build;
|
|
||||||
releaseTime = build.TimeBuilt;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static readonly DateTime epoch = new DateTime(1970, 1, 1, 0, 0, 0, DateTimeKind.Utc);
|
|
||||||
Build MakeBuild(JsonObject obj, bool release) {
|
|
||||||
Build build = new Build();
|
|
||||||
string timeKey = release ? "release_ts" : "ts";
|
|
||||||
double rawTime = Double.Parse((string)obj[timeKey], CultureInfo.InvariantCulture);
|
|
||||||
build.TimeBuilt = epoch.AddSeconds(rawTime).ToLocalTime();
|
|
||||||
|
|
||||||
build.DirectXSize = Int32.Parse((string)obj["dx_size"]);
|
|
||||||
build.DirectXPath = (string)obj["dx_file"];
|
|
||||||
build.OpenGLSize = Int32.Parse((string)obj["ogl_size"]);
|
|
||||||
build.OpenGLPath = (string)obj["ogl_file"];
|
|
||||||
if (obj.ContainsKey("version"))
|
|
||||||
build.Version = (string)obj["version"];
|
|
||||||
return build;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
219
Launcher2/WebTasks.cs
Normal file
219
Launcher2/WebTasks.cs
Normal file
@ -0,0 +1,219 @@
|
|||||||
|
// ClassicalSharp copyright 2014-2016 UnknownShadow200 | Licensed under MIT
|
||||||
|
using ClassicalSharp;
|
||||||
|
using ClassicalSharp.Network;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Globalization;
|
||||||
|
using System;
|
||||||
|
using System.Net;
|
||||||
|
using JsonObject = System.Collections.Generic.Dictionary<string, object>;
|
||||||
|
|
||||||
|
namespace Launcher.Web {
|
||||||
|
|
||||||
|
public abstract class WebTask {
|
||||||
|
public LauncherWindow Game;
|
||||||
|
public bool Completed = false, Success = false;
|
||||||
|
public WebException WebEx;
|
||||||
|
|
||||||
|
DateTime start;
|
||||||
|
protected string identifier, uri, section;
|
||||||
|
|
||||||
|
public void RunAsync(LauncherWindow game) {
|
||||||
|
Game = game; Completed = false; Success = false;
|
||||||
|
start = DateTime.UtcNow;
|
||||||
|
Init();
|
||||||
|
Begin();
|
||||||
|
}
|
||||||
|
|
||||||
|
public void Tick() {
|
||||||
|
if (Completed) return;
|
||||||
|
Request req;
|
||||||
|
if (!Game.Downloader.TryGetItem(identifier, out req)) return;
|
||||||
|
Utils.LogDebug(identifier + " took " + (DateTime.UtcNow - start).TotalMilliseconds);
|
||||||
|
|
||||||
|
WebEx = req.WebEx;
|
||||||
|
Completed = true;
|
||||||
|
Success = req != null && req.Data != null;
|
||||||
|
if (Success) Handle(req);
|
||||||
|
}
|
||||||
|
|
||||||
|
protected abstract void Init();
|
||||||
|
protected virtual void Begin() {
|
||||||
|
Game.Downloader.AsyncGetString(uri, false, identifier);
|
||||||
|
}
|
||||||
|
protected abstract void Handle(Request req);
|
||||||
|
}
|
||||||
|
|
||||||
|
public sealed class GetCSRFTokenTask : WebTask {
|
||||||
|
public GetCSRFTokenTask() {
|
||||||
|
identifier = "CC get login";
|
||||||
|
uri = "https://www.classicube.net/api/login/";
|
||||||
|
}
|
||||||
|
|
||||||
|
public string Token;
|
||||||
|
protected override void Init() { }
|
||||||
|
|
||||||
|
protected override void Handle(Request req) {
|
||||||
|
int index = 0; bool success = true;
|
||||||
|
JsonObject data = (JsonObject)Json.ParseValue((string)req.Data, ref index, ref success);
|
||||||
|
Token = (string)data["token"];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public sealed class SignInTask : WebTask {
|
||||||
|
public SignInTask() {
|
||||||
|
identifier = "CC post login";
|
||||||
|
uri = "https://www.classicube.net/api/login/";
|
||||||
|
}
|
||||||
|
|
||||||
|
public string Username, Password, Token, Error;
|
||||||
|
protected override void Init() { }
|
||||||
|
protected override void Begin() {
|
||||||
|
string data = String.Format(
|
||||||
|
"username={0}&password={1}&token={2}",
|
||||||
|
Uri.EscapeDataString(Username),
|
||||||
|
Uri.EscapeDataString(Password),
|
||||||
|
Uri.EscapeDataString(Token)
|
||||||
|
);
|
||||||
|
Game.Downloader.AsyncPostString(uri, false, identifier, data);
|
||||||
|
}
|
||||||
|
|
||||||
|
protected override void Handle(Request req) {
|
||||||
|
int index = 0; bool success = true;
|
||||||
|
JsonObject data = (JsonObject)Json.ParseValue((string)req.Data, ref index, ref success);
|
||||||
|
|
||||||
|
Error = GetLoginError(data);
|
||||||
|
Username = (string)data["username"];
|
||||||
|
}
|
||||||
|
|
||||||
|
static string GetLoginError(JsonObject obj) {
|
||||||
|
List<object> errors = (List<object>)obj["errors"];
|
||||||
|
if (errors.Count == 0) return null;
|
||||||
|
|
||||||
|
string err = (string)errors[0];
|
||||||
|
if (err == "username" || err == "password") return "Wrong username or password";
|
||||||
|
if (err == "verification") return "Account verification required";
|
||||||
|
return "Unknown error occurred";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public class ServerListEntry {
|
||||||
|
public string Hash, Name, Players, MaxPlayers;
|
||||||
|
public string Uptime, IPAddress, Port, Mppass, Software;
|
||||||
|
public bool Featured;
|
||||||
|
}
|
||||||
|
|
||||||
|
public sealed class FetchServerTask : WebTask {
|
||||||
|
public FetchServerTask(string user, string hash) {
|
||||||
|
Username = user;
|
||||||
|
identifier = "CC get servers";
|
||||||
|
uri = "https://www.classicube.net/api/server/" + hash;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static ServerListEntry ParseEntry(JsonObject obj) {
|
||||||
|
ServerListEntry entry = new ServerListEntry();
|
||||||
|
entry.Hash = (string)obj["hash"];
|
||||||
|
entry.Name = (string)obj["name"];
|
||||||
|
entry.Players = (string)obj["players"];
|
||||||
|
entry.MaxPlayers = (string)obj["maxplayers"];
|
||||||
|
entry.Uptime = (string)obj["uptime"];
|
||||||
|
entry.Mppass = (string)obj["mppass"];
|
||||||
|
entry.IPAddress = (string)obj["ip"];
|
||||||
|
entry.Port = (string)obj["port"];
|
||||||
|
entry.Software = (string)obj["software"];
|
||||||
|
|
||||||
|
if (obj.ContainsKey("featured")) {
|
||||||
|
entry.Featured = (bool)obj["featured"];
|
||||||
|
}
|
||||||
|
return entry;
|
||||||
|
}
|
||||||
|
|
||||||
|
public string Username;
|
||||||
|
public ClientStartData Info;
|
||||||
|
protected override void Init() { }
|
||||||
|
|
||||||
|
protected override void Handle(Request req) {
|
||||||
|
int index = 0; bool success = true;
|
||||||
|
JsonObject root = (JsonObject)Json.ParseValue((string)req.Data, ref index, ref success);
|
||||||
|
List<object> list = (List<object>)root["servers"];
|
||||||
|
|
||||||
|
JsonObject obj = (JsonObject)list[0];
|
||||||
|
ServerListEntry entry = ParseEntry(obj);
|
||||||
|
Info = new ClientStartData(Username, entry.Mppass, entry.IPAddress, entry.Port, entry.Name);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public sealed class FetchServersTask : WebTask {
|
||||||
|
public FetchServersTask() {
|
||||||
|
identifier = "CC get servers";
|
||||||
|
uri = "https://www.classicube.net/api/servers";
|
||||||
|
}
|
||||||
|
|
||||||
|
public List<ServerListEntry> Servers;
|
||||||
|
protected override void Init() {
|
||||||
|
Servers = new List<ServerListEntry>();
|
||||||
|
}
|
||||||
|
|
||||||
|
protected override void Handle(Request req) {
|
||||||
|
int index = 0; bool success = true;
|
||||||
|
JsonObject root = (JsonObject)Json.ParseValue((string)req.Data, ref index, ref success);
|
||||||
|
List<object> list = (List<object>)root["servers"];
|
||||||
|
|
||||||
|
for (int i = 0; i < list.Count; i++) {
|
||||||
|
JsonObject obj = (JsonObject)list[i];
|
||||||
|
ServerListEntry entry = FetchServerTask.ParseEntry(obj);
|
||||||
|
Servers.Add(entry);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public class Build {
|
||||||
|
public DateTime TimeBuilt;
|
||||||
|
public string DirectXPath, OpenGLPath;
|
||||||
|
public int DirectXSize, OpenGLSize;
|
||||||
|
public string Version;
|
||||||
|
}
|
||||||
|
|
||||||
|
public sealed class UpdateCheckTask : WebTask {
|
||||||
|
public UpdateCheckTask() {
|
||||||
|
identifier = "CC update check";
|
||||||
|
uri = "http://cs.classicube.net/builds.json";
|
||||||
|
}
|
||||||
|
|
||||||
|
public Build LatestDev, LatestStable;
|
||||||
|
protected override void Init() { }
|
||||||
|
|
||||||
|
protected override void Handle(Request req) {
|
||||||
|
int index = 0; bool success = true;
|
||||||
|
JsonObject data = (JsonObject)Json.ParseValue((string)req.Data, ref index, ref success);
|
||||||
|
JsonObject latest = (JsonObject)data["latest"], releases = (JsonObject)data["releases"];
|
||||||
|
LatestDev = MakeBuild(latest, false);
|
||||||
|
|
||||||
|
DateTime releaseTime = DateTime.MinValue;
|
||||||
|
foreach (KeyValuePair<string, object> pair in releases) {
|
||||||
|
Build build = MakeBuild((JsonObject)pair.Value, true);
|
||||||
|
if (build.TimeBuilt < releaseTime) continue;
|
||||||
|
|
||||||
|
LatestStable = build;
|
||||||
|
releaseTime = build.TimeBuilt;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static readonly DateTime epoch = new DateTime(1970, 1, 1, 0, 0, 0, DateTimeKind.Utc);
|
||||||
|
Build MakeBuild(JsonObject obj, bool release) {
|
||||||
|
Build build = new Build();
|
||||||
|
string timeKey = release ? "release_ts" : "ts";
|
||||||
|
double rawTime = Double.Parse((string)obj[timeKey], CultureInfo.InvariantCulture);
|
||||||
|
build.TimeBuilt = epoch.AddSeconds(rawTime).ToLocalTime();
|
||||||
|
|
||||||
|
build.DirectXSize = Int32.Parse((string)obj["dx_size"]);
|
||||||
|
build.DirectXPath = (string)obj["dx_file"];
|
||||||
|
build.OpenGLSize = Int32.Parse((string)obj["ogl_size"]);
|
||||||
|
build.OpenGLPath = (string)obj["ogl_file"];
|
||||||
|
if (obj.ContainsKey("version"))
|
||||||
|
build.Version = (string)obj["version"];
|
||||||
|
return build;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -292,6 +292,7 @@ void Entities_ContextLost(void) {
|
|||||||
if (Entities_List[i] == NULL) continue;
|
if (Entities_List[i] == NULL) continue;
|
||||||
Entities_List[i]->VTABLE->ContextLost(Entities_List[i]);
|
Entities_List[i]->VTABLE->ContextLost(Entities_List[i]);
|
||||||
}
|
}
|
||||||
|
Gfx_DeleteTexture(&ShadowComponent_ShadowTex);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Entities_ContextRecreated(void) {
|
void Entities_ContextRecreated(void) {
|
||||||
|
@ -595,7 +595,7 @@ void ShadowComponent_MakeTex(void) {
|
|||||||
row[x] = dist < half * half ? inPix : outPix;
|
row[x] = dist < half * half ? inPix : outPix;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
ShadowComponent_ShadowTex = Gfx_CreateTexture(&bmp, true, false);
|
ShadowComponent_ShadowTex = Gfx_CreateTexture(&bmp, false, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
void ShadowComponent_Draw(Entity* entity) {
|
void ShadowComponent_Draw(Entity* entity) {
|
||||||
|
@ -155,7 +155,7 @@ void Gfx_BindTexture(GfxResourceID texId) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void Gfx_DeleteTexture(GfxResourceID* texId) {
|
void Gfx_DeleteTexture(GfxResourceID* texId) {
|
||||||
if (*texId <= 0) return;
|
if (*texId == NULL) return;
|
||||||
glDeleteTextures(1, texId);
|
glDeleteTextures(1, texId);
|
||||||
*texId = NULL;
|
*texId = NULL;
|
||||||
}
|
}
|
||||||
@ -312,7 +312,7 @@ void Gfx_BindIb(GfxResourceID ib) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void Gfx_DeleteVb(GfxResourceID* vb) {
|
void Gfx_DeleteVb(GfxResourceID* vb) {
|
||||||
if (*vb <= 0) return;
|
if (*vb == NULL) return;
|
||||||
|
|
||||||
if (gl_lists) {
|
if (gl_lists) {
|
||||||
if (*vb != gl_DYNAMICLISTID) glDeleteLists(*vb, 1);
|
if (*vb != gl_DYNAMICLISTID) glDeleteLists(*vb, 1);
|
||||||
@ -323,7 +323,7 @@ void Gfx_DeleteVb(GfxResourceID* vb) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void Gfx_DeleteIb(GfxResourceID* ib) {
|
void Gfx_DeleteIb(GfxResourceID* ib) {
|
||||||
if (gl_lists || *ib <= 0) return;
|
if (gl_lists || *ib == NULL) return;
|
||||||
glDeleteBuffers(1, ib);
|
glDeleteBuffers(1, ib);
|
||||||
*ib = NULL;
|
*ib = NULL;
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user