mirror of
https://github.com/ClassiCube/ClassiCube.git
synced 2025-09-19 04:26:52 -04:00
Fix .zip with too many entries not getting loaded
This commit is contained in:
parent
5de42ad3d3
commit
7813b5719e
@ -4,9 +4,10 @@
|
|||||||
Copyright 2017 ClassicalSharp | Licensed under BSD-3
|
Copyright 2017 ClassicalSharp | Licensed under BSD-3
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#define PROGRAM_MAX_CMDARGS 5
|
#define GAME_MAX_CMDARGS 5
|
||||||
#define PROGRAM_APP_NAME "ClassiCube 0.99.9.2"
|
#define GAME_APP_NAME "ClassiCube 0.99.9.2"
|
||||||
#define PROGRAM_APP_VER "0.99.9.2"
|
#define GAME_APP_VER "0.99.9.2"
|
||||||
|
#define GAME_API_VER 1
|
||||||
|
|
||||||
/* Max number of characters strings can have. */
|
/* Max number of characters strings can have. */
|
||||||
#define STRING_SIZE 64
|
#define STRING_SIZE 64
|
||||||
|
@ -1107,34 +1107,45 @@ static ReturnCode Zip_ReadLocalFileHeader(struct ZipState* state, struct ZipEntr
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static ReturnCode Zip_ReadCentralDirectory(struct ZipState* state, struct ZipEntry* entry) {
|
static ReturnCode Zip_ReadCentralDirectory(struct ZipState* state) {
|
||||||
struct Stream* stream = state->Input;
|
struct Stream* stream = state->Input;
|
||||||
|
struct ZipEntry* entry;
|
||||||
uint8_t header[42];
|
uint8_t header[42];
|
||||||
|
|
||||||
|
String path; char pathBuffer[ZIP_MAXNAMELEN];
|
||||||
int pathLen, extraLen, commentLen;
|
int pathLen, extraLen, commentLen;
|
||||||
ReturnCode res;
|
ReturnCode res;
|
||||||
if ((res = Stream_Read(stream, header, sizeof(header)))) return res;
|
if ((res = Stream_Read(stream, header, sizeof(header)))) return res;
|
||||||
|
|
||||||
entry->CompressedSize = Stream_GetU32_LE(&header[16]);
|
|
||||||
entry->UncompressedSize = Stream_GetU32_LE(&header[20]);
|
|
||||||
|
|
||||||
pathLen = Stream_GetU16_LE(&header[24]);
|
pathLen = Stream_GetU16_LE(&header[24]);
|
||||||
|
path = String_Init(pathBuffer, pathLen, pathLen);
|
||||||
|
if (pathLen > ZIP_MAXNAMELEN) return ZIP_ERR_FILENAME_LEN;
|
||||||
|
if ((res = Stream_Read(stream, pathBuffer, pathLen))) return res;
|
||||||
|
|
||||||
|
/* skip data following central directory entry header */
|
||||||
extraLen = Stream_GetU16_LE(&header[26]);
|
extraLen = Stream_GetU16_LE(&header[26]);
|
||||||
commentLen = Stream_GetU16_LE(&header[28]);
|
commentLen = Stream_GetU16_LE(&header[28]);
|
||||||
|
if ((res = stream->Skip(stream, extraLen + commentLen))) return res;
|
||||||
|
|
||||||
|
if (!state->SelectEntry(&path)) return 0;
|
||||||
|
if (state->_usedEntries >= ZIP_MAX_ENTRIES) return ZIP_ERR_TOO_MANY_ENTRIES;
|
||||||
|
entry = &state->Entries[state->_usedEntries++];
|
||||||
|
|
||||||
|
entry->CompressedSize = Stream_GetU32_LE(&header[16]);
|
||||||
|
entry->UncompressedSize = Stream_GetU32_LE(&header[20]);
|
||||||
entry->LocalHeaderOffset = Stream_GetU32_LE(&header[38]);
|
entry->LocalHeaderOffset = Stream_GetU32_LE(&header[38]);
|
||||||
/* skip data following central directory entry header */
|
return 0;
|
||||||
return stream->Skip(stream, pathLen + extraLen + commentLen);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static ReturnCode Zip_ReadEndOfCentralDirectory(struct ZipState* state, uint32_t* centralDirectoryOffset) {
|
static ReturnCode Zip_ReadEndOfCentralDirectory(struct ZipState* state) {
|
||||||
struct Stream* stream = state->Input;
|
struct Stream* stream = state->Input;
|
||||||
uint8_t header[18];
|
uint8_t header[18];
|
||||||
|
|
||||||
ReturnCode res;
|
ReturnCode res;
|
||||||
if ((res = Stream_Read(stream, header, sizeof(header)))) return res;
|
if ((res = Stream_Read(stream, header, sizeof(header)))) return res;
|
||||||
|
|
||||||
state->EntriesCount = Stream_GetU16_LE(&header[6]);
|
state->_totalEntries = Stream_GetU16_LE(&header[6]);
|
||||||
*centralDirectoryOffset = Stream_GetU32_LE(&header[12]);
|
state->_centralDirBeg = Stream_GetU32_LE(&header[12]);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1149,19 +1160,17 @@ static bool Zip_DefaultSelector(const String* path) { return true; }
|
|||||||
void Zip_Init(struct ZipState* state, struct Stream* input) {
|
void Zip_Init(struct ZipState* state, struct Stream* input) {
|
||||||
state->Input = input;
|
state->Input = input;
|
||||||
state->Obj = NULL;
|
state->Obj = NULL;
|
||||||
state->EntriesCount = 0;
|
|
||||||
state->ProcessEntry = Zip_DefaultProcessor;
|
state->ProcessEntry = Zip_DefaultProcessor;
|
||||||
state->SelectEntry = Zip_DefaultSelector;
|
state->SelectEntry = Zip_DefaultSelector;
|
||||||
}
|
}
|
||||||
|
|
||||||
ReturnCode Zip_Extract(struct ZipState* state) {
|
ReturnCode Zip_Extract(struct ZipState* state) {
|
||||||
struct Stream* stream = state->Input;
|
struct Stream* stream = state->Input;
|
||||||
uint32_t stream_len, centralDirOffset;
|
uint32_t stream_len;
|
||||||
uint32_t sig = 0;
|
uint32_t sig = 0;
|
||||||
int i, count;
|
int i, count;
|
||||||
|
|
||||||
ReturnCode res;
|
ReturnCode res;
|
||||||
state->EntriesCount = 0;
|
|
||||||
if ((res = stream->Length(stream, &stream_len))) return res;
|
if ((res = stream->Length(stream, &stream_len))) return res;
|
||||||
|
|
||||||
/* At -22 for nearly all zips, but try a bit further back in case of comment */
|
/* At -22 for nearly all zips, but try a bit further back in case of comment */
|
||||||
@ -1175,19 +1184,19 @@ ReturnCode Zip_Extract(struct ZipState* state) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (sig != ZIP_SIG_ENDOFCENTRALDIR) return ZIP_ERR_NO_END_OF_CENTRAL_DIR;
|
if (sig != ZIP_SIG_ENDOFCENTRALDIR) return ZIP_ERR_NO_END_OF_CENTRAL_DIR;
|
||||||
res = Zip_ReadEndOfCentralDirectory(state, ¢ralDirOffset);
|
res = Zip_ReadEndOfCentralDirectory(state);
|
||||||
if (res) return res;
|
if (res) return res;
|
||||||
|
|
||||||
res = stream->Seek(stream, centralDirOffset);
|
res = stream->Seek(stream, state->_centralDirBeg);
|
||||||
if (res) return ZIP_ERR_SEEK_CENTRAL_DIR;
|
if (res) return ZIP_ERR_SEEK_CENTRAL_DIR;
|
||||||
if (state->EntriesCount > ZIP_MAX_ENTRIES) return ZIP_ERR_TOO_MANY_ENTRIES;
|
state->_usedEntries = 0;
|
||||||
|
|
||||||
/* Read all the central directory entries */
|
/* Read all the central directory entries */
|
||||||
for (count = 0; count < state->EntriesCount; count++) {
|
for (i = 0; i < state->_totalEntries; i++) {
|
||||||
if ((res = Stream_ReadU32_LE(stream, &sig))) return res;
|
if ((res = Stream_ReadU32_LE(stream, &sig))) return res;
|
||||||
|
|
||||||
if (sig == ZIP_SIG_CENTRALDIR) {
|
if (sig == ZIP_SIG_CENTRALDIR) {
|
||||||
res = Zip_ReadCentralDirectory(state, &state->Entries[count]);
|
res = Zip_ReadCentralDirectory(state);
|
||||||
if (res) return res;
|
if (res) return res;
|
||||||
} else if (sig == ZIP_SIG_ENDOFCENTRALDIR) {
|
} else if (sig == ZIP_SIG_ENDOFCENTRALDIR) {
|
||||||
break;
|
break;
|
||||||
@ -1197,7 +1206,7 @@ ReturnCode Zip_Extract(struct ZipState* state) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* Now read the local file header entries */
|
/* Now read the local file header entries */
|
||||||
for (i = 0; i < count; i++) {
|
for (i = 0; i < state->_usedEntries; i++) {
|
||||||
struct ZipEntry* entry = &state->Entries[i];
|
struct ZipEntry* entry = &state->Entries[i];
|
||||||
res = stream->Seek(stream, entry->LocalHeaderOffset);
|
res = stream->Seek(stream, entry->LocalHeaderOffset);
|
||||||
if (res) return ZIP_ERR_SEEK_LOCAL_DIR;
|
if (res) return ZIP_ERR_SEEK_LOCAL_DIR;
|
||||||
|
@ -67,7 +67,7 @@ struct InflateState {
|
|||||||
|
|
||||||
/* Initialises DEFLATE decompressor state to defaults. */
|
/* Initialises DEFLATE decompressor state to defaults. */
|
||||||
CC_API void Inflate_Init(struct InflateState* state, struct Stream* source);
|
CC_API void Inflate_Init(struct InflateState* state, struct Stream* source);
|
||||||
/* Attempts to decompress all currently pending data. */
|
/* Attempts to decompress as much of the currently pending data as possible. */
|
||||||
/* NOTE: This is a low level call - usually you should use Inflate_MakeStream. */
|
/* NOTE: This is a low level call - usually you should use Inflate_MakeStream. */
|
||||||
void Inflate_Process(struct InflateState* state);
|
void Inflate_Process(struct InflateState* state);
|
||||||
/* Deompresses input data read from another stream using DEFLATE. Read only stream. */
|
/* Deompresses input data read from another stream using DEFLATE. Read only stream. */
|
||||||
@ -122,13 +122,18 @@ struct ZipState {
|
|||||||
/* Return non-zero to indicate an error and stop further processing. */
|
/* 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) */
|
/* 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, void* obj);
|
||||||
/* Predicate used to select which entries in a .zip archive get proessed. */
|
/* Predicate used to select which entries in a .zip archive get processed. */
|
||||||
/* NOTE: returning false entirely skips the entry. (avoids pointless seek to entry) */
|
/* NOTE: returning false entirely skips the entry. (avoids pointless seek to entry) */
|
||||||
bool (*SelectEntry)(const String* path);
|
bool (*SelectEntry)(const String* path);
|
||||||
/* Generic object/pointer passed to ProcessEntry callback. */
|
/* Generic object/pointer passed to ProcessEntry callback. */
|
||||||
void* Obj;
|
void* Obj;
|
||||||
/* Number of entries in the .zip archive. */
|
|
||||||
int EntriesCount;
|
/* (internal) Number of entries selected by SelectEntry. */
|
||||||
|
int _usedEntries;
|
||||||
|
/* (internal) Total number of entries in the archive. */
|
||||||
|
int _totalEntries;
|
||||||
|
/* (internal) Offset to central directory entries. */
|
||||||
|
uint32_t _centralDirBeg;
|
||||||
/* Data for each entry in the .zip archive. */
|
/* Data for each entry in the .zip archive. */
|
||||||
struct ZipEntry Entries[ZIP_MAX_ENTRIES];
|
struct ZipEntry Entries[ZIP_MAX_ENTRIES];
|
||||||
};
|
};
|
||||||
|
48
src/Game.c
48
src/Game.c
@ -372,6 +372,41 @@ static void Game_LoadOptions(void) {
|
|||||||
}*/
|
}*/
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void Game_LoadPlugin(const String* filename, void* obj) {
|
||||||
|
void* lib;
|
||||||
|
void* verSymbol; /* EXPORT int Plugin_ApiVersion = GAME_API_VER; */
|
||||||
|
void* compSymbol; /* EXPORT struct IGameComponent Plugin_Component = { (whatever) } */
|
||||||
|
int ver;
|
||||||
|
ReturnCode res;
|
||||||
|
|
||||||
|
res = Platform_LoadLibrary(filename, &lib);
|
||||||
|
if (res) { Chat_LogError2(res, "loading plugin", filename); return; }
|
||||||
|
|
||||||
|
res = Platform_GetSymbol(lib, "Plugin_ApiVersion", &verSymbol);
|
||||||
|
if (res) { Chat_LogError2(res, "getting plugin version", filename); return; }
|
||||||
|
res = Platform_GetSymbol(lib, "Plugin_Component", &compSymbol);
|
||||||
|
if (res) { Chat_LogError2(res, "initing plugin", filename); return; }
|
||||||
|
|
||||||
|
ver = *((int*)verSymbol);
|
||||||
|
if (ver < GAME_API_VER) {
|
||||||
|
Chat_Add1("&c%s plugin is outdated! Try getting a more recent version.", filename);
|
||||||
|
return;
|
||||||
|
} else if (ver > GAME_API_VER) {
|
||||||
|
Chat_Add1("&cYour game is too outdated to use %s plugin! Try updating it.", filename);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
Game_AddComponent((struct IGameComponent*)compSymbol);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void Game_LoadPlugins(void) {
|
||||||
|
const static String dir = String_FromConst("plugins");
|
||||||
|
ReturnCode res;
|
||||||
|
|
||||||
|
res = Directory_Enum(&dir, NULL, Game_LoadPlugin);
|
||||||
|
if (res) Chat_LogError(res, "enumerating plugins directory");
|
||||||
|
}
|
||||||
|
|
||||||
void Game_Free(void* obj);
|
void Game_Free(void* obj);
|
||||||
static void Game_Load(void) {
|
static void Game_Load(void) {
|
||||||
String title; char titleBuffer[STRING_SIZE];
|
String title; char titleBuffer[STRING_SIZE];
|
||||||
@ -438,22 +473,13 @@ static void Game_Load(void) {
|
|||||||
Game_AddComponent(&Audio_Component);
|
Game_AddComponent(&Audio_Component);
|
||||||
Game_AddComponent(&AxisLinesRenderer_Component);
|
Game_AddComponent(&AxisLinesRenderer_Component);
|
||||||
|
|
||||||
/* TODO: plugin dll support */
|
//Game_LoadPlugins();
|
||||||
/* List<string> nonLoaded = PluginLoader.LoadAll(); */
|
|
||||||
|
|
||||||
for (comp = comps_head; comp; comp = comp->Next) {
|
for (comp = comps_head; comp; comp = comp->Next) {
|
||||||
if (comp->Init) comp->Init();
|
if (comp->Init) comp->Init();
|
||||||
}
|
}
|
||||||
Game_ExtractInitialTexturePack();
|
|
||||||
|
|
||||||
|
Game_ExtractInitialTexturePack();
|
||||||
entTaskI = ScheduledTask_Add(GAME_DEF_TICKS, Entities_Tick);
|
entTaskI = ScheduledTask_Add(GAME_DEF_TICKS, Entities_Tick);
|
||||||
/* TODO: plugin dll support */
|
|
||||||
/* if (nonLoaded != null) {
|
|
||||||
for (int i = 0; i < nonLoaded.Count; i++) {
|
|
||||||
Overlay warning = new PluginOverlay(this, nonLoaded[i]);
|
|
||||||
Gui_ShowOverlay(warning, false);
|
|
||||||
}
|
|
||||||
}*/
|
|
||||||
|
|
||||||
if (Gfx_WarnIfNecessary()) EnvRenderer_SetMode(EnvRenderer_Minimal | ENV_LEGACY);
|
if (Gfx_WarnIfNecessary()) EnvRenderer_SetMode(EnvRenderer_Minimal | ENV_LEGACY);
|
||||||
String_InitArray(title, titleBuffer);
|
String_InitArray(title, titleBuffer);
|
||||||
|
@ -828,7 +828,7 @@ static void MainScreen_TickCheckUpdates(struct MainScreen* s) {
|
|||||||
const static String needUpdate = String_FromConst("&aNew release");
|
const static String needUpdate = String_FromConst("&aNew release");
|
||||||
const static String upToDate = String_FromConst("&eUp to date");
|
const static String upToDate = String_FromConst("&eUp to date");
|
||||||
const static String failed = String_FromConst("&cCheck failed");
|
const static String failed = String_FromConst("&cCheck failed");
|
||||||
const static String currentStr = String_FromConst(PROGRAM_APP_VER);
|
const static String currentStr = String_FromConst(GAME_APP_VER);
|
||||||
uint32_t latest, current;
|
uint32_t latest, current;
|
||||||
|
|
||||||
if (!CheckUpdateTask.Base.Working) return;
|
if (!CheckUpdateTask.Base.Working) return;
|
||||||
|
@ -235,7 +235,7 @@ static void Launcher_Free(void) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void Launcher_Run(void) {
|
void Launcher_Run(void) {
|
||||||
const static String title = String_FromConst(PROGRAM_APP_NAME);
|
const static String title = String_FromConst(GAME_APP_NAME);
|
||||||
Window_CreateSimple(640, 400);
|
Window_CreateSimple(640, 400);
|
||||||
Window_SetTitle(&title);
|
Window_SetTitle(&title);
|
||||||
Window_SetVisible(true);
|
Window_SetVisible(true);
|
||||||
|
@ -1333,7 +1333,7 @@ static HINTERNET hInternet;
|
|||||||
|
|
||||||
void Http_Init(void) {
|
void Http_Init(void) {
|
||||||
/* TODO: Should we use INTERNET_OPEN_TYPE_PRECONFIG instead? */
|
/* TODO: Should we use INTERNET_OPEN_TYPE_PRECONFIG instead? */
|
||||||
hInternet = InternetOpenA(PROGRAM_APP_NAME, INTERNET_OPEN_TYPE_DIRECT, NULL, NULL, 0);
|
hInternet = InternetOpenA(GAME_APP_NAME, INTERNET_OPEN_TYPE_DIRECT, NULL, NULL, 0);
|
||||||
if (!hInternet) ErrorHandler_Fail2(GetLastError(), "Failed to init WinINet");
|
if (!hInternet) ErrorHandler_Fail2(GetLastError(), "Failed to init WinINet");
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -2031,7 +2031,7 @@ int Platform_GetCommandLineArgs(int argc, STRING_REF const char** argv, String*
|
|||||||
int i;
|
int i;
|
||||||
Platform_NextArg(&cmdArgs); /* skip exe path */
|
Platform_NextArg(&cmdArgs); /* skip exe path */
|
||||||
|
|
||||||
for (i = 0; i < PROGRAM_MAX_CMDARGS; i++) {
|
for (i = 0; i < GAME_MAX_CMDARGS; i++) {
|
||||||
args[i] = Platform_NextArg(&cmdArgs);
|
args[i] = Platform_NextArg(&cmdArgs);
|
||||||
|
|
||||||
if (!args[i].length) break;
|
if (!args[i].length) break;
|
||||||
|
@ -61,12 +61,12 @@ static void Program_RunGame(void) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
String_InitArray(title, titleBuffer);
|
String_InitArray(title, titleBuffer);
|
||||||
String_Format2(&title, "%c (%s)", PROGRAM_APP_NAME, &Game_Username);
|
String_Format2(&title, "%c (%s)", GAME_APP_NAME, &Game_Username);
|
||||||
Game_Run(width, height, &title);
|
Game_Run(width, height, &title);
|
||||||
}
|
}
|
||||||
|
|
||||||
int main(int argc, char** argv) {
|
int main(int argc, char** argv) {
|
||||||
String args[PROGRAM_MAX_CMDARGS];
|
String args[GAME_MAX_CMDARGS];
|
||||||
int argsCount;
|
int argsCount;
|
||||||
uint8_t ip[4];
|
uint8_t ip[4];
|
||||||
uint16_t port;
|
uint16_t port;
|
||||||
@ -82,7 +82,7 @@ int main(int argc, char** argv) {
|
|||||||
#ifdef CC_TEST_VORBIS
|
#ifdef CC_TEST_VORBIS
|
||||||
main_imdct();
|
main_imdct();
|
||||||
#endif
|
#endif
|
||||||
Platform_LogConst("Starting " PROGRAM_APP_NAME " ..");
|
Platform_LogConst("Starting " GAME_APP_NAME " ..");
|
||||||
|
|
||||||
Utils_EnsureDirectory("maps");
|
Utils_EnsureDirectory("maps");
|
||||||
Utils_EnsureDirectory("texpacks");
|
Utils_EnsureDirectory("texpacks");
|
||||||
|
@ -172,11 +172,11 @@ struct ResourceMusic Resources_Music[7] = {
|
|||||||
/*########################################################################################################################*
|
/*########################################################################################################################*
|
||||||
*---------------------------------------------------------Zip writer------------------------------------------------------*
|
*---------------------------------------------------------Zip writer------------------------------------------------------*
|
||||||
*#########################################################################################################################*/
|
*#########################################################################################################################*/
|
||||||
static ReturnCode ZipPatcher_LocalFile(struct Stream* s, struct ResourceTexture* entry) {
|
static ReturnCode ZipPatcher_LocalFile(struct Stream* s, struct ResourceTexture* e) {
|
||||||
String name = String_FromReadonly(entry->Filename);
|
String name = String_FromReadonly(e->Filename);
|
||||||
uint8_t header[30 + STRING_SIZE];
|
uint8_t header[30 + STRING_SIZE];
|
||||||
ReturnCode res;
|
ReturnCode res;
|
||||||
if ((res = s->Position(s, &entry->Offset))) return res;
|
if ((res = s->Position(s, &e->Offset))) return res;
|
||||||
|
|
||||||
Stream_SetU32_LE(&header[0], 0x04034b50); /* signature */
|
Stream_SetU32_LE(&header[0], 0x04034b50); /* signature */
|
||||||
Stream_SetU16_LE(&header[4], 20); /* version needed */
|
Stream_SetU16_LE(&header[4], 20); /* version needed */
|
||||||
@ -185,9 +185,9 @@ static ReturnCode ZipPatcher_LocalFile(struct Stream* s, struct ResourceTexture*
|
|||||||
Stream_SetU16_LE(&header[10], 0); /* last modified */
|
Stream_SetU16_LE(&header[10], 0); /* last modified */
|
||||||
Stream_SetU16_LE(&header[12], 0); /* last modified */
|
Stream_SetU16_LE(&header[12], 0); /* last modified */
|
||||||
|
|
||||||
Stream_SetU32_LE(&header[14], 0); /* CRC32 */
|
Stream_SetU32_LE(&header[14], e->Crc32); /* CRC32 */
|
||||||
Stream_SetU32_LE(&header[18], 0); /* Compressed size */
|
Stream_SetU32_LE(&header[18], e->Size); /* Compressed size */
|
||||||
Stream_SetU32_LE(&header[22], 0); /* Uncompressed size */
|
Stream_SetU32_LE(&header[22], e->Size); /* Uncompressed size */
|
||||||
|
|
||||||
Stream_SetU16_LE(&header[26], name.length); /* name length */
|
Stream_SetU16_LE(&header[26], name.length); /* name length */
|
||||||
Stream_SetU16_LE(&header[28], 0); /* extra field length */
|
Stream_SetU16_LE(&header[28], 0); /* extra field length */
|
||||||
@ -196,8 +196,8 @@ static ReturnCode ZipPatcher_LocalFile(struct Stream* s, struct ResourceTexture*
|
|||||||
return Stream_Write(s, header, 30 + name.length);
|
return Stream_Write(s, header, 30 + name.length);
|
||||||
}
|
}
|
||||||
|
|
||||||
static ReturnCode ZipPatcher_CentralDir(struct Stream* s, struct ResourceTexture* res) {
|
static ReturnCode ZipPatcher_CentralDir(struct Stream* s, struct ResourceTexture* e) {
|
||||||
String name = String_FromReadonly(res->Filename);
|
String name = String_FromReadonly(e->Filename);
|
||||||
uint8_t header[46 + STRING_SIZE];
|
uint8_t header[46 + STRING_SIZE];
|
||||||
struct DateTime now;
|
struct DateTime now;
|
||||||
int modTime, modDate;
|
int modTime, modDate;
|
||||||
@ -214,9 +214,9 @@ static ReturnCode ZipPatcher_CentralDir(struct Stream* s, struct ResourceTexture
|
|||||||
Stream_SetU16_LE(&header[12], modTime); /* last modified */
|
Stream_SetU16_LE(&header[12], modTime); /* last modified */
|
||||||
Stream_SetU16_LE(&header[14], modDate); /* last modified */
|
Stream_SetU16_LE(&header[14], modDate); /* last modified */
|
||||||
|
|
||||||
Stream_SetU32_LE(&header[16], res->Crc32); /* CRC32 */
|
Stream_SetU32_LE(&header[16], e->Crc32); /* CRC32 */
|
||||||
Stream_SetU32_LE(&header[20], res->Size); /* compressed size */
|
Stream_SetU32_LE(&header[20], e->Size); /* compressed size */
|
||||||
Stream_SetU32_LE(&header[24], res->Size); /* uncompressed size */
|
Stream_SetU32_LE(&header[24], e->Size); /* uncompressed size */
|
||||||
|
|
||||||
Stream_SetU16_LE(&header[28], name.length); /* name length */
|
Stream_SetU16_LE(&header[28], name.length); /* name length */
|
||||||
Stream_SetU16_LE(&header[30], 0); /* extra field length */
|
Stream_SetU16_LE(&header[30], 0); /* extra field length */
|
||||||
@ -224,7 +224,7 @@ static ReturnCode ZipPatcher_CentralDir(struct Stream* s, struct ResourceTexture
|
|||||||
Stream_SetU16_LE(&header[34], 0); /* disk number */
|
Stream_SetU16_LE(&header[34], 0); /* disk number */
|
||||||
Stream_SetU16_LE(&header[36], 0); /* internal attributes */
|
Stream_SetU16_LE(&header[36], 0); /* internal attributes */
|
||||||
Stream_SetU32_LE(&header[38], 0); /* external attributes */
|
Stream_SetU32_LE(&header[38], 0); /* external attributes */
|
||||||
Stream_SetU32_LE(&header[42], res->Offset); /* local header offset */
|
Stream_SetU32_LE(&header[42], e->Offset); /* local header offset */
|
||||||
|
|
||||||
Mem_Copy(&header[46], name.buffer, name.length);
|
Mem_Copy(&header[46], name.buffer, name.length);
|
||||||
return Stream_Write(s, header, 46 + name.length);
|
return Stream_Write(s, header, 46 + name.length);
|
||||||
|
@ -561,7 +561,7 @@ static void ServerConnection_Init(void) {
|
|||||||
|
|
||||||
Gfx_LostContextFunction = ServerConnection.Tick;
|
Gfx_LostContextFunction = ServerConnection.Tick;
|
||||||
ScheduledTask_Add(GAME_NET_TICKS, ServerConnection.Tick);
|
ScheduledTask_Add(GAME_NET_TICKS, ServerConnection.Tick);
|
||||||
String_AppendConst(&ServerConnection_AppName, PROGRAM_APP_NAME);
|
String_AppendConst(&ServerConnection_AppName, GAME_APP_NAME);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void ServerConnection_Free(void) {
|
static void ServerConnection_Free(void) {
|
||||||
|
Loading…
x
Reference in New Issue
Block a user