mirror of
https://github.com/ClassiCube/ClassiCube.git
synced 2025-09-18 03:55:19 -04:00
Start porting servers to C launcher
This commit is contained in:
parent
251fd578ac
commit
483fb591ed
@ -6,9 +6,9 @@
|
|||||||
#include "GameStructs.h"
|
#include "GameStructs.h"
|
||||||
|
|
||||||
void ASyncRequest_Free(struct AsyncRequest* request) {
|
void ASyncRequest_Free(struct AsyncRequest* request) {
|
||||||
Mem_Free(request->ResultData);
|
Mem_Free(request->Data);
|
||||||
request->ResultData = NULL;
|
request->Data = NULL;
|
||||||
request->ResultSize = 0;
|
request->Size = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
#define ASYNC_DEF_ELEMS 10
|
#define ASYNC_DEF_ELEMS 10
|
||||||
@ -205,9 +205,9 @@ static void AsyncDownloader_ProcessRequest(struct AsyncRequest* request) {
|
|||||||
Platform_Log3("HTTP: return code %i (http %i), in %i ms",
|
Platform_Log3("HTTP: return code %i (http %i), in %i ms",
|
||||||
&request->Result, &request->StatusCode, &elapsed);
|
&request->Result, &request->StatusCode, &elapsed);
|
||||||
|
|
||||||
if (request->ResultData) {
|
if (request->Data) {
|
||||||
size = request->ResultSize;
|
size = request->Size;
|
||||||
addr = (uintptr_t)request->ResultData;
|
addr = (uintptr_t)request->Data;
|
||||||
Platform_Log2("HTTP returned data: %i bytes at %x", &size, &addr);
|
Platform_Log2("HTTP returned data: %i bytes at %x", &size, &addr);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -20,20 +20,20 @@ enum AsyncProgress {
|
|||||||
};
|
};
|
||||||
|
|
||||||
struct AsyncRequest {
|
struct AsyncRequest {
|
||||||
char URL[STRING_SIZE];
|
char URL[STRING_SIZE]; /* URL data is downloaded from/uploaded to. */
|
||||||
char ID[STRING_SIZE];
|
char ID[STRING_SIZE]; /* Unique identifier for this request. */
|
||||||
|
TimeMS TimeAdded; /* Time this request was added to queue of requests. */
|
||||||
|
TimeMS TimeDownloaded; /* Time response contents were completely downloaded. */
|
||||||
|
int StatusCode; /* HTTP status code returned in the response. */
|
||||||
|
uint32_t ContentLength; /* HTTP content length returned in the response. */
|
||||||
|
|
||||||
TimeMS TimeAdded, TimeDownloaded;
|
ReturnCode Result; /* 0 on success, otherwise platform-specific error. */
|
||||||
int StatusCode;
|
void* Data; /* Contents of the response. */
|
||||||
uint32_t ContentLength;
|
uint32_t Size; /* Size of the contents. */
|
||||||
|
|
||||||
ReturnCode Result;
|
|
||||||
void* ResultData;
|
|
||||||
uint32_t ResultSize;
|
|
||||||
|
|
||||||
TimeMS LastModified; /* Time item cached at (if at all) */
|
TimeMS LastModified; /* Time item cached at (if at all) */
|
||||||
char Etag[STRING_SIZE]; /* ETag of cached item (if any) */
|
char Etag[STRING_SIZE]; /* ETag of cached item (if any) */
|
||||||
uint8_t RequestType;
|
uint8_t RequestType; /* Whether to fetch contents or just headers. */
|
||||||
};
|
};
|
||||||
|
|
||||||
void ASyncRequest_Free(struct AsyncRequest* request);
|
void ASyncRequest_Free(struct AsyncRequest* request);
|
||||||
@ -42,7 +42,7 @@ void AsyncDownloader_GetSkin(const String* id, const String* skinName);
|
|||||||
void AsyncDownloader_GetData(const String* url, bool priority, const String* id);
|
void AsyncDownloader_GetData(const String* url, bool priority, const String* id);
|
||||||
void AsyncDownloader_GetContentLength(const String* url, bool priority, const String* id);
|
void AsyncDownloader_GetContentLength(const String* url, bool priority, const String* id);
|
||||||
/* TODO: Implement post */
|
/* TODO: Implement post */
|
||||||
/* void AsyncDownloader_PostString(const String* url, bool priority, const String* id, const String* contents); */
|
void AsyncDownloader_UNSAFE_PostData(const String* url, bool priority, const String* id, const void* data, const uint32_t size);
|
||||||
void AsyncDownloader_GetDataEx(const String* url, bool priority, const String* id, TimeMS* lastModified, const String* etag);
|
void AsyncDownloader_GetDataEx(const String* url, bool priority, const String* id, TimeMS* lastModified, const String* etag);
|
||||||
|
|
||||||
bool AsyncDownloader_Get(const String* id, struct AsyncRequest* item);
|
bool AsyncDownloader_Get(const String* id, struct AsyncRequest* item);
|
||||||
|
@ -698,8 +698,8 @@ static void Player_CheckSkin(struct Player* p) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (!AsyncDownloader_Get(&skin, &item)) return;
|
if (!AsyncDownloader_Get(&skin, &item)) return;
|
||||||
if (!item.ResultData) { Player_SetSkinAll(p, true); return; }
|
if (!item.Data) { Player_SetSkinAll(p, true); return; }
|
||||||
Stream_ReadonlyMemory(&mem, item.ResultData, item.ResultSize);
|
Stream_ReadonlyMemory(&mem, item.Data, item.Size);
|
||||||
|
|
||||||
if ((res = Png_Decode(&bmp, &mem))) {
|
if ((res = Png_Decode(&bmp, &mem))) {
|
||||||
url = String_FromRawArray(item.URL);
|
url = String_FromRawArray(item.URL);
|
||||||
|
@ -433,7 +433,7 @@ static void ColoursScreen_KeyDown(struct LScreen* s, Key key) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void ColoursScreen_ResetAll(void* widget, int x, int y) {
|
static void ColoursScreen_ResetAll(void* w, int x, int y) {
|
||||||
Launcher_ResetSkin();
|
Launcher_ResetSkin();
|
||||||
Launcher_SaveSkin();
|
Launcher_SaveSkin();
|
||||||
ColoursScreen_UpdateAll(&ColoursScreen_Instance);
|
ColoursScreen_UpdateAll(&ColoursScreen_Instance);
|
||||||
@ -884,7 +884,7 @@ static void MainScreen_TickFetchServers(struct MainScreen* s) {
|
|||||||
|
|
||||||
if (FetchServersTask.Base.Success) {
|
if (FetchServersTask.Base.Success) {
|
||||||
s->SigningIn = false;
|
s->SigningIn = false;
|
||||||
Launcher_SetScreen(SettingsScreen_MakeInstance());
|
Launcher_SetScreen(ServersScreen_MakeInstance());
|
||||||
} else {
|
} else {
|
||||||
MainScreen_Error(&FetchServersTask.Base, "retrieving servers list");
|
MainScreen_Error(&FetchServersTask.Base, "retrieving servers list");
|
||||||
}
|
}
|
||||||
@ -898,7 +898,6 @@ static void MainScreen_Tick(struct LScreen* s_) {
|
|||||||
MainScreen_TickFetchServers(s);
|
MainScreen_TickFetchServers(s);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
struct LScreen* MainScreen_MakeInstance(void) {
|
struct LScreen* MainScreen_MakeInstance(void) {
|
||||||
struct MainScreen* s = &MainScreen_Instance;
|
struct MainScreen* s = &MainScreen_Instance;
|
||||||
LScreen_Reset((struct LScreen*)s);
|
LScreen_Reset((struct LScreen*)s);
|
||||||
@ -911,6 +910,68 @@ struct LScreen* MainScreen_MakeInstance(void) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*########################################################################################################################*
|
||||||
|
*--------------------------------------------------------ServersScreen----------------------------------------------------*
|
||||||
|
*#########################################################################################################################*/
|
||||||
|
static struct ServersScreen {
|
||||||
|
LScreen_Layout
|
||||||
|
struct LInput IptName, IptHash;
|
||||||
|
struct LButton BtnBack, BtnConnect, BtnRefresh;
|
||||||
|
struct LWidget* _widgets[5];
|
||||||
|
} ServersScreen_Instance;
|
||||||
|
|
||||||
|
static void ServersScreen_Connect(void* w, int x, int y) {
|
||||||
|
Launcher_ConnectToServer(&ServersScreen_Instance.IptHash.Text);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void ServersScreen_Refresh(void* w, int x, int y) {
|
||||||
|
const static String working = String_FromConst("&eWorking..");
|
||||||
|
struct LButton* btn;
|
||||||
|
if (FetchServersTask.Base.Working) return;
|
||||||
|
|
||||||
|
FetchServersTask_Run();
|
||||||
|
btn = &ServersScreen_Instance.BtnRefresh;
|
||||||
|
LButton_SetText(btn, &working);
|
||||||
|
LWidget_Redraw(btn);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void ServersScreen_Init(struct LScreen* s_) {
|
||||||
|
struct ServersScreen* s = (struct ServersScreen*)s_;
|
||||||
|
if (s->NumWidgets) return;
|
||||||
|
s->Widgets = s->_widgets;
|
||||||
|
|
||||||
|
LScreen_Input(s_, &s->IptName, 370, false, "&gSearch servers..");
|
||||||
|
LScreen_Input(s_, &s->IptHash, 475, false, "&gclassicube.net/server/play/...");
|
||||||
|
|
||||||
|
LScreen_Button(s_, &s->BtnBack, 110, 30, "Back");
|
||||||
|
LScreen_Button(s_, &s->BtnConnect, 110, 30, "Connect");
|
||||||
|
LScreen_Button(s_, &s->BtnRefresh, 110, 30, "Refresh");
|
||||||
|
|
||||||
|
s->BtnBack.OnClick = SwitchToMain;
|
||||||
|
s->BtnConnect.OnClick = ServersScreen_Connect;
|
||||||
|
s->BtnRefresh.OnClick = ServersScreen_Refresh;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void ServersScreen_Reposition(struct LScreen* s_) {
|
||||||
|
struct ServersScreen* s = (struct ServersScreen*)s_;
|
||||||
|
LWidget_SetLocation(&s->IptName, ANCHOR_MIN, ANCHOR_MIN, 10, 10);
|
||||||
|
LWidget_SetLocation(&s->IptHash, ANCHOR_MIN, ANCHOR_MAX, 10, 10);
|
||||||
|
|
||||||
|
LWidget_SetLocation(&s->BtnBack, ANCHOR_MAX, ANCHOR_MIN, 10, 10);
|
||||||
|
LWidget_SetLocation(&s->BtnConnect, ANCHOR_MAX, ANCHOR_MAX, 10, 10);
|
||||||
|
LWidget_SetLocation(&s->BtnRefresh, ANCHOR_MAX, ANCHOR_MIN, 135, 10);
|
||||||
|
}
|
||||||
|
|
||||||
|
struct LScreen* ServersScreen_MakeInstance(void) {
|
||||||
|
struct ServersScreen* s = &ServersScreen_Instance;
|
||||||
|
LScreen_Reset((struct LScreen*)s);
|
||||||
|
s->HidesBackground = true;
|
||||||
|
s->Init = ServersScreen_Init;
|
||||||
|
s->Reposition = ServersScreen_Reposition;
|
||||||
|
return (struct LScreen*)s;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/*########################################################################################################################*
|
/*########################################################################################################################*
|
||||||
*--------------------------------------------------------SettingsScreen---------------------------------------------------*
|
*--------------------------------------------------------SettingsScreen---------------------------------------------------*
|
||||||
*#########################################################################################################################*/
|
*#########################################################################################################################*/
|
||||||
|
@ -33,7 +33,8 @@ typedef void(*LWidget_Func)(struct LScreen* s, struct LWidget* w);
|
|||||||
struct LWidget* HoveredWidget; /* Widget the mouse is currently hovering over. */ \
|
struct LWidget* HoveredWidget; /* Widget the mouse is currently hovering over. */ \
|
||||||
struct LWidget* SelectedWidget; /* Widget mouse last clicked on. */ \
|
struct LWidget* SelectedWidget; /* Widget mouse last clicked on. */ \
|
||||||
int NumWidgets; /* Number of widgets actually used. */ \
|
int NumWidgets; /* Number of widgets actually used. */ \
|
||||||
struct LWidget** Widgets; /* Array of pointers to all widgets in the screen. */
|
struct LWidget** Widgets; /* Array of pointers to all widgets in the screen. */ \
|
||||||
|
bool HidesBackground; /* Whether titlebar in window is hidden. */
|
||||||
|
|
||||||
struct LScreen { LScreen_Layout };
|
struct LScreen { LScreen_Layout };
|
||||||
|
|
||||||
|
32
src/LWeb.c
32
src/LWeb.c
@ -218,8 +218,8 @@ void LWebTask_Tick(struct LWebTask* task) {
|
|||||||
|
|
||||||
task->Working = false;
|
task->Working = false;
|
||||||
task->Completed = true;
|
task->Completed = true;
|
||||||
task->Success = !task->Res && req.ResultData && req.ResultSize;
|
task->Success = !task->Res && req.Data && req.Size;
|
||||||
if (task->Success) task->Handle(req.ResultData, req.ResultSize);
|
if (task->Success) task->Handle(req.Data, req.Size);
|
||||||
ASyncRequest_Free(&req);
|
ASyncRequest_Free(&req);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -261,7 +261,33 @@ void GetTokenTask_Run(void) {
|
|||||||
*--------------------------------------------------------SignInTask-------------------------------------------------------*
|
*--------------------------------------------------------SignInTask-------------------------------------------------------*
|
||||||
*#########################################################################################################################*/
|
*#########################################################################################################################*/
|
||||||
struct SignInTaskData SignInTask;
|
struct SignInTaskData SignInTask;
|
||||||
void SignInTask_Run(const String* user, const String* pass);
|
char userBuffer[STRING_SIZE];
|
||||||
|
|
||||||
|
static void SignInTask_OnValue(struct JsonContext* ctx, const String* str) {
|
||||||
|
//if (!String_CaselessEqualsConst(&ctx->CurKey, "token")) return;
|
||||||
|
//String_Copy(&GetTokenTask.Token, str);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void SignInTask_Handle(uint8_t* data, uint32_t len) {
|
||||||
|
//Json_Handle(data, len, GetTokenTask_OnValue, NULL, NULL);
|
||||||
|
}
|
||||||
|
|
||||||
|
void SignInTask_Run(const String* user, const String* pass) {
|
||||||
|
const static String id = String_FromConst("CC post login");
|
||||||
|
const static String url = String_FromConst("https://www.classicube.net/api/login");
|
||||||
|
if (SignInTask.Base.Working) return;
|
||||||
|
|
||||||
|
LWebTask_Reset(&SignInTask.Base);
|
||||||
|
String_InitArray(SignInTask.Username, userBuffer);
|
||||||
|
SignInTask.Error.length = 0;
|
||||||
|
|
||||||
|
// remove this
|
||||||
|
String_Copy(&SignInTask.Username, user);
|
||||||
|
|
||||||
|
SignInTask.Base.Identifier = id;
|
||||||
|
AsyncDownloader_GetData(&url, false, &id);
|
||||||
|
SignInTask.Base.Handle = SignInTask_Handle;
|
||||||
|
}
|
||||||
// NOTE: Remember to add &c for errors here too
|
// NOTE: Remember to add &c for errors here too
|
||||||
|
|
||||||
|
|
||||||
|
499
src/LWidgets.c
499
src/LWidgets.c
@ -6,6 +6,7 @@
|
|||||||
#include "ExtMath.h"
|
#include "ExtMath.h"
|
||||||
#include "Window.h"
|
#include "Window.h"
|
||||||
#include "Funcs.h"
|
#include "Funcs.h"
|
||||||
|
#include "LWeb.h"
|
||||||
|
|
||||||
#define BORDER 1
|
#define BORDER 1
|
||||||
|
|
||||||
@ -550,3 +551,501 @@ void LSlider_Init(struct LSlider* w, int width, int height) {
|
|||||||
w->Width = width; w->Height = height;
|
w->Width = width; w->Height = height;
|
||||||
w->MaxValue = 100;
|
w->MaxValue = 100;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*########################################################################################################################*
|
||||||
|
*------------------------------------------------------TableWidget--------------------------------------------------------*
|
||||||
|
*#########################################################################################################################*/
|
||||||
|
static void NameColumn_Get(struct ServerInfo* row, String* str) {
|
||||||
|
String_Copy(str, &row->Name);
|
||||||
|
}
|
||||||
|
static int NameColumn_Sort(struct ServerInfo* a, struct ServerInfo* b) {
|
||||||
|
return String_Compare(&a->Name, &b->Name);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void PlayersColumn_Get(struct ServerInfo* row, String* str) {
|
||||||
|
String_Format2(str, "%i/%i", &row->Players, &row->MaxPlayers);
|
||||||
|
}
|
||||||
|
static int PlayersColumn_Sort(struct ServerInfo* a, struct ServerInfo* b) {
|
||||||
|
return b->Players - a->Players;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void UptimeColumn_Get(struct ServerInfo* row, String* str) {
|
||||||
|
int uptime = row->Uptime;
|
||||||
|
char unit = 's';
|
||||||
|
|
||||||
|
if (uptime >= SECS_PER_DAY * 7) {
|
||||||
|
uptime /= SECS_PER_DAY; unit = 'd';
|
||||||
|
} else if (uptime >= SECS_PER_HOUR) {
|
||||||
|
uptime /= SECS_PER_HOUR; unit = 'h';
|
||||||
|
} else if (uptime >= SECS_PER_MIN) {
|
||||||
|
uptime /= SECS_PER_MIN; unit = 'm';
|
||||||
|
}
|
||||||
|
String_Format2(str, "%i%r", &uptime, &unit);
|
||||||
|
}
|
||||||
|
static int UptimeColumn_Sort(struct ServerInfo* a, struct ServerInfo* b) {
|
||||||
|
return b->Uptime - a->Uptime;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void SoftwareColumn_Get(struct ServerInfo* row, String* str) {
|
||||||
|
String_Copy(str, &row->Software);
|
||||||
|
}
|
||||||
|
static int SoftwareColumn_Sort(struct ServerInfo* a, struct ServerInfo* b) {
|
||||||
|
return String_Compare(&a->Software, &b->Software);
|
||||||
|
}
|
||||||
|
|
||||||
|
static struct LTableColumn tableColumns[4] = {
|
||||||
|
{ "Name", 320, 320, NameColumn_Get, NameColumn_Sort },
|
||||||
|
{ "Players", 65, 65, PlayersColumn_Get, PlayersColumn_Sort },
|
||||||
|
{ "Uptime", 65, 65, UptimeColumn_Get, UptimeColumn_Sort },
|
||||||
|
{ "Software", 140, 140, SoftwareColumn_Get, SoftwareColumn_Sort }
|
||||||
|
};
|
||||||
|
|
||||||
|
/*
|
||||||
|
PackedCol backGridCol = new PackedCol(20, 20, 10);
|
||||||
|
PackedCol foreGridCol = new PackedCol(40, 40, 40);
|
||||||
|
|
||||||
|
int entryHeight, headerHeight;
|
||||||
|
int headerStartY, headerEndY;
|
||||||
|
int numEntries, maxIndex;
|
||||||
|
Font font, titleFont;
|
||||||
|
|
||||||
|
void SetDrawData(IDrawer2D drawer, Font font, Font titleFont) {
|
||||||
|
this.font = font;
|
||||||
|
this.titleFont = titleFont;
|
||||||
|
|
||||||
|
headerHeight = drawer.FontHeight(titleFont, true);
|
||||||
|
entryHeight = drawer.FontHeight(font, true);
|
||||||
|
}
|
||||||
|
|
||||||
|
void RecalculateDrawData() {
|
||||||
|
for (int i = 0; i < table.ColumnWidths.Length; i++) {
|
||||||
|
table.ColumnWidths[i] = table.DesiredColumnWidths[i];
|
||||||
|
Utils.Clamp(ref table.ColumnWidths[i], 20, game.Width - 20);
|
||||||
|
}
|
||||||
|
table.Width = game.Width - table.X;
|
||||||
|
ResetEntries();
|
||||||
|
|
||||||
|
int y = table.Y + 3;
|
||||||
|
y += headerHeight + 2;
|
||||||
|
maxIndex = table.Count;
|
||||||
|
y += 5;
|
||||||
|
|
||||||
|
for (int i = table.CurrentIndex; i < table.Count; i++) {
|
||||||
|
if (y + entryHeight > table.Y + table.Height) {
|
||||||
|
maxIndex = i; return;
|
||||||
|
}
|
||||||
|
|
||||||
|
table.entries[table.order[i]].Y = y;
|
||||||
|
table.entries[table.order[i]].Height = entryHeight;
|
||||||
|
y += entryHeight + 2;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const int flagPadding = 15;
|
||||||
|
void RedrawData(IDrawer2D drawer) {
|
||||||
|
DrawGrid(drawer);
|
||||||
|
int x = table.X + flagPadding + 5;
|
||||||
|
x += DrawColumn(drawer, "Name", 0, x, filterName) + 5;
|
||||||
|
x += DrawColumn(drawer, "Players", 1, x, filterPlayers) + 5;
|
||||||
|
x += DrawColumn(drawer, "Uptime", 2, x, filterUptime) + 5;
|
||||||
|
x += DrawColumn(drawer, "Software", 3, x, filterSoftware) + 5;
|
||||||
|
|
||||||
|
DrawScrollbar(drawer);
|
||||||
|
DrawFlags();
|
||||||
|
}
|
||||||
|
|
||||||
|
void Redraw(IDrawer2D drawer) {
|
||||||
|
RecalculateDrawData();
|
||||||
|
RedrawData(drawer);
|
||||||
|
}
|
||||||
|
|
||||||
|
delegate string ColumnFilter(TableEntry entry);
|
||||||
|
// cache to avoid allocations every redraw
|
||||||
|
static string FilterName(TableEntry e) { return e.Name; } static ColumnFilter filterName = FilterName;
|
||||||
|
static string FilterPlayers(TableEntry e) { return e.Players; } static ColumnFilter filterPlayers = FilterPlayers;
|
||||||
|
static string FilterUptime(TableEntry e) { return e.Uptime; } static ColumnFilter filterUptime = FilterUptime;
|
||||||
|
static string FilterSoftware(TableEntry e) { return e.Software; } static ColumnFilter filterSoftware = FilterSoftware;
|
||||||
|
|
||||||
|
static FastBitmap GetFlag(string flag) {
|
||||||
|
List<string> flags = FetchFlagsTask.Flags;
|
||||||
|
List<FastBitmap> bitmaps = FetchFlagsTask.Bitmaps;
|
||||||
|
|
||||||
|
for (int i = 0; i < flags.Count; i++) {
|
||||||
|
if (flags[i] != flag) continue;
|
||||||
|
return i < bitmaps.Count ? bitmaps[i] : null;
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void DrawFlags() {
|
||||||
|
using (FastBitmap dst = game.LockBits()) {
|
||||||
|
for (int i = table.CurrentIndex; i < maxIndex; i++) {
|
||||||
|
TableEntry entry = table.Get(i);
|
||||||
|
FastBitmap flag = GetFlag(entry.Flag);
|
||||||
|
if (flag == null) continue;
|
||||||
|
|
||||||
|
int x = table.X, y = entry.Y;
|
||||||
|
Rectangle rect = new Rectangle(x + 2, y + 3, 16, 11);
|
||||||
|
BitmapDrawer.Draw(flag, dst, rect);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
int DrawColumn(IDrawer2D drawer, string header, int columnI, int x, ColumnFilter filter) {
|
||||||
|
int y = table.Y + 3;
|
||||||
|
int maxWidth = table.ColumnWidths[columnI];
|
||||||
|
bool separator = columnI > 0;
|
||||||
|
|
||||||
|
DrawTextArgs args = new DrawTextArgs(header, titleFont, true);
|
||||||
|
TableEntry headerEntry = default(TableEntry);
|
||||||
|
DrawColumnEntry(drawer, ref args, maxWidth, x, ref y, ref headerEntry);
|
||||||
|
maxIndex = table.Count;
|
||||||
|
|
||||||
|
y += 5;
|
||||||
|
for (int i = table.CurrentIndex; i < table.Count; i++) {
|
||||||
|
TableEntry entry = table.Get(i);
|
||||||
|
args = new DrawTextArgs(filter(entry), font, true);
|
||||||
|
|
||||||
|
if ((i == table.SelectedIndex || entry.Featured) && !separator) {
|
||||||
|
int startY = y - 3;
|
||||||
|
int height = Math.Min(startY + (entryHeight + 4), table.Y + table.Height) - startY;
|
||||||
|
drawer.Clear(GetGridCol(entry.Featured, i == table.SelectedIndex), table.X, startY, table.Width, height);
|
||||||
|
}
|
||||||
|
if (!DrawColumnEntry(drawer, ref args, maxWidth, x, ref y, ref entry)) {
|
||||||
|
maxIndex = i; break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (separator && !game.ClassicBackground) {
|
||||||
|
drawer.Clear(LauncherSkin.BackgroundCol, x - 7, table.Y, 2, table.Height);
|
||||||
|
}
|
||||||
|
return maxWidth + 5;
|
||||||
|
}
|
||||||
|
|
||||||
|
PackedCol GetGridCol(bool featured, bool selected) {
|
||||||
|
if (featured) {
|
||||||
|
if (selected) return new PackedCol(50, 53, 0);
|
||||||
|
return new PackedCol(101, 107, 0);
|
||||||
|
}
|
||||||
|
return foreGridCol;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool DrawColumnEntry(IDrawer2D drawer, ref DrawTextArgs args,
|
||||||
|
int maxWidth, int x, ref int y, ref TableEntry entry) {
|
||||||
|
Size size = drawer.MeasureText(ref args);
|
||||||
|
bool empty = args.Text == "";
|
||||||
|
if (empty)
|
||||||
|
size.Height = entryHeight;
|
||||||
|
if (y + size.Height > table.Y + table.Height) {
|
||||||
|
y = table.Y + table.Height + 2; return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
entry.Y = y; entry.Height = size.Height;
|
||||||
|
if (!empty) {
|
||||||
|
size.Width = Math.Min(maxWidth, size.Width);
|
||||||
|
args.SkipPartsCheck = false;
|
||||||
|
Drawer2DExt.DrawClippedText(ref args, drawer, x, y, maxWidth);
|
||||||
|
}
|
||||||
|
y += size.Height + 2;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
void ResetEntries() {
|
||||||
|
for (int i = 0; i < table.Count; i++) {
|
||||||
|
table.entries[i].Height = 0;
|
||||||
|
table.entries[i].Y = -10;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void DrawGrid(IDrawer2D drawer) {
|
||||||
|
if (!game.ClassicBackground)
|
||||||
|
drawer.Clear(LauncherSkin.BackgroundCol,
|
||||||
|
table.X, table.Y + headerHeight + 5, table.Width, 2);
|
||||||
|
headerStartY = table.Y;
|
||||||
|
|
||||||
|
headerEndY = table.Y + headerHeight + 5;
|
||||||
|
int startY = headerEndY + 3;
|
||||||
|
numEntries = (table.Y + table.Height - startY) / (entryHeight + 3);
|
||||||
|
}
|
||||||
|
|
||||||
|
void DrawScrollbar(IDrawer2D drawer) {
|
||||||
|
PackedCol col = game.ClassicBackground ? new PackedCol(80, 80, 80) : LauncherSkin.ButtonBorderCol;
|
||||||
|
drawer.Clear(col, game.Width - 10, table.Y, 10, table.Height);
|
||||||
|
col = game.ClassicBackground ? new PackedCol(160, 160, 160) : LauncherSkin.ButtonForeActiveCol;
|
||||||
|
int yOffset, height;
|
||||||
|
table.GetScrollbarCoords(out yOffset, out height);
|
||||||
|
drawer.Clear(col, game.Width - 10, table.Y + yOffset, 10, height);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
internal struct TableEntry {
|
||||||
|
public string Hash, Name, Players, Uptime, Software, RawUptime, Flag;
|
||||||
|
public int Y, Height;
|
||||||
|
public bool Featured;
|
||||||
|
}
|
||||||
|
|
||||||
|
public delegate void TableNeedsRedrawHandler();
|
||||||
|
|
||||||
|
TableView view;
|
||||||
|
public TableWidget(LauncherWindow window) : base(window) {
|
||||||
|
OnClick = HandleOnClick;
|
||||||
|
view = new TableView();
|
||||||
|
view.Init(window, this);
|
||||||
|
}
|
||||||
|
|
||||||
|
public TableNeedsRedrawHandler NeedRedraw;
|
||||||
|
public Action<string> SelectedChanged;
|
||||||
|
public int SelectedIndex = -1;
|
||||||
|
public string SelectedHash = "";
|
||||||
|
public int CurrentIndex, Count;
|
||||||
|
|
||||||
|
internal TableEntry[] entries;
|
||||||
|
internal int[] order;
|
||||||
|
internal List<ServerListEntry> servers;
|
||||||
|
internal TableEntry Get(int i) { return entries[order[i]]; }
|
||||||
|
|
||||||
|
public void SetEntries(List<ServerListEntry> servers) {
|
||||||
|
entries = new TableEntry[servers.Count];
|
||||||
|
order = new int[servers.Count];
|
||||||
|
this.servers = servers;
|
||||||
|
|
||||||
|
for (int i = 0; i < servers.Count; i++) {
|
||||||
|
ServerListEntry e = servers[i];
|
||||||
|
TableEntry tableEntry = default(TableEntry);
|
||||||
|
tableEntry.Hash = e.Hash;
|
||||||
|
tableEntry.Name = e.Name;
|
||||||
|
tableEntry.Players = e.Players + "/" + e.MaxPlayers;
|
||||||
|
tableEntry.Software = e.Software;
|
||||||
|
tableEntry.Uptime = MakeUptime(e.Uptime);
|
||||||
|
tableEntry.RawUptime = e.Uptime;
|
||||||
|
tableEntry.Featured = e.Featured;
|
||||||
|
tableEntry.Flag = e.Flag;
|
||||||
|
|
||||||
|
entries[i] = tableEntry;
|
||||||
|
order[i] = i;
|
||||||
|
}
|
||||||
|
Count = entries.Length;
|
||||||
|
}
|
||||||
|
|
||||||
|
string curFilter;
|
||||||
|
public void FilterEntries(string filter) {
|
||||||
|
curFilter = filter;
|
||||||
|
Count = 0;
|
||||||
|
for (int i = 0; i < entries.Length; i++) {
|
||||||
|
TableEntry entry = entries[i];
|
||||||
|
if (entry.Name.IndexOf(filter, StringComparison.OrdinalIgnoreCase) >= 0) {
|
||||||
|
order[Count++] = i;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
for (int i = Count; i < entries.Length; i++) {
|
||||||
|
order[i] = -100000;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
internal void GetScrollbarCoords(out int y, out int height) {
|
||||||
|
if (Count == 0) { y = 0; height = 0; return; }
|
||||||
|
|
||||||
|
float scale = Height / (float)Count;
|
||||||
|
y = (int)Math.Ceiling(CurrentIndex * scale);
|
||||||
|
height = (int)Math.Ceiling((view.maxIndex - CurrentIndex) * scale);
|
||||||
|
height = Math.Min(y + height, Height) - y;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void SetSelected(int index) {
|
||||||
|
if (index >= view.maxIndex) CurrentIndex = index + 1 - view.numEntries;
|
||||||
|
if (index < CurrentIndex) CurrentIndex = index;
|
||||||
|
if (index >= Count) index = Count - 1;
|
||||||
|
if (index < 0) index = 0;
|
||||||
|
|
||||||
|
SelectedHash = "";
|
||||||
|
SelectedIndex = index;
|
||||||
|
lastIndex = index;
|
||||||
|
ClampIndex();
|
||||||
|
|
||||||
|
if (Count > 0) {
|
||||||
|
TableEntry entry = Get(index);
|
||||||
|
SelectedChanged(entry.Hash);
|
||||||
|
SelectedHash = entry.Hash;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void SetSelected(string hash) {
|
||||||
|
SelectedIndex = -1;
|
||||||
|
for (int i = 0; i < Count; i++) {
|
||||||
|
if (Get(i).Hash != hash) continue;
|
||||||
|
SetSelected(i);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void ClampIndex() {
|
||||||
|
if (CurrentIndex > Count - view.numEntries)
|
||||||
|
CurrentIndex = Count - view.numEntries;
|
||||||
|
if (CurrentIndex < 0)
|
||||||
|
CurrentIndex = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
string MakeUptime(string rawSeconds) {
|
||||||
|
TimeSpan t = TimeSpan.FromSeconds(Double.Parse(rawSeconds));
|
||||||
|
if (t.TotalHours >= 24 * 7)
|
||||||
|
return (int)t.TotalDays + "d";
|
||||||
|
if (t.TotalHours >= 1)
|
||||||
|
return (int)t.TotalHours + "h";
|
||||||
|
if (t.TotalMinutes >= 1)
|
||||||
|
return (int)t.TotalMinutes + "m";
|
||||||
|
return (int)t.TotalSeconds + "s";
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public int[] ColumnWidths = new int[] { 320, 65, 65, 140 };
|
||||||
|
public int[] DesiredColumnWidths = new int[] { 320, 65, 65, 140 };
|
||||||
|
|
||||||
|
public void SetDrawData(IDrawer2D drawer, Font font, Font titleFont,
|
||||||
|
Anchor horAnchor, Anchor verAnchor, int x, int y) {
|
||||||
|
SetLocation(horAnchor, verAnchor, x, y);
|
||||||
|
view.SetDrawData(drawer, font, titleFont);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void RecalculateDrawData() { view.RecalculateDrawData(); }
|
||||||
|
public void RedrawData(IDrawer2D drawer) { view.RedrawData(drawer); }
|
||||||
|
public void RedrawFlags() { view.DrawFlags(); }
|
||||||
|
|
||||||
|
public override void Redraw(IDrawer2D drawer) {
|
||||||
|
RecalculateDrawData();
|
||||||
|
RedrawData(drawer);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
DefaultComparer defComp = new DefaultComparer();
|
||||||
|
NameComparer nameComp = new NameComparer();
|
||||||
|
PlayersComparer playerComp = new PlayersComparer();
|
||||||
|
UptimeComparer uptimeComp = new UptimeComparer();
|
||||||
|
SoftwareComparer softwareComp = new SoftwareComparer();
|
||||||
|
internal int DraggingColumn = -1;
|
||||||
|
internal bool DraggingScrollbar = false;
|
||||||
|
internal int mouseOffset;
|
||||||
|
|
||||||
|
public void SortDefault() {
|
||||||
|
SortEntries(defComp, true);
|
||||||
|
}
|
||||||
|
|
||||||
|
void SelectHeader(int mouseX, int mouseY) {
|
||||||
|
int x = X + 15;
|
||||||
|
for (int i = 0; i < ColumnWidths.Length; i++) {
|
||||||
|
x += ColumnWidths[i] + 10;
|
||||||
|
if (mouseX >= x - 8 && mouseX < x + 8) {
|
||||||
|
DraggingColumn = i;
|
||||||
|
lastIndex = -10; return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
TrySortColumns(mouseX);
|
||||||
|
}
|
||||||
|
|
||||||
|
void TrySortColumns(int mouseX) {
|
||||||
|
int x = X + TableView.flagPadding;
|
||||||
|
if (mouseX >= x && mouseX < x + ColumnWidths[0]) {
|
||||||
|
SortEntries(nameComp, false); return;
|
||||||
|
}
|
||||||
|
|
||||||
|
x += ColumnWidths[0] + 10;
|
||||||
|
if (mouseX >= x && mouseX < x + ColumnWidths[1]) {
|
||||||
|
SortEntries(playerComp, false); return;
|
||||||
|
}
|
||||||
|
|
||||||
|
x += ColumnWidths[1] + 10;
|
||||||
|
if (mouseX >= x && mouseX < x + ColumnWidths[2]) {
|
||||||
|
SortEntries(uptimeComp, false); return;
|
||||||
|
}
|
||||||
|
|
||||||
|
x += ColumnWidths[2] + 10;
|
||||||
|
if (mouseX >= x) {
|
||||||
|
SortEntries(softwareComp, false); return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void SortEntries(TableEntryComparer comparer, bool noRedraw) {
|
||||||
|
Array.Sort(entries, 0, entries.Length, comparer);
|
||||||
|
lastIndex = -10;
|
||||||
|
if (curFilter != null && curFilter.Length > 0) {
|
||||||
|
FilterEntries(curFilter);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (noRedraw) return;
|
||||||
|
comparer.Invert = !comparer.Invert;
|
||||||
|
SetSelected(SelectedHash);
|
||||||
|
NeedRedraw();
|
||||||
|
}
|
||||||
|
|
||||||
|
void GetSelectedServer(int mouseX, int mouseY) {
|
||||||
|
for (int i = 0; i < Count; i++) {
|
||||||
|
TableEntry entry = Get(i);
|
||||||
|
if (mouseY < entry.Y || mouseY >= entry.Y + entry.Height + 2) continue;
|
||||||
|
|
||||||
|
if (lastIndex == i && (DateTime.UtcNow - lastPress).TotalSeconds < 1) {
|
||||||
|
Window.ConnectToServer(servers, entry.Hash);
|
||||||
|
lastPress = DateTime.MinValue;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
SetSelected(i);
|
||||||
|
NeedRedraw();
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void HandleOnClick(int mouseX, int mouseY) {
|
||||||
|
if (mouseX >= Window.Width - 10) {
|
||||||
|
ScrollbarClick(mouseY);
|
||||||
|
DraggingScrollbar = true;
|
||||||
|
lastIndex = -10; return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (mouseY >= view.headerStartY && mouseY < view.headerEndY) {
|
||||||
|
SelectHeader(mouseX, mouseY);
|
||||||
|
} else {
|
||||||
|
GetSelectedServer(mouseX, mouseY);
|
||||||
|
}
|
||||||
|
lastPress = DateTime.UtcNow;
|
||||||
|
}
|
||||||
|
|
||||||
|
int lastIndex = -10;
|
||||||
|
DateTime lastPress;
|
||||||
|
public void MouseMove(int x, int y, int deltaX, int deltaY) {
|
||||||
|
if (DraggingScrollbar) {
|
||||||
|
y -= Y;
|
||||||
|
float scale = Height / (float)Count;
|
||||||
|
CurrentIndex = (int)((y - mouseOffset) / scale);
|
||||||
|
ClampIndex();
|
||||||
|
NeedRedraw();
|
||||||
|
} else if (DraggingColumn >= 0) {
|
||||||
|
if (x >= Window.Width - 20) return;
|
||||||
|
int col = DraggingColumn;
|
||||||
|
ColumnWidths[col] += deltaX;
|
||||||
|
Utils.Clamp(ref ColumnWidths[col], 20, Window.Width - 20);
|
||||||
|
DesiredColumnWidths[col] = ColumnWidths[col];
|
||||||
|
NeedRedraw();
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
void ScrollbarClick(int mouseY) {
|
||||||
|
mouseY -= Y;
|
||||||
|
int y, height;
|
||||||
|
GetScrollbarCoords(out y, out height);
|
||||||
|
int delta = (view.maxIndex - CurrentIndex);
|
||||||
|
|
||||||
|
if (mouseY < y) {
|
||||||
|
CurrentIndex -= delta;
|
||||||
|
} else if (mouseY >= y + height) {
|
||||||
|
CurrentIndex += delta;
|
||||||
|
} else {
|
||||||
|
DraggingScrollbar = true;
|
||||||
|
mouseOffset = mouseY - y;
|
||||||
|
}
|
||||||
|
ClampIndex();
|
||||||
|
NeedRedraw();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
*/
|
@ -111,4 +111,22 @@ struct LSlider {
|
|||||||
BitmapCol ProgressCol;
|
BitmapCol ProgressCol;
|
||||||
};
|
};
|
||||||
CC_NOINLINE void LSlider_Init(struct LSlider* w, int width, int height);
|
CC_NOINLINE void LSlider_Init(struct LSlider* w, int width, int height);
|
||||||
|
|
||||||
|
struct ServerInfo;
|
||||||
|
struct LTableColumn {
|
||||||
|
/* Name of this column. */
|
||||||
|
const char* Name;
|
||||||
|
/* Current and default width of this column. */
|
||||||
|
int Width, DefaultWidth;
|
||||||
|
/* Gets the value of this column for the given row. */
|
||||||
|
void (*GetValue)(struct ServerInfo* row, String* str);
|
||||||
|
/* Sorts two rows based on value of this column in both rows. */
|
||||||
|
int (*SortRows)(struct ServerInfo* a, struct ServerInfo* b);
|
||||||
|
/* Whether to invert the order of row sorting. */
|
||||||
|
bool InvertSort;
|
||||||
|
};
|
||||||
|
/* Represents a table of server entries. */
|
||||||
|
struct LTable {
|
||||||
|
LWidget_Layout
|
||||||
|
};
|
||||||
#endif
|
#endif
|
||||||
|
@ -14,12 +14,9 @@
|
|||||||
#include "AsyncDownloader.h"
|
#include "AsyncDownloader.h"
|
||||||
|
|
||||||
/* TODO TODO TODO TODO TODO TODO TODO TODO FIX THESE STUBS */
|
/* TODO TODO TODO TODO TODO TODO TODO TODO FIX THESE STUBS */
|
||||||
void SignInTask_Run(const String* user, const String* pass) { }
|
|
||||||
void Launcher_SetSecureOpt(const char* opt, const String* data, const String* key) { }
|
void Launcher_SetSecureOpt(const char* opt, const String* data, const String* key) { }
|
||||||
void Launcher_GetSecureOpt(const char* opt, String* data, const String* key) { }
|
void Launcher_GetSecureOpt(const char* opt, String* data, const String* key) { }
|
||||||
struct LScreen* ResourcesScreen_MakeInstance(void) { return NULL; }
|
struct LScreen* ResourcesScreen_MakeInstance(void) { return NULL; }
|
||||||
struct LScreen* ServersScreen_MakeInstance(void) { return NULL; }
|
|
||||||
|
|
||||||
struct LScreen* Launcher_Screen;
|
struct LScreen* Launcher_Screen;
|
||||||
bool Launcher_Dirty;
|
bool Launcher_Dirty;
|
||||||
Rect2D Launcher_DirtyArea;
|
Rect2D Launcher_DirtyArea;
|
||||||
@ -55,6 +52,50 @@ void Launcher_SetScreen(struct LScreen* screen) {
|
|||||||
Launcher_Redraw();
|
Launcher_Redraw();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
CC_NOINLINE static void Launcher_StartFromInfo(struct ServerInfo* info) {
|
||||||
|
String port; char portBuffer[STRING_INT_CHARS];
|
||||||
|
String_InitArray(port, portBuffer);
|
||||||
|
|
||||||
|
String_AppendInt(&port, info->Port);
|
||||||
|
Launcher_StartGame(&SignInTask.Username, &info->Mppass, &info->IP, &port, &info->Name);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool Launcher_ConnectToServer(const String* hash) {
|
||||||
|
int i;
|
||||||
|
struct ServerInfo* info;
|
||||||
|
if (!hash->length) return false;
|
||||||
|
|
||||||
|
for (i = 0; i < FetchServersTask.NumServers; i++) {
|
||||||
|
info = &FetchServersTask.Servers[i];
|
||||||
|
if (!String_Equals(hash, &info->Hash)) continue;
|
||||||
|
|
||||||
|
Launcher_StartFromInfo(info);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Fallback to private server handling */
|
||||||
|
/* TODO: Rewrite to be async */
|
||||||
|
FetchServerTask_Run(hash);
|
||||||
|
|
||||||
|
while (!FetchServerTask.Base.Completed) {
|
||||||
|
LWebTask_Tick(&FetchServerTask.Base);
|
||||||
|
Thread_Sleep(10);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (FetchServerTask.Server.Hash.length) {
|
||||||
|
Launcher_StartFromInfo(&FetchServerTask.Server);
|
||||||
|
return true;
|
||||||
|
} else if (FetchServerTask.Base.Res) {
|
||||||
|
Launcher_ShowError(FetchServerTask.Base.Res, "fetching server info");
|
||||||
|
} else if (FetchServerTask.Base.Status != 200) {
|
||||||
|
/* TODO: Use a better dialog message.. */
|
||||||
|
Launcher_ShowError(FetchServerTask.Base.Status, "fetching server info");
|
||||||
|
} else {
|
||||||
|
Window_ShowDialog("Failed to connect", "No server has that hash");
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/*########################################################################################################################*
|
/*########################################################################################################################*
|
||||||
*---------------------------------------------------------Event handler---------------------------------------------------*
|
*---------------------------------------------------------Event handler---------------------------------------------------*
|
||||||
@ -425,6 +466,11 @@ void Launcher_ResetPixels(void) {
|
|||||||
struct DrawTextArgs args;
|
struct DrawTextArgs args;
|
||||||
int x;
|
int x;
|
||||||
|
|
||||||
|
if (Launcher_Screen && Launcher_Screen->HidesBackground) {
|
||||||
|
Launcher_ResetArea(0, 0, Game_Width, Game_Height);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
if (Launcher_ClassicBackground && terrainBmp.Scan0) {
|
if (Launcher_ClassicBackground && terrainBmp.Scan0) {
|
||||||
Launcher_ClearTile(0, 0, Game_Width, TILESIZE, TILESIZE);
|
Launcher_ClearTile(0, 0, Game_Width, TILESIZE, TILESIZE);
|
||||||
Launcher_ClearTile(0, TILESIZE, Game_Width, Game_Height - TILESIZE, 0);
|
Launcher_ClearTile(0, TILESIZE, Game_Width, Game_Height - TILESIZE, 0);
|
||||||
|
@ -276,7 +276,7 @@ static void WoM_ParseConfig(struct AsyncRequest* item) {
|
|||||||
PackedCol col;
|
PackedCol col;
|
||||||
|
|
||||||
String_InitArray(line, lineBuffer);
|
String_InitArray(line, lineBuffer);
|
||||||
Stream_ReadonlyMemory(&mem, item->ResultData, item->ResultSize);
|
Stream_ReadonlyMemory(&mem, item->Data, item->Size);
|
||||||
|
|
||||||
while (!Stream_ReadLine(&mem, &line)) {
|
while (!Stream_ReadLine(&mem, &line)) {
|
||||||
Platform_Log(&line);
|
Platform_Log(&line);
|
||||||
@ -311,7 +311,7 @@ static void WoM_Tick(void) {
|
|||||||
struct AsyncRequest item;
|
struct AsyncRequest item;
|
||||||
if (!AsyncDownloader_Get(&wom_identifier, &item)) return;
|
if (!AsyncDownloader_Get(&wom_identifier, &item)) return;
|
||||||
|
|
||||||
if (item.ResultData) WoM_ParseConfig(&item);
|
if (item.Data) WoM_ParseConfig(&item);
|
||||||
ASyncRequest_Free(&item);
|
ASyncRequest_Free(&item);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1384,8 +1384,8 @@ static ReturnCode Http_GetData(struct AsyncRequest* req, HINTERNET handle, volat
|
|||||||
buffer = Mem_Alloc(size, 1, "http get data");
|
buffer = Mem_Alloc(size, 1, "http get data");
|
||||||
totalRead = 0;
|
totalRead = 0;
|
||||||
|
|
||||||
req->ResultData = buffer;
|
req->Data = buffer;
|
||||||
req->ResultSize = 0;
|
req->Size = 0;
|
||||||
|
|
||||||
for (;;) {
|
for (;;) {
|
||||||
if (!InternetQueryDataAvailable(handle, &avail, 0, 0)) break;
|
if (!InternetQueryDataAvailable(handle, &avail, 0, 0)) break;
|
||||||
@ -1395,7 +1395,7 @@ static ReturnCode Http_GetData(struct AsyncRequest* req, HINTERNET handle, volat
|
|||||||
if (totalRead + avail > size) {
|
if (totalRead + avail > size) {
|
||||||
size = totalRead + avail;
|
size = totalRead + avail;
|
||||||
buffer = Mem_Realloc(buffer, size, 1, "http inc data");
|
buffer = Mem_Realloc(buffer, size, 1, "http inc data");
|
||||||
req->ResultData = buffer;
|
req->Data = buffer;
|
||||||
}
|
}
|
||||||
|
|
||||||
success = InternetReadFile(handle, &buffer[totalRead], avail, &read);
|
success = InternetReadFile(handle, &buffer[totalRead], avail, &read);
|
||||||
@ -1404,7 +1404,7 @@ static ReturnCode Http_GetData(struct AsyncRequest* req, HINTERNET handle, volat
|
|||||||
|
|
||||||
totalRead += read;
|
totalRead += read;
|
||||||
if (req->ContentLength) *progress = (int)(100.0f * totalRead / size);
|
if (req->ContentLength) *progress = (int)(100.0f * totalRead / size);
|
||||||
req->ResultSize += read;
|
req->Size += read;
|
||||||
}
|
}
|
||||||
|
|
||||||
*progress = 100;
|
*progress = 100;
|
||||||
|
@ -82,7 +82,7 @@ void ServerConnection_CheckAsyncResources(void) {
|
|||||||
struct AsyncRequest item;
|
struct AsyncRequest item;
|
||||||
if (!AsyncDownloader_Get(&texPack, &item)) return;
|
if (!AsyncDownloader_Get(&texPack, &item)) return;
|
||||||
|
|
||||||
if (item.ResultData) {
|
if (item.Data) {
|
||||||
TexturePack_Extract_Req(&item);
|
TexturePack_Extract_Req(&item);
|
||||||
} else if (item.Result) {
|
} else if (item.Result) {
|
||||||
Chat_Add1("&cError %i when trying to download texture pack", &item.Result);
|
Chat_Add1("&cError %i when trying to download texture pack", &item.Result);
|
||||||
|
@ -719,8 +719,8 @@ void TexturePack_Extract_Req(struct AsyncRequest* item) {
|
|||||||
|
|
||||||
url = String_FromRawArray(item->URL);
|
url = String_FromRawArray(item->URL);
|
||||||
String_Copy(&World_TextureUrl, &url);
|
String_Copy(&World_TextureUrl, &url);
|
||||||
data = item->ResultData;
|
data = item->Data;
|
||||||
len = item->ResultSize;
|
len = item->Size;
|
||||||
|
|
||||||
etag = String_FromRawArray(item->Etag);
|
etag = String_FromRawArray(item->Etag);
|
||||||
TextureCache_Set(&url, data, len);
|
TextureCache_Set(&url, data, len);
|
||||||
|
Loading…
x
Reference in New Issue
Block a user