mirror of
https://github.com/ClassiCube/ClassiCube.git
synced 2025-09-15 18:45:23 -04:00
Fix crashing when going back to main menu in launcher, fix error in chat from missing plugins directory
This commit is contained in:
parent
3aea8a5b1c
commit
48fce2f25f
@ -1095,11 +1095,11 @@ static ReturnCode Zip_ReadLocalFileHeader(struct ZipState* state, struct ZipEntr
|
||||
|
||||
if (method == 0) {
|
||||
Stream_ReadonlyPortion(&portion, stream, uncompressedSize);
|
||||
return state->ProcessEntry(&path, &portion, state->Obj);
|
||||
return state->ProcessEntry(&path, &portion, state);
|
||||
} else if (method == 8) {
|
||||
Stream_ReadonlyPortion(&portion, stream, compressedSize);
|
||||
Inflate_MakeStream(&compStream, &inflate, &portion);
|
||||
return state->ProcessEntry(&path, &compStream, state->Obj);
|
||||
return state->ProcessEntry(&path, &compStream, state);
|
||||
} else {
|
||||
Platform_Log1("Unsupported.zip entry compression method: %i", &method);
|
||||
/* TODO: Should this be an error */
|
||||
@ -1155,7 +1155,7 @@ enum ZipSig {
|
||||
ZIP_SIG_LOCALFILEHEADER = 0x04034b50
|
||||
};
|
||||
|
||||
static ReturnCode Zip_DefaultProcessor(const String* path, struct Stream* data, void* obj) { return 0; }
|
||||
static ReturnCode Zip_DefaultProcessor(const String* path, struct Stream* data, struct ZipState* s) { return 0; }
|
||||
static bool Zip_DefaultSelector(const String* path) { return true; }
|
||||
void Zip_Init(struct ZipState* state, struct Stream* input) {
|
||||
state->Input = input;
|
||||
|
@ -112,6 +112,7 @@ CC_API void ZLib_MakeStream(struct Stream* stream, struct ZLibState* state, stru
|
||||
/* Minimal data needed to describe an entry in a .zip archive. */
|
||||
struct ZipEntry { uint32_t CompressedSize, UncompressedSize, LocalHeaderOffset; };
|
||||
#define ZIP_MAX_ENTRIES 2048
|
||||
struct ZipState;
|
||||
|
||||
/* Stores state for reading and processing entries in a .zip archive. */
|
||||
struct ZipState {
|
||||
@ -121,11 +122,11 @@ struct ZipState {
|
||||
/* obj is user specified in state.Obj variable */
|
||||
/* Return non-zero to indicate an error and stop further processing. */
|
||||
/* NOTE: data stream MAY NOT be seekable. (i.e. entry data might be compressed) */
|
||||
ReturnCode (*ProcessEntry)(const String* path, struct Stream* data, void* obj);
|
||||
ReturnCode (*ProcessEntry)(const String* path, struct Stream* data, struct ZipState* state);
|
||||
/* Predicate used to select which entries in a .zip archive get processed. */
|
||||
/* NOTE: returning false entirely skips the entry. (avoids pointless seek to entry) */
|
||||
bool (*SelectEntry)(const String* path);
|
||||
/* Generic object/pointer passed to ProcessEntry callback. */
|
||||
/* Generic object/pointer for ProcessEntry callback. */
|
||||
void* Obj;
|
||||
|
||||
/* (internal) Number of entries selected by SelectEntry. */
|
||||
|
@ -14,7 +14,7 @@ extern struct IGameComponent Drawer2D_Component;
|
||||
|
||||
void DrawTextArgs_Make(struct DrawTextArgs* args, STRING_REF const String* text, const FontDesc* font, bool useShadow);
|
||||
void DrawTextArgs_MakeEmpty(struct DrawTextArgs* args, const FontDesc* font, bool useShadow);
|
||||
/* Initialises the given font. When Drawer2D_BitmappedText is false, makes native font handle. */
|
||||
/* Initialises the given font. When Drawer2D_BitmappedText is false, creates native font handle using Font_Make. */
|
||||
CC_NOINLINE void Drawer2D_MakeFont(FontDesc* desc, int size, int style);
|
||||
|
||||
/* Whether text should be drawn and measured using the currently set font bitmap. */
|
||||
|
@ -1133,11 +1133,14 @@ static void ServersScreen_Refresh(void* w, int x, int y) {
|
||||
LWidget_Redraw(btn);
|
||||
}
|
||||
|
||||
static void ServersScreen_Init(struct LScreen* s_) {
|
||||
struct ServersScreen* s = (struct ServersScreen*)s_;
|
||||
static void ServersScreen_SearchChanged(struct LInput* w) {
|
||||
struct ServersScreen* s = &ServersScreen_Instance;
|
||||
LTable_Filter(&s->Table, &w->Text);
|
||||
LWidget_Draw(&s->Table);
|
||||
}
|
||||
|
||||
Font_Make(&s->RowFont, &Drawer2D_FontName, 11, FONT_STYLE_NORMAL);
|
||||
if (s->NumWidgets) return;
|
||||
static void ServersScreen_InitWidgets(struct LScreen* s_) {
|
||||
struct ServersScreen* s = (struct ServersScreen*)s_;
|
||||
s->Widgets = s->_widgets;
|
||||
|
||||
LScreen_Input(s_, &s->IptName, 370, false, "&gSearch servers..");
|
||||
@ -1151,10 +1154,25 @@ static void ServersScreen_Init(struct LScreen* s_) {
|
||||
s->BtnConnect.OnClick = ServersScreen_Connect;
|
||||
s->BtnRefresh.OnClick = ServersScreen_Refresh;
|
||||
|
||||
s->IptName.TextChanged = ServersScreen_SearchChanged;
|
||||
|
||||
LTable_Init(&s->Table, &Launcher_TextFont, &s->RowFont);
|
||||
s->Widgets[s->NumWidgets++] = (struct LWidget*)&s->Table;
|
||||
}
|
||||
|
||||
static void ServersScreen_Init(struct LScreen* s_) {
|
||||
struct ServersScreen* s = (struct ServersScreen*)s_;
|
||||
Drawer2D_MakeFont(&s->RowFont, 11, FONT_STYLE_NORMAL);
|
||||
|
||||
if (!s->NumWidgets) ServersScreen_InitWidgets(s_);
|
||||
s->Table.RowFont = s->RowFont;
|
||||
|
||||
s->IptHash.Text.length = 0;
|
||||
s->IptName.Text.length = 0;
|
||||
LTable_Filter(&s->Table, &s->IptHash.Text);
|
||||
LScreen_SelectWidget(s_, (struct LWidget*)&s->IptName, false);
|
||||
}
|
||||
|
||||
static void ServersScreen_Free(struct LScreen* s_) {
|
||||
struct ServersScreen* s = (struct ServersScreen*)s_;
|
||||
Font_Free(&s->RowFont);
|
||||
|
@ -1,5 +1,5 @@
|
||||
#include "Launcher.h"
|
||||
#include "LWeb.h"
|
||||
#include "Launcher.h"
|
||||
#include "Platform.h"
|
||||
#include "Stream.h"
|
||||
|
||||
@ -306,6 +306,7 @@ static void ServerInfo_Init(struct ServerInfo* info) {
|
||||
info->MaxPlayers = 0;
|
||||
info->Uptime = 0;
|
||||
info->Featured = false;
|
||||
info->_order = -100000;
|
||||
}
|
||||
|
||||
static void ServerInfo_Parse(struct JsonContext* ctx, const String* val) {
|
||||
@ -371,10 +372,13 @@ static void FetchServersTask_Next(struct JsonContext* ctx) {
|
||||
}
|
||||
|
||||
static void FetchServersTask_Handle(uint8_t* data, uint32_t len) {
|
||||
/* -1 because servers is surrounded by a { */
|
||||
FetchServersTask.NumServers = -1;
|
||||
Json_Handle(data, len, NULL, NULL, FetchServersTask_Count);
|
||||
if (!FetchServersTask.NumServers) return;
|
||||
|
||||
if (FetchServersTask.NumServers <= 0) return;
|
||||
FetchServersTask.Servers = Mem_Alloc(FetchServersTask.NumServers, sizeof(struct ServerInfo), "servers list");
|
||||
|
||||
/* -2 because servers is surrounded by a { */
|
||||
curServer = FetchServersTask.Servers - 2;
|
||||
Json_Handle(data, len, ServerInfo_Parse, NULL, FetchServersTask_Next);
|
||||
|
@ -35,6 +35,7 @@ struct ServerInfo {
|
||||
int Players, MaxPlayers, Port, Uptime;
|
||||
bool Featured;
|
||||
char _Buffer[6][STRING_SIZE];
|
||||
int _order; /* (internal) order in servers table */
|
||||
};
|
||||
|
||||
struct LWebTask;
|
||||
|
@ -668,6 +668,7 @@ static struct LTableColumn tableColumns[4] = {
|
||||
#define CELL_XPADDING 3
|
||||
|
||||
|
||||
#define LTable_Get(row) &FetchServersTask.Servers[FetchServersTask.Servers[row]._order]
|
||||
void LTable_DrawHeaders(struct LTable* w) {
|
||||
BitmapCol gridCol = BITMAPCOL_CONST(20, 20, 10, 255);
|
||||
struct DrawTextArgs args;
|
||||
@ -697,6 +698,7 @@ void LTable_DrawHeaders(struct LTable* w) {
|
||||
void LTable_DrawRows(struct LTable* w) {
|
||||
BitmapCol gridCol = BITMAPCOL_CONST(20, 20, 10, 255);
|
||||
String str; char strBuffer[STRING_SIZE];
|
||||
struct ServerInfo* entry;
|
||||
struct DrawTextArgs args;
|
||||
int i, x, y, row;
|
||||
|
||||
@ -711,12 +713,14 @@ void LTable_DrawRows(struct LTable* w) {
|
||||
Drawer2D_Clear(&Launcher_Framebuffer, gridCol,
|
||||
x, y, w->Width, w->RowHeight);
|
||||
}
|
||||
if (row >= FetchServersTask.NumServers) continue; /* TODO: w->Count instead */
|
||||
|
||||
if (row >= w->RowsCount) continue;
|
||||
entry = LTable_Get(row);
|
||||
|
||||
for (i = 0; i < w->NumColumns; i++) {
|
||||
x += CELL_XPADDING;
|
||||
args.Text.length = 0;
|
||||
w->Columns[i].GetValue(&FetchServersTask.Servers[row], &args.Text);
|
||||
w->Columns[i].GetValue(entry, &args.Text);
|
||||
|
||||
Drawer2D_DrawClippedText(&Launcher_Framebuffer, &args,
|
||||
x, y, w->Columns[i].Width);
|
||||
@ -1083,3 +1087,21 @@ void LTable_Init(struct LTable* w, const FontDesc* hdrFont, const FontDesc* rowF
|
||||
LTable_StopDragging(w);
|
||||
LTable_Reposition(w);
|
||||
}
|
||||
|
||||
void LTable_Filter(struct LTable* w, const String* filter) {
|
||||
int i, j, count;
|
||||
|
||||
count = FetchServersTask.NumServers;
|
||||
for (i = 0, j = 0; i < count; i++) {
|
||||
if (String_CaselessContains(&FetchServersTask.Servers[i].Name, filter)) {
|
||||
FetchServersTask.Servers[j++]._order = i;
|
||||
}
|
||||
}
|
||||
|
||||
w->RowsCount = j;
|
||||
for (; j < count; j++) {
|
||||
FetchServersTask.Servers[j]._order = -100000;
|
||||
}
|
||||
/* TODO: preserve selected server */
|
||||
/* TODO: Resort entries again */
|
||||
}
|
@ -137,8 +137,10 @@ struct LTable {
|
||||
int RowsBegY, RowHeight;
|
||||
/* Y height of headers. */
|
||||
int HdrHeight;
|
||||
/* Number of rows currently visible. */
|
||||
/* Maximum number of rows visible. */
|
||||
int VisibleRows;
|
||||
/* Total number of rows in the table (after filter is applied). */
|
||||
int RowsCount;
|
||||
|
||||
/* Index of column currently being dragged. */
|
||||
int DraggingColumn;
|
||||
@ -149,4 +151,10 @@ struct LTable {
|
||||
void LTable_Init(struct LTable* table, const FontDesc* hdrFont, const FontDesc* rowFont);
|
||||
CC_NOINLINE void LTable_StopDragging(struct LTable* table);
|
||||
void LTable_Reposition(struct LTable* table);
|
||||
/* Filters rows to only show those containing 'filter' in the name. */
|
||||
void LTable_Filter(struct LTable* table, const String* filter);
|
||||
/* Attempts to select the row whose hash equals the given hash. Scrolls table if needed. */
|
||||
void LTable_SetSelected(struct LTable* table, const String* hash);
|
||||
/* Attempts to get the hash of the currently selected row. */
|
||||
void LTable_GetSelected(struct LTable* table, String* hash);
|
||||
#endif
|
||||
|
@ -197,10 +197,10 @@ static void Launcher_Init(void) {
|
||||
Event_RegisterMouseMove(&MouseEvents_Moved, NULL, Launcher_MouseMove);
|
||||
Event_RegisterFloat(&MouseEvents_Wheel, NULL, Launcher_MouseWheel);
|
||||
|
||||
Font_Make(&logoFont, &Drawer2D_FontName, 32, FONT_STYLE_NORMAL);
|
||||
Font_Make(&Launcher_TitleFont, &Drawer2D_FontName, 16, FONT_STYLE_BOLD);
|
||||
Font_Make(&Launcher_TextFont, &Drawer2D_FontName, 14, FONT_STYLE_NORMAL);
|
||||
Font_Make(&Launcher_HintFont, &Drawer2D_FontName, 12, FONT_STYLE_ITALIC);
|
||||
Drawer2D_MakeFont(&logoFont, 32, FONT_STYLE_NORMAL);
|
||||
Drawer2D_MakeFont(&Launcher_TitleFont, 16, FONT_STYLE_BOLD);
|
||||
Drawer2D_MakeFont(&Launcher_TextFont, 14, FONT_STYLE_NORMAL);
|
||||
Drawer2D_MakeFont(&Launcher_HintFont, 12, FONT_STYLE_ITALIC);
|
||||
|
||||
Drawer2D_Cols['g'] = col;
|
||||
Utils_EnsureDirectory("texpacks");
|
||||
@ -377,7 +377,7 @@ static void Launcher_LoadTextures(Bitmap* bmp) {
|
||||
0, 0, TILESIZE, TILESIZE);
|
||||
}
|
||||
|
||||
static ReturnCode Launcher_ProcessZipEntry(const String* path, struct Stream* data, void* obj) {
|
||||
static ReturnCode Launcher_ProcessZipEntry(const String* path, struct Stream* data, struct ZipState* s) {
|
||||
Bitmap bmp;
|
||||
ReturnCode res;
|
||||
|
||||
|
@ -184,7 +184,7 @@ CC_API void Waitable_Wait(void* handle);
|
||||
CC_API void Waitable_WaitFor(void* handle, uint32_t milliseconds);
|
||||
|
||||
/* Gets the list of all supported font names on this platform. */
|
||||
CC_API void Font_GetNames(StringsBuffer* buffer);
|
||||
void Font_GetNames(StringsBuffer* buffer);
|
||||
/* Finds the path of the given font, with closest matching style */
|
||||
String Font_Lookup(const String* fontName, int style);
|
||||
/* Allocates a new font from the given arguments. */
|
||||
|
@ -88,6 +88,7 @@ int main(int argc, char** argv) {
|
||||
Utils_EnsureDirectory("maps");
|
||||
Utils_EnsureDirectory("texpacks");
|
||||
Utils_EnsureDirectory("texturecache");
|
||||
Utils_EnsureDirectory("plugins");
|
||||
Options_Load();
|
||||
|
||||
if (argsCount == 0) {
|
||||
|
@ -364,9 +364,9 @@ static bool ClassicPatcher_SelectEntry(const String* path ) {
|
||||
return Resources_FindTex(&name) != NULL;
|
||||
}
|
||||
|
||||
static ReturnCode ClassicPatcher_ProcessEntry(const String* path, struct Stream* data, void* obj) {
|
||||
static ReturnCode ClassicPatcher_ProcessEntry(const String* path, struct Stream* data, struct ZipState* state) {
|
||||
static const String guiClassicPng = String_FromConst("gui_classic.png");
|
||||
struct Stream* s = obj;
|
||||
struct Stream* s = state->Obj;
|
||||
struct ResourceTexture* entry;
|
||||
String name;
|
||||
|
||||
@ -465,8 +465,8 @@ static ReturnCode ModernPatcher_MakeAnimations(struct Stream* s, struct Stream*
|
||||
return ZipPatcher_WritePng(s, entry, &anim);
|
||||
}
|
||||
|
||||
static ReturnCode ModernPatcher_ProcessEntry(const String* path, struct Stream* data, void* obj) {
|
||||
struct Stream* s = obj;
|
||||
static ReturnCode ModernPatcher_ProcessEntry(const String* path, struct Stream* data, struct ZipState* state) {
|
||||
struct Stream* s = state->Obj;
|
||||
struct ResourceTexture* entry;
|
||||
struct TilePatch* tile;
|
||||
String name;
|
||||
|
@ -621,7 +621,7 @@ void TextureCache_SetLastModified(const String* url, const TimeMS* lastModified)
|
||||
/*########################################################################################################################*
|
||||
*-------------------------------------------------------TexturePack-------------------------------------------------------*
|
||||
*#########################################################################################################################*/
|
||||
static ReturnCode TexturePack_ProcessZipEntry(const String* path, struct Stream* stream, void* obj) {
|
||||
static ReturnCode TexturePack_ProcessZipEntry(const String* path, struct Stream* stream, struct ZipState* s) {
|
||||
String name = *path;
|
||||
Utils_UNSAFE_GetFilename(&name);
|
||||
Event_RaiseEntry(&TextureEvents_FileChanged, stream, &name);
|
||||
|
Loading…
x
Reference in New Issue
Block a user