diff --git a/CMakeLists.txt b/CMakeLists.txt index 0aa00af..0588056 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -15,6 +15,7 @@ set(SOURCES src/overlayfs.c src/getHome.c src/file.c + src/order.c src/fomod.c src/fomod/group.c src/fomod/xmlUtil.c diff --git a/src/main.c b/src/main.c index 40f5c2e..0ebe429 100644 --- a/src/main.c +++ b/src/main.c @@ -16,6 +16,7 @@ #include "main.h" #include "file.h" #include "fomod.h" +#include "order.h" GHashTable * gamePaths; @@ -119,10 +120,11 @@ int add(int argc, char ** argv) { return EXIT_SUCCESS; } -int listMods(int argc, char ** argv) { +int listAllMods(int argc, char ** argv) { if(argc != 3) return usage(); char * appIdStr = argv[2]; - if(validateAppId(appIdStr) < 0) { + int appid = validateAppId(appIdStr); + if( appid < 0) { return EXIT_FAILURE; } @@ -130,7 +132,8 @@ int listMods(int argc, char ** argv) { char * home = getHome(); char * modFolder = g_build_filename(home, MANAGER_FILES, MOD_FOLDER_NAME, appIdStr, NULL); free(home); - GList * mods = listFilesInFolder(modFolder); + + GList * mods = listMods(appid); unsigned short index = 0; printf("Id | Installed | Name\n"); @@ -528,7 +531,7 @@ int main(int argc, char ** argv) { if(isRoot()) returnValue = noRoot(); else - returnValue = listMods(argc, argv); + returnValue = listAllMods(argc, argv); } else if(strcmp(argv[1], "--install") == 0 || strcmp(argv[1], "-i") == 0) { if(isRoot()) diff --git a/src/main.h b/src/main.h index ea894c5..02a5edd 100644 --- a/src/main.h +++ b/src/main.h @@ -1,3 +1,5 @@ +//no function should ever be put here, only keep important macros here + #define APP_NAME "modmanager" //relative to home the url is not preprocessed so ../ might create some issues // in c "A" "B" is the same as "AB" diff --git a/src/order.c b/src/order.c new file mode 100644 index 0000000..d4ef1de --- /dev/null +++ b/src/order.c @@ -0,0 +1,101 @@ +#include +#include "order.h" + +//no function are declared in main it's just macros +#include "main.h" +#include "getHome.h" + +typedef struct Mod { + int modId; + char * path; + char * name; +} Mod_t; + +gint compareOrder(const void * a, const void * b) { + const Mod_t * ModA = a; + const Mod_t * ModB = b; + + if(ModA->modId == -1) return -1; + if(ModB->modId == -1) return 1; + + return ModA->modId - ModB->modId; +} + +GList * listMods(int appid) { + char appidStr[10]; + sprintf(appidStr, "%d", appid); + + char * home = getHome(); + char * modFolder = g_build_filename(home, MANAGER_FILES, MOD_FOLDER_NAME, appidStr, NULL); + free(home); + + GList * list = NULL; + DIR *d; + struct dirent *dir; + d = opendir(modFolder); + if (d) { + while ((dir = readdir(d)) != NULL) { + //removes .. & . from the list + if(strcmp(dir->d_name, "..") != 0 && strcmp(dir->d_name, ".") != 0) { + int modId = -1; + //TODO: remove order file + char * modPath = g_build_filename(modFolder, dir->d_name, NULL); + char * modOrder = g_build_filename(modPath, ORDER_FILE, NULL); + FILE * fd_oder = fopen(modOrder, "r"); + g_free(modOrder); + if(fd_oder != NULL) { + fscanf(fd_oder, "%d", &modId); + fclose(fd_oder); + } + + Mod_t * mod = alloca(sizeof(Mod_t)); + mod->modId = modId; + mod->name = strdup(dir->d_name); + //strdup but on the stack + //add one for the \0 + mod->path = alloca((strlen(modPath) + 1) * sizeof(char)); + memcpy(mod->path, modPath, (strlen(modPath) + 1) * sizeof(char)); + + + list = g_list_append(list, mod); + g_free(modPath); + } + } + closedir(d); + } + + list = g_list_sort(list, compareOrder); + GList * orderedMods = NULL; + + int index = 0; + for(GList * p_list = list; p_list != NULL; p_list = g_list_next(p_list)) { + Mod_t * mod = p_list->data; + + gchar * modOrder = g_build_filename(mod->path, ORDER_FILE, NULL); + + FILE * fd_oder = fopen(modOrder, "w+"); + g_free(modOrder); + if(fd_oder != NULL) { + fprintf(fd_oder, "%d", index); + fclose(fd_oder); + } + + orderedMods = g_list_append(orderedMods, mod->name); + + index++; + } + + //do not use g_list_free since i used alloca everything is on the stack + g_list_free(list); + g_free(modFolder); + return orderedMods; +} + + +void swapPlace(int appid, int modId, int modId2) { + GList * list = listMods(appid); + + + + g_list_free(list); +} diff --git a/src/order.h b/src/order.h new file mode 100644 index 0000000..118381d --- /dev/null +++ b/src/order.h @@ -0,0 +1,20 @@ +#ifndef __ORDER_H__ +#define __ORDER_H__ + +#include + +#define ORDER_FILE "__ORDER__" + +//This file manager the load order of mods. +// the current solution is using ORDER_FILE to store a number corresponding to the mod +// this might be sub-optimal but at least it will work just fine + +/** + * @brief update the mods ids and return the mods in order + * + * @return GList of char containing the name of the mod folder in order + */ +GList * listMods(int appid); +void swapPlace(int appid, int modId, int modId2); + +#endif