added support for multiple user game data directories
authorHolger Schemel <info@artsoft.org>
Sat, 17 Oct 2020 23:54:32 +0000 (01:54 +0200)
committerHolger Schemel <info@artsoft.org>
Sun, 13 Dec 2020 23:57:57 +0000 (00:57 +0100)
This change adds support for game data directories for multiple users,
to store individual user configuration files (like setup data and last
played level sets and levels) and individual user content files (like
personal tape files, but not personal level sets and scores, which are
still stored to be accessible by all users).

Special treatment is done for the game data files of the first user,
which are still stored in the main game data directory like before,
so there are no changes in file and directory paths for the "default
user", regardless if multiple user support is enabled or disabled.

src/libgame/misc.c
src/libgame/sdl.c
src/libgame/setup.c
src/libgame/setup.h
src/libgame/system.c
src/libgame/system.h

index bf2d2c42fb4b8c84b0dbdcf317ef76ad7af1f4b1..217895c035dfddb4b9adb8e46f9cb62b8bcd040c 100644 (file)
@@ -3761,14 +3761,14 @@ void FreeCustomArtworkLists(struct ArtworkListInfo *artwork_info)
 
 char *getLogFilename(char *basename)
 {
 
 char *getLogFilename(char *basename)
 {
-  return getPath2(getUserGameDataDir(), basename);
+  return getPath2(getMainUserGameDataDir(), basename);
 }
 
 void OpenLogFiles(void)
 {
   int i;
 
 }
 
 void OpenLogFiles(void)
 {
   int i;
 
-  InitUserDataDirectory();
+  InitMainUserDataDirectory();
 
   for (i = 0; i < NUM_LOGS; i++)
   {
 
   for (i = 0; i < NUM_LOGS; i++)
   {
index 9755aaa492a33912ed19d9d2bef685d072421e97..4108b2b531c533825c092df0ceab9fb1fd596d90 100644 (file)
@@ -2709,7 +2709,7 @@ void SDLInitJoysticks(void)
   boolean print_warning = !sdl_joystick_subsystem_initialized;
   char *mappings_file_base = getPath2(options.conf_directory,
                                      GAMECONTROLLER_BASENAME);
   boolean print_warning = !sdl_joystick_subsystem_initialized;
   char *mappings_file_base = getPath2(options.conf_directory,
                                      GAMECONTROLLER_BASENAME);
-  char *mappings_file_user = getPath2(getUserGameDataDir(),
+  char *mappings_file_user = getPath2(getMainUserGameDataDir(),
                                      GAMECONTROLLER_BASENAME);
   int num_mappings;
   int i;
                                      GAMECONTROLLER_BASENAME);
   int num_mappings;
   int i;
index 2a86f2be07706c0380ea7ad7a13494f401a1ca39..74c21fe33bdad1fe05195ff196b84a3f20278f56 100644 (file)
@@ -121,9 +121,9 @@ static char *getScoreDir(char *level_subdir)
   if (score_dir == NULL)
   {
     if (program.global_scores)
   if (score_dir == NULL)
   {
     if (program.global_scores)
-      score_dir = getPath2(getCommonDataDir(),   score_subdir);
+      score_dir = getPath2(getCommonDataDir(),       score_subdir);
     else
     else
-      score_dir = getPath2(getUserGameDataDir(), score_subdir);
+      score_dir = getPath2(getMainUserGameDataDir(), score_subdir);
   }
 
   if (level_subdir != NULL)
   }
 
   if (level_subdir != NULL)
@@ -138,6 +138,32 @@ static char *getScoreDir(char *level_subdir)
   return score_dir;
 }
 
   return score_dir;
 }
 
+static char *getUserSubdir(int nr)
+{
+  static char user_subdir[16] = { 0 };
+
+  sprintf(user_subdir, "%03d", nr);
+
+  return user_subdir;
+}
+
+static char *getUserDir(int nr)
+{
+  static char *user_dir = NULL;
+  char *main_data_dir = getMainUserGameDataDir();
+  char *users_subdir = USERS_DIRECTORY;
+  char *user_subdir = getUserSubdir(nr);
+
+  checked_free(user_dir);
+
+  if (nr != -1)
+    user_dir = getPath3(main_data_dir, users_subdir, user_subdir);
+  else
+    user_dir = getPath2(main_data_dir, users_subdir);
+
+  return user_dir;
+}
+
 static char *getLevelSetupDir(char *level_subdir)
 {
   static char *levelsetup_dir = NULL;
 static char *getLevelSetupDir(char *level_subdir)
 {
   static char *levelsetup_dir = NULL;
@@ -159,7 +185,7 @@ static char *getCacheDir(void)
   static char *cache_dir = NULL;
 
   if (cache_dir == NULL)
   static char *cache_dir = NULL;
 
   if (cache_dir == NULL)
-    cache_dir = getPath2(getUserGameDataDir(), CACHE_DIRECTORY);
+    cache_dir = getPath2(getMainUserGameDataDir(), CACHE_DIRECTORY);
 
   return cache_dir;
 }
 
   return cache_dir;
 }
@@ -169,7 +195,7 @@ static char *getNetworkDir(void)
   static char *network_dir = NULL;
 
   if (network_dir == NULL)
   static char *network_dir = NULL;
 
   if (network_dir == NULL)
-    network_dir = getPath2(getUserGameDataDir(), NETWORK_DIRECTORY);
+    network_dir = getPath2(getMainUserGameDataDir(), NETWORK_DIRECTORY);
 
   return network_dir;
 }
 
   return network_dir;
 }
@@ -192,7 +218,7 @@ char *getLevelDirFromTreeInfo(TreeInfo *node)
 char *getUserLevelDir(char *level_subdir)
 {
   static char *userlevel_dir = NULL;
 char *getUserLevelDir(char *level_subdir)
 {
   static char *userlevel_dir = NULL;
-  char *data_dir = getUserGameDataDir();
+  char *data_dir = getMainUserGameDataDir();
   char *userlevel_subdir = LEVELS_DIRECTORY;
 
   checked_free(userlevel_dir);
   char *userlevel_subdir = LEVELS_DIRECTORY;
 
   checked_free(userlevel_dir);
@@ -341,7 +367,7 @@ char *getUserGraphicsDir(void)
   static char *usergraphics_dir = NULL;
 
   if (usergraphics_dir == NULL)
   static char *usergraphics_dir = NULL;
 
   if (usergraphics_dir == NULL)
-    usergraphics_dir = getPath2(getUserGameDataDir(), GRAPHICS_DIRECTORY);
+    usergraphics_dir = getPath2(getMainUserGameDataDir(), GRAPHICS_DIRECTORY);
 
   return usergraphics_dir;
 }
 
   return usergraphics_dir;
 }
@@ -351,7 +377,7 @@ char *getUserSoundsDir(void)
   static char *usersounds_dir = NULL;
 
   if (usersounds_dir == NULL)
   static char *usersounds_dir = NULL;
 
   if (usersounds_dir == NULL)
-    usersounds_dir = getPath2(getUserGameDataDir(), SOUNDS_DIRECTORY);
+    usersounds_dir = getPath2(getMainUserGameDataDir(), SOUNDS_DIRECTORY);
 
   return usersounds_dir;
 }
 
   return usersounds_dir;
 }
@@ -361,7 +387,7 @@ char *getUserMusicDir(void)
   static char *usermusic_dir = NULL;
 
   if (usermusic_dir == NULL)
   static char *usermusic_dir = NULL;
 
   if (usermusic_dir == NULL)
-    usermusic_dir = getPath2(getUserGameDataDir(), MUSIC_DIRECTORY);
+    usermusic_dir = getPath2(getMainUserGameDataDir(), MUSIC_DIRECTORY);
 
   return usermusic_dir;
 }
 
   return usermusic_dir;
 }
@@ -1067,7 +1093,7 @@ void InitScoreDirectory(char *level_subdir)
   if (program.global_scores)
     createDirectory(getCommonDataDir(), "common data", permissions);
   else
   if (program.global_scores)
     createDirectory(getCommonDataDir(), "common data", permissions);
   else
-    createDirectory(getUserGameDataDir(), "user data", permissions);
+    createDirectory(getMainUserGameDataDir(), "main user data", permissions);
 
   createDirectory(getScoreDir(NULL), "main score", permissions);
   createDirectory(getScoreDir(level_subdir), "level score", permissions);
 
   createDirectory(getScoreDir(NULL), "main score", permissions);
   createDirectory(getScoreDir(level_subdir), "level score", permissions);
@@ -1079,7 +1105,7 @@ void InitUserLevelDirectory(char *level_subdir)
 {
   if (!directoryExists(getUserLevelDir(level_subdir)))
   {
 {
   if (!directoryExists(getUserLevelDir(level_subdir)))
   {
-    createDirectory(getUserGameDataDir(), "user data", PERMS_PRIVATE);
+    createDirectory(getMainUserGameDataDir(), "main user data", PERMS_PRIVATE);
     createDirectory(getUserLevelDir(NULL), "main user level", PERMS_PRIVATE);
     createDirectory(getUserLevelDir(level_subdir), "user level", PERMS_PRIVATE);
 
     createDirectory(getUserLevelDir(NULL), "main user level", PERMS_PRIVATE);
     createDirectory(getUserLevelDir(level_subdir), "user level", PERMS_PRIVATE);
 
@@ -1092,7 +1118,7 @@ void InitNetworkLevelDirectory(char *level_subdir)
 {
   if (!directoryExists(getNetworkLevelDir(level_subdir)))
   {
 {
   if (!directoryExists(getNetworkLevelDir(level_subdir)))
   {
-    createDirectory(getUserGameDataDir(), "user data", PERMS_PRIVATE);
+    createDirectory(getMainUserGameDataDir(), "main user data", PERMS_PRIVATE);
     createDirectory(getNetworkDir(), "network data", PERMS_PRIVATE);
     createDirectory(getNetworkLevelDir(NULL), "main network level", PERMS_PRIVATE);
     createDirectory(getNetworkLevelDir(level_subdir), "network level", PERMS_PRIVATE);
     createDirectory(getNetworkDir(), "network data", PERMS_PRIVATE);
     createDirectory(getNetworkLevelDir(NULL), "main network level", PERMS_PRIVATE);
     createDirectory(getNetworkLevelDir(level_subdir), "network level", PERMS_PRIVATE);
@@ -1108,7 +1134,7 @@ void InitLevelSetupDirectory(char *level_subdir)
 
 static void InitCacheDirectory(void)
 {
 
 static void InitCacheDirectory(void)
 {
-  createDirectory(getUserGameDataDir(), "user data", PERMS_PRIVATE);
+  createDirectory(getMainUserGameDataDir(), "main user data", PERMS_PRIVATE);
   createDirectory(getCacheDir(), "cache data", PERMS_PRIVATE);
 }
 
   createDirectory(getCacheDir(), "cache data", PERMS_PRIVATE);
 }
 
@@ -1552,23 +1578,31 @@ char *getPersonalDataDir(void)
   return personal_data_dir;
 }
 
   return personal_data_dir;
 }
 
-char *getUserGameDataDir(void)
+char *getMainUserGameDataDir(void)
 {
 {
-  static char *user_game_data_dir = NULL;
+  static char *main_user_data_dir = NULL;
 
 #if defined(PLATFORM_ANDROID)
 
 #if defined(PLATFORM_ANDROID)
-  if (user_game_data_dir == NULL)
-    user_game_data_dir = (char *)(SDL_AndroidGetExternalStorageState() &
+  if (main_user_data_dir == NULL)
+    main_user_data_dir = (char *)(SDL_AndroidGetExternalStorageState() &
                                  SDL_ANDROID_EXTERNAL_STORAGE_WRITE ?
                                  SDL_AndroidGetExternalStoragePath() :
                                  SDL_AndroidGetInternalStoragePath());
 #else
                                  SDL_ANDROID_EXTERNAL_STORAGE_WRITE ?
                                  SDL_AndroidGetExternalStoragePath() :
                                  SDL_AndroidGetInternalStoragePath());
 #else
-  if (user_game_data_dir == NULL)
-    user_game_data_dir = getPath2(getPersonalDataDir(),
+  if (main_user_data_dir == NULL)
+    main_user_data_dir = getPath2(getPersonalDataDir(),
                                  program.userdata_subdir);
 #endif
 
                                  program.userdata_subdir);
 #endif
 
-  return user_game_data_dir;
+  return main_user_data_dir;
+}
+
+char *getUserGameDataDir(void)
+{
+  if (user.nr == 0)
+    return getMainUserGameDataDir();
+  else
+    return getUserDir(user.nr);
 }
 
 char *getSetupDir(void)
 }
 
 char *getSetupDir(void)
@@ -1636,9 +1670,20 @@ void createDirectory(char *dir, char *text, int permission_class)
   posix_umask(last_umask);             // restore previous umask
 }
 
   posix_umask(last_umask);             // restore previous umask
 }
 
+void InitMainUserDataDirectory(void)
+{
+  createDirectory(getMainUserGameDataDir(), "main user data", PERMS_PRIVATE);
+}
+
 void InitUserDataDirectory(void)
 {
 void InitUserDataDirectory(void)
 {
-  createDirectory(getUserGameDataDir(), "user data", PERMS_PRIVATE);
+  createDirectory(getMainUserGameDataDir(), "main user data", PERMS_PRIVATE);
+
+  if (user.nr != 0)
+  {
+    createDirectory(getUserDir(-1), "users", PERMS_PRIVATE);
+    createDirectory(getUserDir(user.nr), "user data", PERMS_PRIVATE);
+  }
 }
 
 void SetFilePermissions(char *filename, int permission_class)
 }
 
 void SetFilePermissions(char *filename, int permission_class)
index 59173924a7bcad6a9c8b94f9a99bb2724d9ce428..425c01fa5d22a7caf1e50140acb8a0f3166f08db 100644 (file)
@@ -280,6 +280,7 @@ void freeTreeInfo(TreeInfo *);
 char *getHomeDir(void);
 char *getCommonDataDir(void);
 char *getPersonalDataDir(void);
 char *getHomeDir(void);
 char *getCommonDataDir(void);
 char *getPersonalDataDir(void);
+char *getMainUserGameDataDir(void);
 char *getUserGameDataDir(void);
 char *getSetupDir(void);
 char *getLevelDirFromTreeInfo(TreeInfo *);
 char *getUserGameDataDir(void);
 char *getSetupDir(void);
 char *getLevelDirFromTreeInfo(TreeInfo *);
@@ -289,6 +290,7 @@ char *getCurrentLevelDir(void);
 char *getNewUserLevelSubdir(void);
 
 void createDirectory(char *, char *, int);
 char *getNewUserLevelSubdir(void);
 
 void createDirectory(char *, char *, int);
+void InitMainUserDataDirectory(void);
 void InitUserDataDirectory(void);
 void SetFilePermissions(char *, int);
 
 void InitUserDataDirectory(void);
 void SetFilePermissions(char *, int);
 
index a7a12792b3668d0bfd41397679835774d89be2b6..e852d2ed4aa99eccc7bb282fc74c74a6cfafc1e3 100644 (file)
@@ -80,7 +80,7 @@ void InitProgramInfo(char *argv0, char *config_filename, char *userdata_subdir,
   program.config_filename = config_filename;
 
   program.userdata_subdir = userdata_subdir;
   program.config_filename = config_filename;
 
   program.userdata_subdir = userdata_subdir;
-  program.userdata_path = getUserGameDataDir();
+  program.userdata_path = getMainUserGameDataDir();
 
   program.program_title = program_title;
   program.window_title = "(undefined)";
 
   program.program_title = program_title;
   program.window_title = "(undefined)";
index 3962dbdba4107a6e5fae8890a49d73cb832dee3a..48a03fc1a80e43e8385a2177bb756646ea973571 100644 (file)
 #define CACHE_DIRECTORY                "cache"
 #define CONF_DIRECTORY         "conf"
 #define NETWORK_DIRECTORY      "network"
 #define CACHE_DIRECTORY                "cache"
 #define CONF_DIRECTORY         "conf"
 #define NETWORK_DIRECTORY      "network"
+#define USERS_DIRECTORY                "users"
 
 #define GFX_CLASSIC_SUBDIR     "gfx_classic"
 #define SND_CLASSIC_SUBDIR     "snd_classic"
 
 #define GFX_CLASSIC_SUBDIR     "gfx_classic"
 #define SND_CLASSIC_SUBDIR     "snd_classic"