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:
parent
a7e1ec03d3
commit
d34eed7ad0
|
@ -231,6 +231,26 @@ static bool mod_load_files(struct Mod* mod, char* modName, char* fullPath) {
|
||||||
return true;
|
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) {
|
static void mod_extract_fields(struct Mod* mod) {
|
||||||
// get full path
|
// get full path
|
||||||
char path[SYS_MAX_PATH] = { 0 };
|
char path[SYS_MAX_PATH] = { 0 };
|
||||||
|
@ -372,6 +392,9 @@ bool mod_load(struct Mods* mods, char* basePath, char* modName) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// set loading order
|
||||||
|
mod_set_loading_order(mod);
|
||||||
|
|
||||||
// extract fields
|
// extract fields
|
||||||
mod_extract_fields(mod);
|
mod_extract_fields(mod);
|
||||||
|
|
||||||
|
|
|
@ -170,6 +170,11 @@ void network_receive_mod_list(struct Packet* p) {
|
||||||
packet_read(p, &relativePathLength, sizeof(u16));
|
packet_read(p, &relativePathLength, sizeof(u16));
|
||||||
packet_read(p, file->relativePath, relativePathLength * sizeof(u8));
|
packet_read(p, file->relativePath, relativePathLength * sizeof(u8));
|
||||||
packet_read(p, &file->size, sizeof(u64));
|
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);
|
normalize_path(file->relativePath);
|
||||||
LOG_INFO(" '%s': %llu", file->relativePath, (u64)file->size);
|
LOG_INFO(" '%s': %llu", file->relativePath, (u64)file->size);
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue