Added singleton to search_games

This commit is contained in:
Marc
2022-10-07 11:17:24 +02:00
parent 4ce99996e8
commit 1abef49712
4 changed files with 67 additions and 31 deletions
+41 -21
View File
@@ -1,6 +1,5 @@
#include <stdbool.h> #include <stdbool.h>
#include <stdio.h> #include <stdio.h>
#include <glib.h>
#include <stdlib.h> #include <stdlib.h>
#include <string.h> #include <string.h>
#include <sys/types.h> #include <sys/types.h>
@@ -21,8 +20,6 @@
#define ENABLED_COLOR "\033[0;32m" #define ENABLED_COLOR "\033[0;32m"
#define DISABLED_COLOR "\033[0;31m" #define DISABLED_COLOR "\033[0;31m"
GHashTable * gamePaths;
static bool isRoot() { static bool isRoot() {
return getuid() == 0; return getuid() == 0;
} }
@@ -65,7 +62,13 @@ static int usage() {
return EXIT_FAILURE; return EXIT_FAILURE;
} }
static int validateAppId(const char * appIdStr) { static error_t validateAppId(const char * appIdStr) {
GHashTable * gamePaths;
error_t status = search_games(&gamePaths);
if(status == ERR_FAILURE) {
return ERR_FAILURE;
}
char * strtoulSentinel; char * strtoulSentinel;
//strtoul set EINVAL(after C99) if the string is invalid //strtoul set EINVAL(after C99) if the string is invalid
unsigned long appid = strtoul(appIdStr, &strtoulSentinel, 10); unsigned long appid = strtoul(appIdStr, &strtoulSentinel, 10);
@@ -91,6 +94,13 @@ static int validateAppId(const char * appIdStr) {
static int listGames(int argc, char **) { static int listGames(int argc, char **) {
if(argc != 2) return usage(); if(argc != 2) return usage();
GHashTable * gamePaths;
error_t status = search_games(&gamePaths);
if(status == ERR_FAILURE) {
return EXIT_FAILURE;
}
GList * gamesIds = g_hash_table_get_keys(gamePaths); GList * gamesIds = g_hash_table_get_keys(gamePaths);
GList * gamesIdsFirstPointer = gamesIds; GList * gamesIdsFirstPointer = gamesIds;
if(g_list_length(gamesIds) == 0) { if(g_list_length(gamesIds) == 0) {
@@ -103,7 +113,7 @@ static int listGames(int argc, char **) {
} }
} }
g_list_free(gamesIdsFirstPointer); g_list_free(gamesIdsFirstPointer);
return EXIT_SUCCESS; return EXIT_FAILURE;
} }
static int add(int argc, char ** argv) { static int add(int argc, char ** argv) {
@@ -303,6 +313,15 @@ static int deploy(int argc, char ** argv) {
modsToInstall[modCount + 1] = NULL; modsToInstall[modCount + 1] = NULL;
printf("Mounting the overlay\n"); printf("Mounting the overlay\n");
int gameId = getGameIdFromAppId(appid); int gameId = getGameIdFromAppId(appid);
GHashTable * gamePaths;
error_t lookup_status = search_games(&gamePaths);
if(lookup_status == ERR_FAILURE) {
free(home);
return ERR_FAILURE;
}
const char * path = g_hash_table_lookup(gamePaths, &gameId); const char * path = g_hash_table_lookup(gamePaths, &gameId);
char * steamGameFolder = g_build_path("/", path, "steamapps/common", GAMES_NAMES[gameId], "Data", NULL); char * steamGameFolder = g_build_path("/", path, "steamapps/common", GAMES_NAMES[gameId], "Data", NULL);
@@ -353,6 +372,13 @@ static int setup(int argc, char ** argv) {
free(gameUpperDir); free(gameUpperDir);
free(gameWorkDir); free(gameWorkDir);
GHashTable * gamePaths;
error_t status = search_games(&gamePaths);
if(status == ERR_FAILURE) {
free(home);
return ERR_FAILURE;
}
const char * path = g_hash_table_lookup(gamePaths, &gameId); const char * path = g_hash_table_lookup(gamePaths, &gameId);
char * steamGameFolder = g_build_path("/", path, "steamapps/common", GAMES_NAMES[gameId], "Data", NULL); char * steamGameFolder = g_build_path("/", path, "steamapps/common", GAMES_NAMES[gameId], "Data", NULL);
@@ -393,6 +419,12 @@ static int unbind(int argc, char ** argv) {
if(appid < 0) { if(appid < 0) {
return EXIT_FAILURE; return EXIT_FAILURE;
} }
GHashTable * gamePaths;
error_t status = search_games(&gamePaths);
if(status == ERR_FAILURE)
return EXIT_FAILURE;
int gameId = getGameIdFromAppId(appid); int gameId = getGameIdFromAppId(appid);
const char * path = g_hash_table_lookup(gamePaths, &gameId); const char * path = g_hash_table_lookup(gamePaths, &gameId);
char * steamGameFolder = g_build_path("/", path, "steamapps/common", GAMES_NAMES[gameId], "Data", NULL); char * steamGameFolder = g_build_path("/", path, "steamapps/common", GAMES_NAMES[gameId], "Data", NULL);
@@ -531,17 +563,7 @@ int main(int argc, char ** argv) {
return EXIT_FAILURE; return EXIT_FAILURE;
} }
int searchStatus;
gamePaths = search_games(&searchStatus);
int returnValue = EXIT_SUCCESS; int returnValue = EXIT_SUCCESS;
if(searchStatus == EXIT_FAILURE) {
returnValue = EXIT_FAILURE;
fprintf(stderr, "Error while looking up libraries, do you have steam installed ?");
goto exit;
}
char * home = getHome(); char * home = getHome();
char * configFolder = g_build_filename(home, MANAGER_FILES, NULL); char * configFolder = g_build_filename(home, MANAGER_FILES, NULL);
free(home); free(home);
@@ -554,18 +576,17 @@ int main(int argc, char ** argv) {
if(getuid() == 0) { if(getuid() == 0) {
fprintf(stderr, "For the first run please avoid sudo\n"); fprintf(stderr, "For the first run please avoid sudo\n");
returnValue = EXIT_FAILURE; returnValue = EXIT_FAILURE;
goto exit2; goto exit;
} else { } else {
//leading 0 == octal //leading 0 == octal
int i = g_mkdir_with_parents(configFolder, 0755); int i = g_mkdir_with_parents(configFolder, 0755);
if(i < 0) { if(i < 0) {
fprintf(stderr, "Could not create configs, check access rights for this path: %s", configFolder); fprintf(stderr, "Could not create configs, check access rights for this path: %s", configFolder);
goto exit2; goto exit;
} }
} }
} }
if(strcmp(argv[1], "--list-games") == 0 || strcmp(argv[1], "-l") == 0) if(strcmp(argv[1], "--list-games") == 0 || strcmp(argv[1], "-l") == 0)
returnValue = listGames(argc, argv); returnValue = listGames(argc, argv);
@@ -613,9 +634,8 @@ int main(int argc, char ** argv) {
returnValue = EXIT_FAILURE; returnValue = EXIT_FAILURE;
} }
exit2:
g_free(configFolder);
g_hash_table_destroy(gamePaths);
exit: exit:
g_free(configFolder);
freeGameTableSingleton();
return returnValue; return returnValue;
} }
+4 -2
View File
@@ -1,9 +1,11 @@
#ifndef __MAIN_H__ #ifndef __MAIN_H__
#define __MAIN_H__ #define __MAIN_H__
//no function should ever be put here, only keep important macros here #include <glib.h>
#define APP_NAME "modmanager" //no function should ever be put here, only keep important macros and globals here
#define APP_NAME "mod-manager"
//relative to home the url is not preprocessed so ../ might create some issues //relative to home the url is not preprocessed so ../ might create some issues
// in c "A" "B" is the same as "AB" // in c "A" "B" is the same as "AB"
#define MANAGER_FILES ".local/share/" APP_NAME #define MANAGER_FILES ".local/share/" APP_NAME
+17 -5
View File
@@ -1,6 +1,7 @@
#include "steam.h" #include "steam.h"
#include "macro.h" #include "macro.h"
#include "getHome.h" #include "getHome.h"
#include "main.h"
#include <unistd.h> #include <unistd.h>
#include <stddef.h> #include <stddef.h>
#include <stdio.h> #include <stdio.h>
@@ -190,11 +191,21 @@ static void freeLibraries(ValveLibraries_t * libraries, int size) {
free(libraries); free(libraries);
} }
GHashTable* search_games(int * status) { static GHashTable* gameTableSingleton = NULL;
void freeGameTableSingleton() {
if(gameTableSingleton != NULL)g_hash_table_destroy(gameTableSingleton);
}
error_t search_games(GHashTable ** p_hashTable) {
if(gameTableSingleton != NULL) {
*p_hashTable = gameTableSingleton;
return ERR_SUCCESS;
}
ValveLibraries_t * libraries = NULL; ValveLibraries_t * libraries = NULL;
size_t size = 0; size_t size = 0;
char * home = getHome(); char * home = getHome();
*status = EXIT_SUCCESS;
for(unsigned long i = 0; i < LEN(steamLibraries); i++) { for(unsigned long i = 0; i < LEN(steamLibraries); i++) {
char * path = g_build_filename(home, steamLibraries[i], "steamapps/libraryfolders.vdf", NULL); char * path = g_build_filename(home, steamLibraries[i], "steamapps/libraryfolders.vdf", NULL);
@@ -212,8 +223,7 @@ GHashTable* search_games(int * status) {
free(home); free(home);
if(libraries == NULL) { if(libraries == NULL) {
*status = EXIT_FAILURE; return ERR_FAILURE;
return NULL;
} }
GHashTable* table = g_hash_table_new_full(g_int_hash, g_int_equal, free, free); GHashTable* table = g_hash_table_new_full(g_int_hash, g_int_equal, free, free);
@@ -231,7 +241,9 @@ GHashTable* search_games(int * status) {
} }
freeLibraries(libraries, size); freeLibraries(libraries, size);
return table; *p_hashTable = table;
gameTableSingleton = table;
return ERR_SUCCESS;
} }
+5 -3
View File
@@ -45,12 +45,14 @@ _Static_assert(LEN(GAMES_APPIDS) == LEN(GAMES_NAMES), "Game APPIDS and Game Name
/** /**
* @brief list all installed games and the paths to the game's files * @brief list all installed games and the paths to the game's files
* This method has a singleton so after the first execution it will no rescan for new games.
* *
* @param status pointer to a status variable that will be modified to EXIT_SUCCESS or EXIT_FAILURE * @param status pointer to a status variable that will be modified to EXIT_SUCCESS or EXIT_FAILURE
* @return GHashTable* a map appid(int) => path(char *) * @return GHashTable* a map appid(int) => path(char *) to the corresponding steam library
*/ */
//TODO: flip the return value and parameter error_t search_games(GHashTable** tablePointer);
GHashTable* search_games(int * status);
void freeGameTableSingleton(void);
/** /**
* @brief search the index of the game inside GAMES_NAMES or GAMES_APPIDS * @brief search the index of the game inside GAMES_NAMES or GAMES_APPIDS