Set loading order of mods files to alphabetical; Fixed a bug with downloaded mod folders (#54)

Mods as a directory of files depend on loading order for them to work
properly. Currently, the loading order is basically undefined behavior
and unpredictable. The function mod_set_loading_order is here to
specify this order. By default (and for now), the order will be
alphabetical and will follow the ascii table values, meaning digits
come before capital letters and lowercase letters.

Fixed a bug with mods as directories of files when they are downloaded.
The bug was the following: If two selected mods have files with the
same relative filename, they overwrite each other when downloaded,
causing file corruption and making the client game crash when loaded.
To fix it, the mod's directory name is appended to every .lua filename,
so each file has a unique filename when downloaded.
This commit is contained in:
PeachyPeach 2022-04-04 22:43:29 +02:00 committed by GitHub
parent a7e1ec03d3
commit d34eed7ad0
2 changed files with 28 additions and 0 deletions

View File

@ -231,6 +231,26 @@ static bool mod_load_files(struct Mod* mod, char* modName, char* fullPath) {
return true;
}
static void mod_set_loading_order(struct Mod* mod) {
if (mod->fileCount <= 1) {
return;
}
// TODO: add a way to specify the loading order of a mod's files?
// By default, this is the alphabetical order on relative path
for (s32 i = 1; i < mod->fileCount; ++i) {
struct ModFile file = mod->files[i];
for (s32 j = 0; j < i; ++j) {
if (strcmp(file.relativePath, mod->files[j].relativePath) < 0) {
memmove(mod->files + j + 1, mod->files + j, sizeof(struct ModFile) * (i - j));
memcpy(mod->files + j, &file, sizeof(struct ModFile));
break;
}
}
}
}
static void mod_extract_fields(struct Mod* mod) {
// get full path
char path[SYS_MAX_PATH] = { 0 };
@ -372,6 +392,9 @@ bool mod_load(struct Mods* mods, char* basePath, char* modName) {
return false;
}
// set loading order
mod_set_loading_order(mod);
// extract fields
mod_extract_fields(mod);

View File

@ -170,6 +170,11 @@ void network_receive_mod_list(struct Packet* p) {
packet_read(p, &relativePathLength, sizeof(u16));
packet_read(p, file->relativePath, relativePathLength * sizeof(u8));
packet_read(p, &file->size, sizeof(u64));
if (mod->isDirectory && !strstr(file->relativePath, "actors")) {
char tmp[SYS_MAX_PATH];
snprintf(tmp, SYS_MAX_PATH, "%s-%s", mod->relativePath, file->relativePath);
memcpy(file->relativePath, tmp, strlen(tmp) + 1);
}
normalize_path(file->relativePath);
LOG_INFO(" '%s': %llu", file->relativePath, (u64)file->size);
}