* allow changing the name of the base folder used to store save data via saves_folder_name, by default it would be Goldberg SteamEmu Saves

* changed the environment variable `SteamAppPath` to `GseAppPath`
* allow loading `config.ini` from global settings path + merge it with the local one, and allow the local one to override the global one
* fixed the path returned by `get_user_appdata_path()` to include the path separator
* updated readmes
This commit is contained in:
otavepto 2024-04-16 22:58:05 +02:00
parent e7bc867b56
commit 35c0c408b9
12 changed files with 198 additions and 72 deletions

View File

@ -2,10 +2,14 @@
---
* **[breaking]** move some settings inside a new file `config.ini` which has to be created inside the `steam_settings` folder
* **[breaking]** move some settings inside a new file `config.ini` which could be created inside the `steam_settings` folder, or inside the global settings folder, which is located at `%appdata%\Goldberg SteamEmu Saves\settings\` on Windows for example.
you can create a global `.ini` file `Goldberg SteamEmu Saves/settings/config.ini` for the common options, and another local one `steam_settings/config.ini` for the game-specific options, and the emu will merge them.
---
* **[breaking]** changed the environment variable `SteamAppPath` to `GseAppPath`, which is used to override the program path detected by the emu
* allow changing the name of the base folder used to store save data, by default it would be `Goldberg SteamEmu Saves`, suggested by **[Clompress]**
this could be changed by setting the option `saves_folder_name` inside the local file `steam_settings/config.ini`, the global one will not work
* allow creating the file `local_save.txt` inside the `steam_settings` folder
* increase run callbacks background thread polling time to `~200ms`
* changed the overlay title to give proper credits to its author

View File

@ -218,7 +218,7 @@ std::string get_full_lib_path()
std::string get_full_program_path()
{
std::string env_program_path = get_env_variable("SteamAppPath");
std::string env_program_path = get_env_variable("GseAppPath");
if (env_program_path.length()) {
if (env_program_path.back() != PATH_SEPARATOR[0]) {
env_program_path = env_program_path.append(PATH_SEPARATOR);

View File

@ -54,6 +54,7 @@
#include <cstdint>
#include <algorithm>
#include <string>
#include <string_view>
#include <chrono>
#include <cctype>
#include <iomanip>
@ -237,14 +238,6 @@ static inline void reset_LastError()
#define SERVER_HSTEAMUSER 1
#define DEFAULT_NAME "orca"
#define PROGRAM_NAME_1 "Go"
#define PROGRAM_NAME_2 "ld"
#define PROGRAM_NAME_3 "be"
#define PROGRAM_NAME_4 "rg "
#define PROGRAM_NAME_5 "St"
#define PROGRAM_NAME_6 "ea"
#define PROGRAM_NAME_7 "mE"
#define PROGRAM_NAME_8 "mu"
#define DEFAULT_LANGUAGE "english"

View File

@ -42,30 +42,39 @@ struct image_t
};
class Local_Storage {
public:
static constexpr auto inventory_storage_folder = "inventory";
static constexpr auto settings_storage_folder = "settings";
static constexpr auto remote_storage_folder = "remote";
static constexpr auto stats_storage_folder = "stats";
static constexpr auto leaderboard_storage_folder = "leaderboard";
static constexpr auto user_data_storage = "local";
static constexpr auto screenshots_folder = "screenshots";
static constexpr auto game_settings_folder = "steam_settings";
private:
std::string save_directory;
std::string appid;
static std::string saves_folder_name;
public:
static constexpr char inventory_storage_folder[] = "inventory";
static constexpr char settings_storage_folder[] = "settings";
static constexpr char remote_storage_folder[] = "remote";
static constexpr char stats_storage_folder[] = "stats";
static constexpr char leaderboard_storage_folder[] = "leaderboard";
static constexpr char user_data_storage[] = "local";
static constexpr char screenshots_folder[] = "screenshots";
static constexpr char game_settings_folder[] = "steam_settings";
static std::string get_program_path();
static std::string get_game_settings_path();
static std::string get_user_appdata_path();
static int get_file_data(const std::string &full_path, char *data, unsigned int max_length, unsigned int offset=0);
static int store_file_data(std::string folder, std::string file, const char *data, unsigned int length);
static std::vector<std::string> get_filenames_path(std::string path);
static std::vector<std::string> get_folders_path(std::string path);
static void set_saves_folder_name(const std::string_view &str);
static const std::string& get_saves_folder_name();
private:
std::string save_directory{};
std::string appid{}; // game appid
public:
Local_Storage(const std::string &save_directory);
void setAppId(uint32 appid);
int store_data(std::string folder, std::string file, char *data, unsigned int length);
int store_data_settings(std::string file, const char *data, unsigned int length);

View File

@ -346,7 +346,7 @@ static Lobby_Member *get_lobby_member(Lobby *lobby, CSteamID user_id)
int GetFavoriteGameCount()
{
PRINT_DEBUG_ENTRY();
std::string file_path = Local_Storage::get_user_appdata_path() + "/7/" + Local_Storage::remote_storage_folder + "/serverbrowser_favorites.txt";
std::string file_path = Local_Storage::get_user_appdata_path() + "7" + PATH_SEPARATOR + Local_Storage::remote_storage_folder + PATH_SEPARATOR + "serverbrowser_favorites.txt";
unsigned long long file_size = file_size_(file_path);
if (file_size) {
std::string list{};
@ -381,11 +381,11 @@ int AddFavoriteGame( AppId_t nAppID, uint32 nIP, uint16 nConnPort, uint16 nQuery
unsigned long long file_size;
if (unFlags == 1) {
file_path = Local_Storage::get_user_appdata_path() + "/7/" + Local_Storage::remote_storage_folder + "/serverbrowser_favorites.txt";
file_path = Local_Storage::get_user_appdata_path() + "7" + PATH_SEPARATOR + Local_Storage::remote_storage_folder + PATH_SEPARATOR + "serverbrowser_favorites.txt";
file_size = file_size_(file_path);
}
else if (unFlags == 2) {
file_path = Local_Storage::get_user_appdata_path() + "/7/" + Local_Storage::remote_storage_folder + "/serverbrowser_history.txt";
file_path = Local_Storage::get_user_appdata_path() + "7" + PATH_SEPARATOR + Local_Storage::remote_storage_folder + PATH_SEPARATOR + "serverbrowser_history.txt";
file_size = file_size_(file_path);
}
else {
@ -454,11 +454,11 @@ bool RemoveFavoriteGame( AppId_t nAppID, uint32 nIP, uint16 nConnPort, uint16 nQ
unsigned long long file_size;
if (unFlags == 1) {
file_path = Local_Storage::get_user_appdata_path() + "/7/" + Local_Storage::remote_storage_folder + "/serverbrowser_favorites.txt";
file_path = Local_Storage::get_user_appdata_path() + "7" + PATH_SEPARATOR + Local_Storage::remote_storage_folder + "serverbrowser_favorites.txt";
file_size = file_size_(file_path);
}
else if (unFlags == 2) {
file_path = Local_Storage::get_user_appdata_path() + "/7/" + Local_Storage::remote_storage_folder + "/serverbrowser_history.txt";
file_path = Local_Storage::get_user_appdata_path() + "7" + PATH_SEPARATOR + Local_Storage::remote_storage_folder + "serverbrowser_history.txt";
file_size = file_size_(file_path);
}
else {

View File

@ -34,24 +34,58 @@
#include "stb/stb_image_resize.h"
struct File_Data {
std::string name;
std::string name{};
};
std::string Local_Storage::saves_folder_name = "Goldberg SteamEmu Saves";
#ifdef NO_DISK_WRITES
std::string Local_Storage::get_program_path()
{
return " ";
}
std::string Local_Storage::get_game_settings_path()
{
return " ";
}
std::string Local_Storage::get_user_appdata_path()
{
return " ";
}
std::string Local_Storage::get_game_settings_path()
int Local_Storage::get_file_data(const std::string &full_path, char *data, unsigned int max_length, unsigned int offset)
{
return " ";
return -1;
}
int Local_Storage::store_file_data(std::string folder, std::string file, const char *data, unsigned int length)
{
return -1;
}
std::vector<std::string> Local_Storage::get_filenames_path(std::string path)
{
return std::vector<std::string>();
}
std::vector<std::string> Local_Storage::get_folders_path(std::string path)
{
return std::vector<std::string>();
}
void Local_Storage::set_saves_folder_name(const std::string_view &str)
{
}
const std::string& Local_Storage::get_saves_folder_name()
{
const static std::string empty{};
return empty;
}
std::string Local_Storage::get_path(std::string folder)
@ -74,11 +108,6 @@ void Local_Storage::setAppId(uint32 appid)
}
int Local_Storage::store_file_data(std::string folder, std::string file, const char *data, unsigned int length)
{
return -1;
}
int Local_Storage::store_data(std::string folder, std::string file, char *data, unsigned int length)
{
return -1;
@ -89,11 +118,6 @@ int Local_Storage::store_data_settings(std::string file, const char *data, unsig
return -1;
}
int Local_Storage::get_file_data(const std::string &full_path, char *data, unsigned int max_length, unsigned int offset)
{
return -1;
}
int Local_Storage::get_data(std::string folder, std::string file, char *data, unsigned int max_length, unsigned int offset)
{
return -1;
@ -154,16 +178,6 @@ bool Local_Storage::write_json_file(std::string folder, std::string const&file,
return false;
}
std::vector<std::string> Local_Storage::get_filenames_path(std::string path)
{
return std::vector<std::string>();
}
std::vector<std::string> Local_Storage::get_folders_path(std::string path)
{
return std::vector<std::string>();
}
std::vector<image_pixel_t> Local_Storage::load_image(std::string const& image_path)
{
return std::vector<image_pixel_t>();
@ -459,7 +473,7 @@ std::string Local_Storage::get_user_appdata_path()
}
}
#endif
return user_appdata_path.append(PATH_SEPARATOR).append(PROGRAM_NAME_1).append(PROGRAM_NAME_2).append(PROGRAM_NAME_3).append(PROGRAM_NAME_4).append(PROGRAM_NAME_5).append(PROGRAM_NAME_6).append(PROGRAM_NAME_7).append(PROGRAM_NAME_8).append(" Saves");
return user_appdata_path.append(PATH_SEPARATOR).append(get_saves_folder_name()).append(PATH_SEPARATOR);
}
static std::string replace_with(std::string s, std::string const &old, const char *new_str)
@ -600,6 +614,16 @@ std::vector<std::string> Local_Storage::get_folders_path(std::string path)
return output;
}
void Local_Storage::set_saves_folder_name(const std::string_view &str)
{
Local_Storage::saves_folder_name = str;
}
const std::string& Local_Storage::get_saves_folder_name()
{
return Local_Storage::saves_folder_name;
}
int Local_Storage::store_data(std::string folder, std::string file, char *data, unsigned int length)
{
if (folder.size() && folder.back() != *PATH_SEPARATOR) {

View File

@ -1298,16 +1298,96 @@ static void load_main_config()
if (loaded) return;
loaded = true;
std::ifstream ini_file(Local_Storage::get_game_settings_path() + "configs.ini", std::ios::binary | std::ios::in);
if (!ini_file.is_open()) {
PRINT_DEBUG("failed to open configs.ini");
return;
}
constexpr const static auto merge_ini = [](const CSimpleIniA &new_ini) {
std::list<CSimpleIniA::Entry> sections{};
new_ini.GetAllSections(sections);
for (auto const &sec : sections) {
std::list<CSimpleIniA::Entry> keys{};
new_ini.GetAllKeys(sec.pItem, keys);
for (auto const &key : keys) {
std::list<CSimpleIniA::Entry> vals{};
new_ini.GetAllValues(sec.pItem, key.pItem, vals);
for (const auto &val : vals) {
ini.SetValue(sec.pItem, key.pItem, val.pItem);
}
}
}
};
ini.SetUnicode();
auto err = ini.LoadData(ini_file);
PRINT_DEBUG("result of parsing configs.ini %i (success == 0)", (int)err);
ini_file.close();
CSimpleIniA local_ini{};
local_ini.SetUnicode();
// we have to load the local one first, since it might change base saves_folder_name
{
std::ifstream local_ini_file(Local_Storage::get_game_settings_path() + "configs.ini", std::ios::binary | std::ios::in);
if (local_ini_file.is_open()) {
auto err = local_ini.LoadData(local_ini_file);
PRINT_DEBUG("result of parsing local configs.ini %i (success == 0)", (int)err);
local_ini_file.close();
if (err == SI_OK) {
std::string saves_folder_name{};
auto ptr = local_ini.GetValue("saves", "saves_folder_name", nullptr);
if (ptr && ptr[0]) {
saves_folder_name = Settings::sanitize(common_helpers::string_strip(ptr));
}
if (saves_folder_name.size()) {
Local_Storage::set_saves_folder_name(saves_folder_name);
PRINT_DEBUG("changed name of the base folder used for save data to '%s'", saves_folder_name.c_str());
}
}
}
}
{
CSimpleIniA global_ini{};
global_ini.SetUnicode();
std::ifstream ini_file(Local_Storage::get_user_appdata_path() + Local_Storage::settings_storage_folder + PATH_SEPARATOR + "configs.ini", std::ios::binary | std::ios::in);
if (ini_file.is_open()) {
auto err = global_ini.LoadData(ini_file);
PRINT_DEBUG("result of parsing global configs.ini %i (success == 0)", (int)err);
ini_file.close();
if (err == SI_OK) {
merge_ini(global_ini);
}
}
}
if (!local_ini.IsEmpty()) {
merge_ini(local_ini);
}
#ifndef EMU_RELEASE_BUILD
// dump the final ini file
{
PRINT_DEBUG("final ini start ---------");
std::list<CSimpleIniA::Entry> sections{};
ini.GetAllSections(sections);
for (auto const &sec : sections) {
PRINT_DEBUG("[%s]", sec.pItem);
std::list<CSimpleIniA::Entry> keys{};
ini.GetAllKeys(sec.pItem, keys);
for (auto const &key : keys) {
std::list<CSimpleIniA::Entry> vals{};
ini.GetAllValues(sec.pItem, key.pItem, vals);
for (const auto &val : vals) {
PRINT_DEBUG("%s=%s", key.pItem, val.pItem);
}
}
PRINT_DEBUG("");
}
PRINT_DEBUG("final ini end *********");
}
#endif // EMU_RELEASE_BUILD
reset_LastError();
}
@ -1335,6 +1415,7 @@ uint32 create_localstorage_settings(Settings **settings_client_out, Settings **s
PRINT_DEBUG("program path: '%s', save path: '%s'", program_path.c_str(), save_path.c_str());
Local_Storage *local_storage = new Local_Storage(save_path);
PRINT_DEBUG("global settings path for this app/game: '%s'", local_storage->get_global_settings_path().c_str());
local_storage->setAppId(appid);
// Listen port

View File

@ -88,13 +88,13 @@ HServerListRequest Steam_Matchmaking_Servers::RequestServerList(AppId_t iApp, IS
std::string file_path;
unsigned long long file_size;
if (type == eInternetServer || type == eSpectatorServer) {
file_path = Local_Storage::get_user_appdata_path() + "/7/" + Local_Storage::remote_storage_folder + "/serverbrowser.txt";
file_path = Local_Storage::get_user_appdata_path() + "7" + PATH_SEPARATOR + Local_Storage::remote_storage_folder + PATH_SEPARATOR + "serverbrowser.txt";
file_size = file_size_(file_path);
} else if (type == eFavoritesServer) {
file_path = Local_Storage::get_user_appdata_path() + "/7/" + Local_Storage::remote_storage_folder + "/serverbrowser_favorites.txt";
file_path = Local_Storage::get_user_appdata_path() + "7" + PATH_SEPARATOR + Local_Storage::remote_storage_folder + PATH_SEPARATOR + "serverbrowser_favorites.txt";
file_size = file_size_(file_path);
} else if (type == eHistoryServer) {
file_path = Local_Storage::get_user_appdata_path() + "/7/" + Local_Storage::remote_storage_folder + "/serverbrowser_history.txt";
file_path = Local_Storage::get_user_appdata_path() + "7" + PATH_SEPARATOR + Local_Storage::remote_storage_folder + PATH_SEPARATOR + "serverbrowser_history.txt";
file_size = file_size_(file_path);
}

View File

@ -3,7 +3,7 @@ This is the debug build of the emu, while the game/app is running
the emu will write various events to a log file called `STEAM_LOG.txt`.
## Where is this log file ?
Generally it should be beside the .dll/.so iteself, unless the environment variable `SteamAppPath`
Generally it should be beside the .dll/.so iteself, unless the environment variable `GseAppPath`
is defined, in which case this will be the path of this log file
## Why ?

View File

@ -29,20 +29,28 @@ so it is recommended to check each example file in the `steam_settings` folder,
## Saves location:
* On Windows:
`C:\Users\<Your windows user name>\AppData\Roaming\Goldberg SteamEmu Saves\`
`%appdata%\Goldberg SteamEmu Saves\`
For example, if your user Windows user name is `Lion`, the save location would be:
`C:\Users\Lion\AppData\Roaming\Goldberg SteamEmu Saves\`
* On Linux:
* if `XDG_DATA_HOME` is defined:
`$XDG_DATA_HOME/Goldberg SteamEmu Saves/`
* Otherwise:
* Otherwise, if `HOME` is defined:
`$HOME/.local/share/Goldberg SteamEmu Saves/`
* Otherwise:
`SAVE/Goldberg SteamEmu Saves/` (relative to the current directory, which might not be the same as app/game directory)
You can override the name of the base folder `Goldberg SteamEmu Saves` to whatever you want per game, to do this modify `configs.ini` inside your `steam_settings` folder and change the value of `saves_folder_name`.
Check the example file in `steam_settings.EXAMPLE\configs.EXAMPLE.ini`.
---
In the global settings folder in that save location you will find these files (if you have used the emulator at least once):
In the global settings folder, in that save location, you will find these files (if you have used the emulator at least once):
* `account_name.txt`: edit this file to change your name
* `listen_port.txt`: edit this file if you want to change the UDP/TCP port the emulator listens on, you should probably not change this because everyone needs to use the same port or you won't find yourselves on the network
* `user_steam_id.txt` this is where your steam id is saved, you can change it, if your saves for a game are locked to a specific steam id see below for a way to change it on a per game basis, but it has to be valid
* `language.txt`: edit this to change the language the emulator will report to the game, default is `english`, it must be a valid steam language name or the game might have weird behaviour (list provided at the end of this readme)
* You can also create the file `configs.ini` and specify the most common options you usually set, you can use the provided example file `steam_settings.EXAMPLE\configs.EXAMPLE.ini` as a base. Note that you do not have to specify everything
Note that these are global so you won't have to change them for each game. For game unique stuff (stats and remote storage) a folder is created with the appid of the game.
If you want to change your steam_id on a per game basis, simply create a settings folder in the game unique directory (Full path: `C:\Users\<Your windows user name>\AppData\Roaming\Goldberg SteamEmu Saves\<appid>\settings`)

View File

@ -1,8 +1,10 @@
# you do not have to specify everything, pick and choose the options you need only
[general]
# generate new app auth ticket
new_app_ticket=0
# generate/embed generate GC inside new App Ticket
gc_token=0
new_app_ticket=1
# generate/embed generate GC token inside new App Ticket
gc_token=1
# disable avatar functionality
disable_account_avatar=0
# make the game/app think we're playing on a beta branch
@ -28,7 +30,7 @@ matchmaking_server_details_via_source_query=0
[connectivity]
# prevent hooking OS networking APIs and allow any external requests
# only used by the experimental builds on Windows
disable_lan_only=0
disable_lan_only=1
# disable all steam networking interface functionality
# this won't prevent games/apps from making external requests
disable_networking=0
@ -51,6 +53,11 @@ download_steamhttp_requests=0
# force the function Steam_HTTP::SendHTTPRequest() to always succeed
force_steamhttp_success=0
[saves]
# name of the base folder used to store save data, leading and trailing whitespaces are trimmed
# default=Goldberg SteamEmu Saves
saves_folder_name=Goldberg SteamEmu Saves
[overlay]
# ---------------------
# USE AT YOUR OWN RISK

View File

@ -214,7 +214,7 @@ if [ ! -z "${STEAM_RUNTIME}" ]; then
)
fi
SteamAppPath="${EXE_RUN_DIR}" SteamAppId=$APP_ID SteamGameId=$APP_ID SteamOverlayGameId=$APP_ID SteamAppUser='client_player' SteamUser='client_player' SteamClientLaunch='1' SteamEnv='1' SteamPath="$script_dir" "$TARGET_EXE" "${EXE_COMMAND_LINE[@]}"
GseAppPath="${EXE_RUN_DIR}" SteamAppId=$APP_ID SteamGameId=$APP_ID SteamOverlayGameId=$APP_ID SteamAppUser='client_player' SteamUser='client_player' SteamClientLaunch='1' SteamEnv='1' SteamPath="$script_dir" "$TARGET_EXE" "${EXE_COMMAND_LINE[@]}"
popd