[Untested] Experimental plugin order management support
This commit is contained in:
+22
@@ -128,3 +128,25 @@ void casefold(const char * folder) {
|
||||
closedir(d);
|
||||
}
|
||||
}
|
||||
|
||||
const char * extractLastPart(const char * filePath, const char delimeter) {
|
||||
const int length = strlen(filePath);
|
||||
long index = -1;
|
||||
for(long i= length - 1; i >= 0; i--) {
|
||||
if(filePath[i] == delimeter) {
|
||||
index = i + 1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if(index <= 0 || index == length) return NULL;
|
||||
return &filePath[index];
|
||||
}
|
||||
|
||||
const char * extractExtension(const char * filePath) {
|
||||
return extractLastPart(filePath, '.');
|
||||
}
|
||||
|
||||
const char * extractFileName(const char * filePath) {
|
||||
return extractLastPart(filePath, '/');
|
||||
}
|
||||
|
||||
+17
@@ -45,4 +45,21 @@ int move(const char * source, const char * destination);
|
||||
*/
|
||||
void casefold(const char * folder);
|
||||
|
||||
|
||||
const char * extractLastPart(const char * filePath, const char delimeter);
|
||||
|
||||
/**
|
||||
* @brief Return the extension of a file by looking for the character '.'
|
||||
* @param filePath
|
||||
* @return return a pointer to the address after the '.' or null if it was not found;
|
||||
*/
|
||||
const char * extractExtension(const char * filePath);
|
||||
|
||||
/**
|
||||
* @brief Return the file name by looking for the last character '/'
|
||||
* @param filePath
|
||||
* @return return a pointer to the address after the last '/' or null if it was not found (the path might not be a path in this case)
|
||||
*/
|
||||
const char * extractFileName(const char * filePath);
|
||||
|
||||
#endif
|
||||
|
||||
+1
-22
@@ -7,28 +7,7 @@
|
||||
#include "install.h"
|
||||
#include "main.h"
|
||||
#include "archives.h"
|
||||
|
||||
static const char * extractLastPart(const char * filePath, const char delimeter) {
|
||||
const int length = strlen(filePath);
|
||||
long index = -1;
|
||||
for(long i= length - 1; i >= 0; i--) {
|
||||
if(filePath[i] == delimeter) {
|
||||
index = i + 1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if(index <= 0 || index == length) return NULL;
|
||||
return &filePath[index];
|
||||
}
|
||||
|
||||
static const char * extractExtension(const char * filePath) {
|
||||
return extractLastPart(filePath, '.');
|
||||
}
|
||||
|
||||
static const char * extractFileName(const char * filePath) {
|
||||
return extractLastPart(filePath, '/');
|
||||
}
|
||||
#include "file.h"
|
||||
|
||||
error_t addMod(char * filePath, int appId) {
|
||||
error_t resultError = ERR_SUCCESS;
|
||||
|
||||
+141
@@ -0,0 +1,141 @@
|
||||
#include "loadOrder.h"
|
||||
#include "main.h"
|
||||
#include "steam.h"
|
||||
#include "file.h"
|
||||
|
||||
#include <stdio.h>
|
||||
#include <unistd.h>
|
||||
|
||||
error_t listPlugins(int appid, GList ** plugins) {
|
||||
GHashTable * gamePaths;
|
||||
error_t status = search_games(&gamePaths);
|
||||
if(status == ERR_FAILURE) {
|
||||
return ERR_FAILURE;
|
||||
}
|
||||
|
||||
int gameId = getGameIdFromAppId(appid);
|
||||
if(gameId < 0 ) {
|
||||
return ERR_FAILURE;
|
||||
}
|
||||
|
||||
//save appid parsing
|
||||
//TODO: apply a similar mechanism everywhere
|
||||
size_t appidStrLen = snprintf(NULL, 0, "%d", appid) + 1;
|
||||
char appidStr[appidStrLen];
|
||||
sprintf(appidStr, "%d", appid);
|
||||
|
||||
|
||||
|
||||
const char * path = g_hash_table_lookup(gamePaths, &appid);
|
||||
char * steamGameFolder = g_build_filename(path, "steamapps/common", GAMES_NAMES[gameId], "Data", NULL);
|
||||
|
||||
//esp && esm files are loadable
|
||||
DIR * d = opendir(steamGameFolder);
|
||||
struct dirent *dir;
|
||||
if (d) {
|
||||
while ((dir = readdir(d)) != NULL) {
|
||||
const char * extension = extractExtension(dir->d_name);
|
||||
if(strcmp(extension, "esp") == 0 || strcmp(extension, "esm") == 0) {
|
||||
*plugins = g_list_append(*plugins, strdup(dir->d_name));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
g_free(steamGameFolder);
|
||||
return ERR_SUCCESS;
|
||||
}
|
||||
|
||||
error_t getLoadOrder(int appid, GList ** order) {
|
||||
|
||||
GHashTable * gamePaths;
|
||||
error_t status = search_games(&gamePaths);
|
||||
if(status == ERR_FAILURE) {
|
||||
return ERR_FAILURE;
|
||||
}
|
||||
|
||||
GList * l_plugins = NULL;
|
||||
error_t error = listPlugins(appid, &l_plugins);
|
||||
if(error == ERR_FAILURE)
|
||||
return ERR_FAILURE;
|
||||
|
||||
|
||||
int gameId = getGameIdFromAppId(appid);
|
||||
if(gameId < 0 ) {
|
||||
return ERR_FAILURE;
|
||||
}
|
||||
|
||||
size_t appidStrLen = snprintf(NULL, 0, "%d", appid) + 1;
|
||||
char appidStr[appidStrLen];
|
||||
sprintf(appidStr, "%d", appid);
|
||||
|
||||
const char * path = g_hash_table_lookup(gamePaths, &appid);
|
||||
char * loadOrderPath = g_build_filename(path, "steamapps/compatdata", appidStr, "pfx/drive_c/users/steamuser/AppData/Local/", GAMES_NAMES[gameId], "loadorder.txt", NULL);
|
||||
|
||||
GList * l_currentLoadOrder = NULL;
|
||||
if(access(loadOrderPath, F_OK)) {
|
||||
FILE * f_loadOrder = fopen(loadOrderPath, "r");
|
||||
|
||||
size_t length = 0;
|
||||
char * line = NULL;
|
||||
|
||||
while(getline(&line, &length, f_loadOrder) > 0) {
|
||||
if(line[0] == '#' || line[0] == '\n')
|
||||
continue;
|
||||
|
||||
l_currentLoadOrder = g_list_append(l_currentLoadOrder, strdup(line));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
GList * l_currentLoadOrderCursor = l_currentLoadOrder;
|
||||
GList * l_completeLoadOrder = NULL;
|
||||
|
||||
while(l_currentLoadOrderCursor != NULL) {
|
||||
char * modName = l_currentLoadOrderCursor->data;
|
||||
//TODO: finir sa
|
||||
GList * mod = g_list_find_custom(l_plugins, modName, (GCompareFunc)strcmp);
|
||||
if(mod == NULL) {
|
||||
//The plugin is no longer installed
|
||||
continue;
|
||||
} else {
|
||||
l_completeLoadOrder = g_list_append(l_completeLoadOrder, strdup(modName));
|
||||
}
|
||||
l_currentLoadOrderCursor = g_list_next(l_currentLoadOrderCursor);
|
||||
}
|
||||
|
||||
*order = l_completeLoadOrder;
|
||||
|
||||
g_list_free_full(l_plugins, free);
|
||||
g_list_free_full(l_currentLoadOrder, free);
|
||||
g_free(loadOrderPath);
|
||||
return ERR_SUCCESS;
|
||||
}
|
||||
|
||||
error_t setLoadOrder(int appid, GList * loadOrder) {
|
||||
GHashTable * gamePaths;
|
||||
error_t status = search_games(&gamePaths);
|
||||
if(status == ERR_FAILURE) {
|
||||
return ERR_FAILURE;
|
||||
}
|
||||
|
||||
int gameId = getGameIdFromAppId(appid);
|
||||
if(gameId < 0 ) {
|
||||
return ERR_FAILURE;
|
||||
}
|
||||
|
||||
size_t appidStrLen = snprintf(NULL, 0, "%d", appid) + 1;
|
||||
char appidStr[appidStrLen];
|
||||
sprintf(appidStr, "%d", appid);
|
||||
|
||||
const char * path = g_hash_table_lookup(gamePaths, &appid);
|
||||
char * loadOrderPath = g_build_filename(path, "steamapps/compatdata", appidStr, "pfx/drive_c/users/steamuser/AppData/Local/", GAMES_NAMES[gameId], "loadorder.txt", NULL);
|
||||
|
||||
FILE * f_loadOrder = fopen(loadOrderPath, "w");
|
||||
while(loadOrder != NULL) {
|
||||
fwrite(loadOrder->data, sizeof(char), strlen(loadOrder->data), f_loadOrder);
|
||||
loadOrder = g_list_next(loadOrder);
|
||||
}
|
||||
fclose(f_loadOrder);
|
||||
|
||||
return ERR_SUCCESS;
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
#ifndef __LOAD_ORDER_H__
|
||||
#define __LOAD_ORDER_H__
|
||||
|
||||
#include <glib.h>
|
||||
#include "main.h"
|
||||
|
||||
error_t listPlugins(int appid, GList ** list) __attribute__((warn_unused_result));
|
||||
error_t getLoadOrder(int appid, GList ** order) __attribute__((warn_unused_result));
|
||||
error_t setLoadOrder(int appid, GList * loadOrder) __attribute__((warn_unused_result));
|
||||
|
||||
#endif
|
||||
Reference in New Issue
Block a user