Merge branch 'master' into achievements_support

merge-requests/24/head
Nemirtingas 2019-08-26 19:45:58 +02:00
commit 7a59f48000
15 changed files with 540 additions and 326 deletions

View File

@ -87,6 +87,13 @@ For the sort methods: 0 = none, 1 = ascending, 2 = descending
For the display type: 0 = none, 1 = numeric, 2 = time seconds, 3 = milliseconds
An example can be found in steam_settings.EXAMPLE
Stats:
By default this emulators assumes all stats do not exist unless they have been written once by the game. This works for the majority of games but some games might read a stat for the first time
and expect a default value to be read when doing so. To set the type for each stat along with the default value, put a stats.txt file in the steam_settings/ folder.
The format is: STAT_NAME=type=default value
The type can be: int, float or avgrate
The default value is simply a number that represents the default value for the stat.
Support for CPY steam_api(64).dll cracks: See the build in the experimental folder.

View File

@ -1,16 +1,22 @@
if exist "C:\Program Files (x86)\Microsoft Visual Studio 14.0\VC\bin\amd64\vcvars64.bat" goto vs14
if exist "C:\Program Files (x86)\Microsoft Visual Studio\2017\BuildTools\VC\Auxiliary\Build\vcvars64.bat" goto vs2017
if exist "C:\Program Files (x86)\Microsoft Visual Studio\2019\BuildTools\VC\Auxiliary\Build\vcvars64.bat" goto vs2019
@echo off
cd /d "%~dp0"
rem Put in the base path in which Visual Studio is installed, default would be C:\Program Files (x86)
:vs14
call "C:\Program Files (x86)\Microsoft Visual Studio 14.0\VC\bin\amd64\vcvars64.bat"
set VS_Base_Path=C:\Program Files (x86)
if exist "%VS_Base_Path%\Microsoft Visual Studio\2019\Community\VC\Auxiliary\Build\vcvars64.bat" goto vs2019
if exist "%VS_Base_Path%\Microsoft Visual Studio\2017\Community\VC\Auxiliary\Build\vcvars64.bat" goto vs2017
if exist "%VS_Base_Path%\Microsoft Visual Studio 14.0\VC\bin\amd64\vcvars64.bat" goto vs14
:vs2019
call "%VS_Base_Path%\Microsoft Visual Studio\2019\Community\VC\Auxiliary\Build\vcvars64.bat"
goto batend
:vs2017
call "C:\Program Files (x86)\Microsoft Visual Studio\2017\BuildTools\VC\Auxiliary\Build\vcvars64.bat"
call "%VS_Base_Path%\Microsoft Visual Studio\2017\Community\VC\Auxiliary\Build\vcvars64.bat"
goto batend
:vs2019
call "C:\Program Files (x86)\Microsoft Visual Studio\2019\BuildTools\VC\Auxiliary\Build\vcvars64.bat"
:vs14
call "%VS_Base_Path%\Microsoft Visual Studio 14.0\VC\bin\amd64\vcvars64.bat"
goto batend
:batend

View File

@ -1,16 +1,22 @@
if exist "C:\Program Files (x86)\Microsoft Visual Studio 14.0\VC\bin\vcvars32.bat" goto vs14
if exist "C:\Program Files (x86)\Microsoft Visual Studio\2017\BuildTools\VC\Auxiliary\Build\vcvars32.bat" goto vs2017
if exist "C:\Program Files (x86)\Microsoft Visual Studio\2019\BuildTools\VC\Auxiliary\Build\vcvars32.bat" goto vs2019
@echo off
cd /d "%~dp0"
rem Put in the base path in which Visual Studio is installed, default would be C:\Program Files (x86)
:vs14
call "C:\Program Files (x86)\Microsoft Visual Studio 14.0\VC\bin\vcvars32.bat"
set VS_Base_Path=C:\Program Files (x86)
if exist "%VS_Base_Path%\Microsoft Visual Studio\2019\Community\VC\Auxiliary\Build\vcvars32.bat" goto vs2019
if exist "%VS_Base_Path%\Microsoft Visual Studio\2017\Community\VC\Auxiliary\Build\vcvars32.bat" goto vs2017
if exist "%VS_Base_Path%\Microsoft Visual Studio 14.0\VC\bin\amd64_x86\vcvarsamd64_x86.bat" goto vs14
:vs2019
call "%VS_Base_Path%\Microsoft Visual Studio\2019\Community\VC\Auxiliary\Build\vcvars32.bat"
goto batend
:vs2017
call "C:\Program Files (x86)\Microsoft Visual Studio\2017\BuildTools\VC\Auxiliary\Build\vcvars32.bat"
call "%VS_Base_Path%\Microsoft Visual Studio\2017\Community\VC\Auxiliary\Build\vcvars32.bat"
goto batend
:vs2019
call "C:\Program Files (x86)\Microsoft Visual Studio\2019\BuildTools\VC\Auxiliary\Build\vcvars32.bat"
:vs14
call "%VS_Base_Path%\Microsoft Visual Studio 14.0\VC\bin\amd64_x86\vcvarsamd64_x86.bat"
goto batend
:batend

View File

@ -1,12 +1,16 @@
@echo off
cd /d "%~dp0"
call build_set_protobuf_directories.bat
%PROTOBUF_X86_DIRECTORY%%PROTOC_DIRECTORY% -I.\dll\ --cpp_out=.\dll\ .\dll\net.proto
"%PROTOC_X86_EXE%" -I.\dll\ --cpp_out=.\dll\ .\dll\net.proto
call build_env_x86.bat
cl dll/rtlgenrandom.c dll/rtlgenrandom.def
cl /LD /I%PROTOBUF_X86_DIRECTORY%\include\ /DEMU_EXPERIMENTAL_BUILD dll/*.cpp dll/*.cc detours/*.cpp %PROTOBUF_X86_DIRECTORY%%PROTOBUF_LIBRARY% Iphlpapi.lib Ws2_32.lib rtlgenrandom.lib Shell32.lib /EHsc /MP12 /link /OUT:steam_api.dll
cl /LD /I%PROTOBUF_X86_DIRECTORY%\include\ /DEMU_EXPERIMENTAL_BUILD dll/*.cpp dll/*.cc detours/*.cpp "%PROTOBUF_X86_LIBRARY%" Iphlpapi.lib Ws2_32.lib rtlgenrandom.lib Shell32.lib /EHsc /MP12 /link /OUT:steam_api.dll
cl /LD steamclient.cpp /EHsc /MP12 /link /OUT:steamclient.dll
cl /LD steamnetworkingsockets.cpp /EHsc /MP12 /link /OUT:steamnetworkingsockets.dll
"%PROTOC_X64_EXE%" -I.\dll\ --cpp_out=.\dll\ .\dll\net.proto
call build_env_x64.bat
cl dll/rtlgenrandom.c dll/rtlgenrandom.def
cl /LD /I%PROTOBUF_X64_DIRECTORY%\include\ /DEMU_EXPERIMENTAL_BUILD dll/*.cpp dll/*.cc detours/*.cpp %PROTOBUF_X64_DIRECTORY%%PROTOBUF_LIBRARY% Iphlpapi.lib Ws2_32.lib rtlgenrandom.lib Shell32.lib /EHsc /MP12 /link /OUT:steam_api64.dll
cl /LD /I%PROTOBUF_X64_DIRECTORY%\include\ /DEMU_EXPERIMENTAL_BUILD dll/*.cpp dll/*.cc detours/*.cpp "%PROTOBUF_X64_LIBRARY%" Iphlpapi.lib Ws2_32.lib rtlgenrandom.lib Shell32.lib /EHsc /MP12 /link /OUT:steam_api64.dll
cl /LD steamclient.cpp /EHsc /MP12 /link /OUT:steamclient64.dll
cl /LD steamnetworkingsockets.cpp /EHsc /MP12 /link /OUT:steamnetworkingsockets64.dll

View File

@ -1,3 +1,5 @@
@ecbo off
cd /d "%~dp0"
mkdir release\tools
del /Q release\tools\*
call build_env_x86.bat

View File

@ -1,10 +1,12 @@
@echo off
cd /d "%~dp0"
mkdir release\lobby_connect
del /Q release\lobby_connect\*
call build_set_protobuf_directories.bat
%PROTOBUF_X86_DIRECTORY%%PROTOC_DIRECTORY% -I.\dll\ --cpp_out=.\dll\ .\dll\net.proto
"%PROTOC_X86_EXE%" -I.\dll\ --cpp_out=.\dll\ .\dll\net.proto
call build_env_x86.bat
cl dll/rtlgenrandom.c dll/rtlgenrandom.def
cl /DNO_DISK_WRITES /DLOBBY_CONNECT /DEMU_RELEASE_BUILD /DNDEBUG /I%PROTOBUF_X86_DIRECTORY%\include\ lobby_connect.cpp dll/*.cpp dll/*.cc %PROTOBUF_X86_DIRECTORY%%PROTOBUF_LIBRARY% Iphlpapi.lib Ws2_32.lib rtlgenrandom.lib Shell32.lib Comdlg32.lib /EHsc /MP12 /Ox /link /debug:none /OUT:release\lobby_connect\lobby_connect.exe
cl /DNO_DISK_WRITES /DLOBBY_CONNECT /DEMU_RELEASE_BUILD /DNDEBUG /I%PROTOBUF_X86_DIRECTORY%\include\ lobby_connect.cpp dll/*.cpp dll/*.cc "%PROTOBUF_X86_LIBRARY%" Iphlpapi.lib Ws2_32.lib rtlgenrandom.lib Shell32.lib Comdlg32.lib /EHsc /MP12 /Ox /link /debug:none /OUT:release\lobby_connect\lobby_connect.exe
del /Q /S release\lobby_connect\*.lib
del /Q /S release\lobby_connect\*.exp
copy Readme_lobby_connect.txt release\lobby_connect\Readme.txt

View File

@ -1,17 +1,20 @@
@echo off
cd /d "%~dp0"
del /Q /S release\*
rmdir /S /Q release\experimental
rmdir /S /Q release\lobby_connect
rmdir /S /Q release
mkdir release
call build_set_protobuf_directories.bat
%PROTOBUF_X86_DIRECTORY%%PROTOC_DIRECTORY% -I.\dll\ --cpp_out=.\dll\ .\dll\net.proto
"%PROTOC_X86_EXE%" -I.\dll\ --cpp_out=.\dll\ .\dll\net.proto
call build_env_x86.bat
cl dll/rtlgenrandom.c dll/rtlgenrandom.def
cl /LD /DEMU_RELEASE_BUILD /DNDEBUG /I%PROTOBUF_X86_DIRECTORY%\include\ dll/*.cpp dll/*.cc %PROTOBUF_X86_DIRECTORY%%PROTOBUF_LIBRARY% Iphlpapi.lib Ws2_32.lib rtlgenrandom.lib Shell32.lib /EHsc /MP12 /Ox /link /debug:none /OUT:release\steam_api.dll
%PROTOBUF_X64_DIRECTORY%%PROTOC_DIRECTORY% -I.\dll\ --cpp_out=.\dll\ .\dll\net.proto
cl /LD /DEMU_RELEASE_BUILD /DNDEBUG /I%PROTOBUF_X86_DIRECTORY%\include\ dll/*.cpp dll/*.cc "%PROTOBUF_X86_LIBRARY%" Iphlpapi.lib Ws2_32.lib rtlgenrandom.lib Shell32.lib /EHsc /MP12 /Ox /link /debug:none /OUT:release\steam_api.dll
call build_set_protobuf_directories.bat
"%PROTOC_X64_EXE%" -I.\dll\ --cpp_out=.\dll\ .\dll\net.proto
call build_env_x64.bat
cl dll/rtlgenrandom.c dll/rtlgenrandom.def
cl /LD /DEMU_RELEASE_BUILD /DNDEBUG /I%PROTOBUF_X64_DIRECTORY%\include\ dll/*.cpp dll/*.cc %PROTOBUF_X64_DIRECTORY%%PROTOBUF_LIBRARY% Iphlpapi.lib Ws2_32.lib rtlgenrandom.lib Shell32.lib /EHsc /MP12 /Ox /link /debug:none /OUT:release\steam_api64.dll
cl /LD /DEMU_RELEASE_BUILD /DNDEBUG /I%PROTOBUF_X64_DIRECTORY%\include\ dll/*.cpp dll/*.cc "%PROTOBUF_X64_LIBRARY%" Iphlpapi.lib Ws2_32.lib rtlgenrandom.lib Shell32.lib /EHsc /MP12 /Ox /link /debug:none /OUT:release\steam_api64.dll
copy Readme_release.txt release\Readme.txt
xcopy /s files_example\* release\
call build_win_release_experimental.bat

View File

@ -1,14 +1,16 @@
@echo off
cd /d "%~dp0"
mkdir release\experimental
del /Q release\experimental\*
call build_set_protobuf_directories.bat
%PROTOBUF_X86_DIRECTORY%%PROTOC_DIRECTORY% -I.\dll\ --cpp_out=.\dll\ .\dll\net.proto
"%PROTOC_X86_EXE%" -I.\dll\ --cpp_out=.\dll\ .\dll\net.proto
call build_env_x86.bat
cl dll/rtlgenrandom.c dll/rtlgenrandom.def
cl /LD /DEMU_RELEASE_BUILD /DEMU_EXPERIMENTAL_BUILD /DNDEBUG /I%PROTOBUF_X86_DIRECTORY%\include\ dll/*.cpp dll/*.cc detours/*.cpp %PROTOBUF_X86_DIRECTORY%%PROTOBUF_LIBRARY% Iphlpapi.lib Ws2_32.lib rtlgenrandom.lib Shell32.lib /EHsc /MP12 /Ox /link /debug:none /OUT:release\experimental\steam_api.dll
cl /LD /DEMU_RELEASE_BUILD /DEMU_EXPERIMENTAL_BUILD /DNDEBUG /I%PROTOBUF_X86_DIRECTORY%\include\ dll/*.cpp dll/*.cc detours/*.cpp "%PROTOBUF_X86_LIBRARY%" Iphlpapi.lib Ws2_32.lib rtlgenrandom.lib Shell32.lib /EHsc /MP12 /Ox /link /debug:none /OUT:release\experimental\steam_api.dll
cl /LD /DEMU_RELEASE_BUILD /DEMU_EXPERIMENTAL_BUILD /DNDEBUG steamclient.cpp /EHsc /MP12 /Ox /link /OUT:release\experimental\steamclient.dll
%PROTOBUF_X64_DIRECTORY%%PROTOC_DIRECTORY% -I.\dll\ --cpp_out=.\dll\ .\dll\net.proto
"%PROTOC_X64_EXE%" -I.\dll\ --cpp_out=.\dll\ .\dll\net.proto
call build_env_x64.bat
cl dll/rtlgenrandom.c dll/rtlgenrandom.def
cl /LD /DEMU_RELEASE_BUILD /DEMU_EXPERIMENTAL_BUILD /DNDEBUG /I%PROTOBUF_X64_DIRECTORY%\include\ dll/*.cpp dll/*.cc detours/*.cpp %PROTOBUF_X64_DIRECTORY%%PROTOBUF_LIBRARY% Iphlpapi.lib Ws2_32.lib rtlgenrandom.lib Shell32.lib /EHsc /MP12 /Ox /link /debug:none /OUT:release\experimental\steam_api64.dll
cl /LD /DEMU_RELEASE_BUILD /DEMU_EXPERIMENTAL_BUILD /DNDEBUG /I%PROTOBUF_X64_DIRECTORY%\include\ dll/*.cpp dll/*.cc detours/*.cpp "%PROTOBUF_X64_LIBRARY%" Iphlpapi.lib Ws2_32.lib rtlgenrandom.lib Shell32.lib /EHsc /MP12 /Ox /link /debug:none /OUT:release\experimental\steam_api64.dll
cl /LD /DEMU_RELEASE_BUILD /DEMU_EXPERIMENTAL_BUILD /DNDEBUG steamclient.cpp /EHsc /MP12 /Ox /link /OUT:release\experimental\steamclient64.dll
copy Readme_experimental.txt release\experimental\Readme.txt

View File

@ -38,6 +38,20 @@ struct Leaderboard_config {
enum ELeaderboardDisplayType display_type;
};
enum Stat_Type {
STAT_TYPE_INT,
STAT_TYPE_FLOAT,
STAT_TYPE_AVGRATE
};
struct Stat_config {
enum Stat_Type type;
union {
float default_value_float;
uint32 default_value_int;
};
};
class Settings {
CSteamID steam_id;
CGameID game_id;
@ -50,7 +64,9 @@ class Settings {
std::vector<struct Mod_entry> mods;
std::map<AppId_t, std::string> app_paths;
std::map<std::string, Leaderboard_config> leaderboards;
std::map<std::string, Stat_config> stats;
bool create_unknown_leaderboards;
uint16 port;
public:
#ifdef LOBBY_CONNECT
@ -68,6 +84,8 @@ public:
void set_lobby(CSteamID lobby_id);
CSteamID get_lobby();
bool is_offline() {return offline; }
uint16 get_port() {return port;}
void set_port(uint16 port) { this->port = port;}
//DLC stuff
void unlockAllDLC(bool value);
@ -91,6 +109,13 @@ public:
std::map<std::string, Leaderboard_config> getLeaderboards() { return leaderboards; }
void setCreateUnknownLeaderboards(bool enable) {create_unknown_leaderboards = enable;}
bool createUnknownLeaderboards() { return create_unknown_leaderboards; }
//custom broadcasts
std::set<uint32> custom_broadcasts;
//stats
std::map<std::string, Stat_config> getStats() { return stats; }
void setStatDefiniton(std::string name, struct Stat_config stat_config) {stats[name] = stat_config; }
};
#endif

394
dll/settings_parser.cpp Normal file
View File

@ -0,0 +1,394 @@
/* Copyright (C) 2019 Mr Goldberg
This file is part of the Goldberg Emulator
The Goldberg Emulator is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 3 of the License, or (at your option) any later version.
The Goldberg Emulator is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with the Goldberg Emulator; if not, see
<http://www.gnu.org/licenses/>. */
#include "settings_parser.h"
#include <fstream>
#include <cctype>
static void load_custom_broadcasts(std::string broadcasts_filepath, std::set<uint32> &custom_broadcasts)
{
std::ifstream broadcasts_file(broadcasts_filepath);
PRINT_DEBUG("Broadcasts file path: %s\n", broadcasts_filepath.c_str());
if (broadcasts_file.is_open()) {
std::string line;
while (std::getline(broadcasts_file, line)) {
std::set<uint32> ips = Networking::resolve_ip(line);
custom_broadcasts.insert(ips.begin(), ips.end());
}
}
}
uint32 create_localstorage_settings(Settings **settings_client_out, Settings **settings_server_out, Local_Storage **local_storage_out)
{
std::string program_path = Local_Storage::get_program_path(), save_path = Local_Storage::get_user_appdata_path();;
PRINT_DEBUG("Current Path %s save_path: %s\n", program_path.c_str(), save_path.c_str());
char array[10] = {};
array[0] = '0';
Local_Storage::get_file_data(Local_Storage::get_game_settings_path() + "steam_appid.txt", array, sizeof(array) - 1);
uint32 appid = 0;
try {
appid = std::stoi(array);
} catch (...) {}
if (!appid) {
memset(array, 0, sizeof(array));
array[0] = '0';
Local_Storage::get_file_data("steam_appid.txt", array, sizeof(array) - 1);
try {
appid = std::stoi(array);
} catch (...) {}
if (!appid) {
memset(array, 0, sizeof(array));
array[0] = '0';
Local_Storage::get_file_data(program_path + "steam_appid.txt", array, sizeof(array) - 1);
try {
appid = std::stoi(array);
} catch (...) {}
}
}
if (!appid) {
std::string str_appid = get_env_variable("SteamAppId");
std::string str_gameid = get_env_variable("SteamGameId");
PRINT_DEBUG("str_appid %s str_gameid: %s\n", str_appid.c_str(), str_gameid.c_str());
uint32 appid_env = 0;
uint32 gameid_env = 0;
if (str_appid.size() > 0) {
try {
appid_env = std::stoul(str_appid);
} catch (...) {
appid_env = 0;
}
}
if (str_gameid.size() > 0) {
try {
gameid_env = std::stoul(str_gameid);
} catch (...) {
gameid_env = 0;
}
}
PRINT_DEBUG("appid_env %u gameid_env: %u\n", appid_env, gameid_env);
if (appid_env) {
appid = appid_env;
}
if (gameid_env) {
appid = gameid_env;
}
}
{
char array[33] = {};
if (Local_Storage::get_file_data(program_path + "local_save.txt", array, sizeof(array) - 1) != -1) {
save_path = program_path + Settings::sanitize(array);
}
}
PRINT_DEBUG("Set save_path: %s\n", save_path.c_str());
Local_Storage *local_storage = new Local_Storage(save_path);
local_storage->setAppId(appid);
// Listen port
char array_port[10] = {};
array_port[0] = '0';
local_storage->get_data_settings("listen_port.txt", array_port, sizeof(array_port) - 1);
uint16 port = std::stoi(array_port);
if (port == 0) {
port = DEFAULT_PORT;
snprintf(array_port, sizeof(array_port), "%hu", port);
local_storage->store_data_settings("listen_port.txt", array_port, strlen(array_port));
}
// Custom broadcasts
std::set<uint32> custom_broadcasts;
load_custom_broadcasts(local_storage->get_global_settings_path() + "custom_broadcasts.txt", custom_broadcasts);
load_custom_broadcasts(Local_Storage::get_game_settings_path() + "custom_broadcasts.txt", custom_broadcasts);
// Acount name
char name[32] = {};
if (local_storage->get_data_settings("account_name.txt", name, sizeof(name) - 1) <= 0) {
strcpy(name, DEFAULT_NAME);
local_storage->store_data_settings("account_name.txt", name, strlen(name));
}
// Language
char language[32] = {};
if (local_storage->get_data_settings("language.txt", language, sizeof(language) - 1) <= 0) {
strcpy(language, DEFAULT_LANGUAGE);
local_storage->store_data_settings("language.txt", language, strlen(language));
}
// Steam ID
char array_steam_id[32] = {};
CSteamID user_id;
uint64 steam_id = 0;
bool generate_new = false;
//try to load steam id from game specific settings folder first
if (local_storage->get_data(SETTINGS_STORAGE_FOLDER, "user_steam_id.txt", array_steam_id, sizeof(array_steam_id) - 1) > 0) {
user_id = CSteamID((uint64)std::atoll(array_steam_id));
if (!user_id.IsValid()) {
generate_new = true;
}
} else {
generate_new = true;
}
if (generate_new) {
generate_new = false;
if (local_storage->get_data_settings("user_steam_id.txt", array_steam_id, sizeof(array_steam_id) - 1) > 0) {
user_id = CSteamID((uint64)std::atoll(array_steam_id));
if (!user_id.IsValid()) {
generate_new = true;
}
} else {
generate_new = true;
}
}
if (generate_new) {
user_id = generate_steam_id_user();
uint64 steam_id = user_id.ConvertToUint64();
char temp_text[32] = {};
snprintf(temp_text, sizeof(temp_text), "%llu", steam_id);
local_storage->store_data_settings("user_steam_id.txt", temp_text, strlen(temp_text));
}
bool steam_offline_mode = false;
{
std::string steam_settings_path = Local_Storage::get_game_settings_path();
std::vector<std::string> paths = Local_Storage::get_filenames_path(steam_settings_path);
for (auto & p: paths) {
PRINT_DEBUG("steam settings path %s\n", p.c_str());
if (p == "offline.txt") {
steam_offline_mode = true;
}
}
}
Settings *settings_client = new Settings(user_id, CGameID(appid), name, language, steam_offline_mode);
Settings *settings_server = new Settings(generate_steam_id_server(), CGameID(appid), name, language, steam_offline_mode);
settings_client->set_port(port);
settings_server->set_port(port);
settings_client->custom_broadcasts = custom_broadcasts;
settings_server->custom_broadcasts = custom_broadcasts;
{
std::string dlc_config_path = Local_Storage::get_game_settings_path() + "DLC.txt";
std::ifstream input( dlc_config_path );
if (input.is_open()) {
settings_client->unlockAllDLC(false);
settings_server->unlockAllDLC(false);
PRINT_DEBUG("Locking all DLC\n");
for( std::string line; std::getline( input, line ); ) {
if (!line.empty() && line.front() == '#') {
continue;
}
if (!line.empty() && line.back() == '\n') {
line.pop_back();
}
if (!line.empty() && line.back() == '\r') {
line.pop_back();
}
std::size_t deliminator = line.find("=");
if (deliminator != 0 && deliminator != std::string::npos && deliminator != line.size()) {
AppId_t appid = stol(line.substr(0, deliminator));
std::string name = line.substr(deliminator + 1);
bool available = true;
if (appid) {
PRINT_DEBUG("Adding DLC: %u|%s| %u\n", appid, name.c_str(), available);
settings_client->addDLC(appid, name, available);
settings_server->addDLC(appid, name, available);
}
}
}
} else {
//unlock all DLC
PRINT_DEBUG("Unlocking all DLC\n");
settings_client->unlockAllDLC(true);
settings_server->unlockAllDLC(true);
}
}
{
std::string dlc_config_path = Local_Storage::get_game_settings_path() + "app_paths.txt";
std::ifstream input( dlc_config_path );
if (input.is_open()) {
for( std::string line; getline( input, line ); ) {
if (!line.empty() && line[line.length()-1] == '\n') {
line.pop_back();
}
if (!line.empty() && line[line.length()-1] == '\r') {
line.pop_back();
}
std::size_t deliminator = line.find("=");
if (deliminator != 0 && deliminator != std::string::npos && deliminator != line.size()) {
AppId_t appid = stol(line.substr(0, deliminator));
std::string rel_path = line.substr(deliminator + 1);
std::string path = canonical_path(program_path + rel_path);
if (appid) {
if (path.size()) {
PRINT_DEBUG("Adding app path: %u|%s|\n", appid, path.c_str());
settings_client->setAppInstallPath(appid, path);
settings_server->setAppInstallPath(appid, path);
} else {
PRINT_DEBUG("Error adding app path for: %u does this path exist? |%s|\n", appid, rel_path.c_str());
}
}
}
}
}
}
{
std::string dlc_config_path = Local_Storage::get_game_settings_path() + "leaderboards.txt";
std::ifstream input( dlc_config_path );
if (input.is_open()) {
settings_client->setCreateUnknownLeaderboards(false);
settings_server->setCreateUnknownLeaderboards(false);
for( std::string line; getline( input, line ); ) {
if (!line.empty() && line[line.length()-1] == '\n') {
line.pop_back();
}
if (!line.empty() && line[line.length()-1] == '\r') {
line.pop_back();
}
std::string leaderboard;
unsigned int sort_method = 0;
unsigned int display_type = 0;
std::size_t deliminator = line.find("=");
if (deliminator != 0 && deliminator != std::string::npos && deliminator != line.size()) {
leaderboard = line.substr(0, deliminator);
std::size_t deliminator2 = line.find("=", deliminator + 1);
if (deliminator2 != std::string::npos && deliminator2 != line.size()) {
sort_method = stol(line.substr(deliminator + 1, deliminator2 - (deliminator + 1)));
display_type = stol(line.substr(deliminator2 + 1));
}
}
if (leaderboard.size() && sort_method <= k_ELeaderboardSortMethodDescending && display_type <= k_ELeaderboardDisplayTypeTimeMilliSeconds) {
PRINT_DEBUG("Adding leaderboard: %s|%u|%u\n", leaderboard.c_str(), sort_method, display_type);
settings_client->setLeaderboard(leaderboard, (ELeaderboardSortMethod)sort_method, (ELeaderboardDisplayType)display_type);
settings_server->setLeaderboard(leaderboard, (ELeaderboardSortMethod)sort_method, (ELeaderboardDisplayType)display_type);
} else {
PRINT_DEBUG("Error adding leaderboard for: %s, are sort method %u or display type %u valid?\n", leaderboard.c_str(), sort_method, display_type);
}
}
}
}
{
std::string stats_config_path = Local_Storage::get_game_settings_path() + "stats.txt";
std::ifstream input( stats_config_path );
if (input.is_open()) {
for( std::string line; getline( input, line ); ) {
if (!line.empty() && line[line.length()-1] == '\n') {
line.pop_back();
}
if (!line.empty() && line[line.length()-1] == '\r') {
line.pop_back();
}
std::string stat_name;
std::string stat_type;
std::string stat_default_value;
std::size_t deliminator = line.find("=");
if (deliminator != 0 && deliminator != std::string::npos && deliminator != line.size()) {
stat_name = line.substr(0, deliminator);
std::size_t deliminator2 = line.find("=", deliminator + 1);
if (deliminator2 != std::string::npos && deliminator2 != line.size()) {
stat_type = line.substr(deliminator + 1, deliminator2 - (deliminator + 1));
stat_default_value = line.substr(deliminator2 + 1);
} else {
stat_type = line.substr(deliminator + 1);
stat_default_value = "0";
}
}
std::transform(stat_type.begin(), stat_type.end(), stat_type.begin(),[](unsigned char c){ return std::tolower(c); });
struct Stat_config config = {};
try {
if (stat_type == "float") {
config.type = Stat_Type::STAT_TYPE_FLOAT;
config.default_value_float = std::stof(stat_default_value);
} else if (stat_type == "int") {
config.type = Stat_Type::STAT_TYPE_INT;
config.default_value_int = std::stol(stat_default_value);
} else if (stat_type == "avgrate") {
config.type = Stat_Type::STAT_TYPE_AVGRATE;
config.default_value_float = std::stof(stat_default_value);
} else {
PRINT_DEBUG("Error adding stat %s, type %s isn't valid\n", stat_name.c_str(), stat_type.c_str());
continue;
}
} catch (...) {
PRINT_DEBUG("Error adding stat %s, default value %s isn't valid\n", stat_name.c_str(), stat_default_value.c_str());
continue;
}
if (stat_name.size()) {
PRINT_DEBUG("Adding stat type: %s|%u|%f|%u\n", stat_name.c_str(), config.type, config.default_value_float, config.default_value_int);
settings_client->setStatDefiniton(stat_name, config);
settings_server->setStatDefiniton(stat_name, config);
} else {
PRINT_DEBUG("Error adding stat for: %s, empty name\n", stat_name.c_str());
}
}
}
}
{
std::string mod_path = Local_Storage::get_game_settings_path() + "mods";
std::vector<std::string> paths = Local_Storage::get_filenames_path(mod_path);
for (auto & p: paths) {
PRINT_DEBUG("mod directory %s\n", p.c_str());
try {
PublishedFileId_t id = std::stoull(p);
settings_client->addMod(id, p, mod_path + PATH_SEPARATOR + p);
settings_server->addMod(id, p, mod_path + PATH_SEPARATOR + p);
} catch (...) {}
}
}
*settings_client_out = settings_client;
*settings_server_out = settings_server;
*local_storage_out = local_storage;
return appid;
}

27
dll/settings_parser.h Normal file
View File

@ -0,0 +1,27 @@
/* Copyright (C) 2019 Mr Goldberg
This file is part of the Goldberg Emulator
The Goldberg Emulator is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 3 of the License, or (at your option) any later version.
The Goldberg Emulator is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with the Goldberg Emulator; if not, see
<http://www.gnu.org/licenses/>. */
#include "settings.h"
#ifndef SETTINGS_PARSER_INCLUDE
#define SETTINGS_PARSER_INCLUDE
//returns appid
uint32 create_localstorage_settings(Settings **settings_client_out, Settings **settings_server_out, Local_Storage **local_storage_out);
#endif

View File

@ -16,8 +16,8 @@
<http://www.gnu.org/licenses/>. */
#include "steam_client.h"
#include "settings_parser.h"
#include <fstream>
static void background_thread(Steam_Client *client)
{
@ -39,303 +39,12 @@ static void background_thread(Steam_Client *client)
}
}
static void load_custom_broadcasts(std::string broadcasts_filepath, std::set<uint32> &custom_broadcasts)
{
std::ifstream broadcasts_file(broadcasts_filepath);
PRINT_DEBUG("Broadcasts file path: %s\n", broadcasts_filepath.c_str());
if (broadcasts_file.is_open()) {
std::string line;
while (std::getline(broadcasts_file, line)) {
std::set<uint32> ips = Networking::resolve_ip(line);
custom_broadcasts.insert(ips.begin(), ips.end());
}
}
}
Steam_Client::Steam_Client()
{
std::string program_path = Local_Storage::get_program_path(), save_path = Local_Storage::get_user_appdata_path();;
PRINT_DEBUG("Current Path %s save_path: %s\n", program_path.c_str(), save_path.c_str());
uint32 appid = create_localstorage_settings(&settings_client, &settings_server, &local_storage);
char array[10] = {};
array[0] = '0';
Local_Storage::get_file_data(Local_Storage::get_game_settings_path() + "steam_appid.txt", array, sizeof(array) - 1);
uint32 appid = 0;
try {
appid = std::stoi(array);
} catch (...) {}
if (!appid) {
memset(array, 0, sizeof(array));
array[0] = '0';
Local_Storage::get_file_data("steam_appid.txt", array, sizeof(array) - 1);
try {
appid = std::stoi(array);
} catch (...) {}
if (!appid) {
memset(array, 0, sizeof(array));
array[0] = '0';
Local_Storage::get_file_data(program_path + "steam_appid.txt", array, sizeof(array) - 1);
try {
appid = std::stoi(array);
} catch (...) {}
}
}
if (!appid) {
std::string str_appid = get_env_variable("SteamAppId");
std::string str_gameid = get_env_variable("SteamGameId");
PRINT_DEBUG("str_appid %s str_gameid: %s\n", str_appid.c_str(), str_gameid.c_str());
uint32 appid_env = 0;
uint32 gameid_env = 0;
if (str_appid.size() > 0) {
try {
appid_env = std::stoul(str_appid);
} catch (...) {
appid_env = 0;
}
}
if (str_gameid.size() > 0) {
try {
gameid_env = std::stoul(str_gameid);
} catch (...) {
gameid_env = 0;
}
}
PRINT_DEBUG("appid_env %u gameid_env: %u\n", appid_env, gameid_env);
if (appid_env) {
appid = appid_env;
}
if (gameid_env) {
appid = gameid_env;
}
}
{
char array[33] = {};
if (Local_Storage::get_file_data(program_path + "local_save.txt", array, sizeof(array) - 1) != -1) {
save_path = program_path + Settings::sanitize(array);
}
}
PRINT_DEBUG("Set save_path: %s\n", save_path.c_str());
local_storage = new Local_Storage(save_path);
local_storage->setAppId(appid);
// Listen port
char array_port[10] = {};
array_port[0] = '0';
local_storage->get_data_settings("listen_port.txt", array_port, sizeof(array_port) - 1);
uint16 port = std::stoi(array_port);
if (port == 0) {
port = DEFAULT_PORT;
snprintf(array_port, sizeof(array_port), "%hu", port);
local_storage->store_data_settings("listen_port.txt", array_port, strlen(array_port));
}
// Custom broadcasts
std::set<uint32> custom_broadcasts;
load_custom_broadcasts(local_storage->get_global_settings_path() + "custom_broadcasts.txt", custom_broadcasts);
load_custom_broadcasts(Local_Storage::get_game_settings_path() + "custom_broadcasts.txt", custom_broadcasts);
// Acount name
char name[32] = {};
if (local_storage->get_data_settings("account_name.txt", name, sizeof(name) - 1) <= 0) {
strcpy(name, DEFAULT_NAME);
local_storage->store_data_settings("account_name.txt", name, strlen(name));
}
// Language
char language[32] = {};
if (local_storage->get_data_settings("language.txt", language, sizeof(language) - 1) <= 0) {
strcpy(language, DEFAULT_LANGUAGE);
local_storage->store_data_settings("language.txt", language, strlen(language));
}
// Steam ID
char array_steam_id[32] = {};
CSteamID user_id;
uint64 steam_id = 0;
bool generate_new = false;
//try to load steam id from game specific settings folder first
if (local_storage->get_data(Local_Storage::settings_storage_folder, "user_steam_id.txt", array_steam_id, sizeof(array_steam_id) - 1) > 0) {
user_id = CSteamID((uint64)std::atoll(array_steam_id));
if (!user_id.IsValid()) {
generate_new = true;
}
} else {
generate_new = true;
}
if (generate_new) {
generate_new = false;
if (local_storage->get_data_settings("user_steam_id.txt", array_steam_id, sizeof(array_steam_id) - 1) > 0) {
user_id = CSteamID((uint64)std::atoll(array_steam_id));
if (!user_id.IsValid()) {
generate_new = true;
}
} else {
generate_new = true;
}
}
if (generate_new) {
user_id = generate_steam_id_user();
uint64 steam_id = user_id.ConvertToUint64();
char temp_text[32] = {};
snprintf(temp_text, sizeof(temp_text), "%llu", steam_id);
local_storage->store_data_settings("user_steam_id.txt", temp_text, strlen(temp_text));
}
bool steam_offline_mode = false;
{
std::string steam_settings_path = Local_Storage::get_game_settings_path();
std::vector<std::string> paths = Local_Storage::get_filenames_path(steam_settings_path);
for (auto & p: paths) {
PRINT_DEBUG("steam settings path %s\n", p.c_str());
if (p == "offline.txt") {
steam_offline_mode = true;
}
}
}
settings_client = new Settings(user_id, CGameID(appid), name, language, steam_offline_mode);
settings_server = new Settings(generate_steam_id_server(), CGameID(appid), name, language, steam_offline_mode);
{
std::string dlc_config_path = Local_Storage::get_game_settings_path() + "DLC.txt";
std::ifstream input( dlc_config_path );
if (input.is_open()) {
settings_client->unlockAllDLC(false);
settings_server->unlockAllDLC(false);
PRINT_DEBUG("Locking all DLC\n");
for( std::string line; std::getline( input, line ); ) {
if (!line.empty() && line.front() == '#') {
continue;
}
if (!line.empty() && line.back() == '\n') {
line.pop_back();
}
if (!line.empty() && line.back() == '\r') {
line.pop_back();
}
std::size_t deliminator = line.find("=");
if (deliminator != 0 && deliminator != std::string::npos && deliminator != line.size()) {
AppId_t appid = stol(line.substr(0, deliminator));
std::string name = line.substr(deliminator + 1);
bool available = true;
if (appid) {
PRINT_DEBUG("Adding DLC: %u|%s| %u\n", appid, name.c_str(), available);
settings_client->addDLC(appid, name, available);
settings_server->addDLC(appid, name, available);
}
}
}
} else {
//unlock all DLC
PRINT_DEBUG("Unlocking all DLC\n");
settings_client->unlockAllDLC(true);
settings_server->unlockAllDLC(true);
}
}
{
std::string dlc_config_path = Local_Storage::get_game_settings_path() + "app_paths.txt";
std::ifstream input( dlc_config_path );
if (input.is_open()) {
for( std::string line; getline( input, line ); ) {
if (!line.empty() && line[line.length()-1] == '\n') {
line.erase(line.length()-1);
}
if (!line.empty() && line[line.length()-1] == '\r') {
line.erase(line.length()-1);
}
std::size_t deliminator = line.find("=");
if (deliminator != 0 && deliminator != std::string::npos && deliminator != line.size()) {
AppId_t appid = stol(line.substr(0, deliminator));
std::string rel_path = line.substr(deliminator + 1);
std::string path = canonical_path(program_path + rel_path);
if (appid) {
if (path.size()) {
PRINT_DEBUG("Adding app path: %u|%s|\n", appid, path.c_str());
settings_client->setAppInstallPath(appid, path);
settings_server->setAppInstallPath(appid, path);
} else {
PRINT_DEBUG("Error adding app path for: %u does this path exist? |%s|\n", appid, rel_path.c_str());
}
}
}
}
}
}
{
std::string dlc_config_path = Local_Storage::get_game_settings_path() + "leaderboards.txt";
std::ifstream input( dlc_config_path );
if (input.is_open()) {
settings_client->setCreateUnknownLeaderboards(false);
settings_server->setCreateUnknownLeaderboards(false);
for( std::string line; getline( input, line ); ) {
if (!line.empty() && line[line.length()-1] == '\n') {
line.erase(line.length()-1);
}
if (!line.empty() && line[line.length()-1] == '\r') {
line.erase(line.length()-1);
}
std::string leaderboard;
unsigned int sort_method = 0;
unsigned int display_type = 0;
std::size_t deliminator = line.find("=");
if (deliminator != 0 && deliminator != std::string::npos && deliminator != line.size()) {
leaderboard = line.substr(0, deliminator);
std::size_t deliminator2 = line.find("=", deliminator + 1);
if (deliminator2 != std::string::npos && deliminator2 != line.size()) {
sort_method = stol(line.substr(deliminator + 1, deliminator2));
display_type = stol(line.substr(deliminator2 + 1));
}
}
if (leaderboard.size() && sort_method <= k_ELeaderboardSortMethodDescending && display_type <= k_ELeaderboardDisplayTypeTimeMilliSeconds) {
PRINT_DEBUG("Adding leaderboard: %s|%u|%u\n", leaderboard.c_str(), sort_method, display_type);
settings_client->setLeaderboard(leaderboard, (ELeaderboardSortMethod)sort_method, (ELeaderboardDisplayType)display_type);
settings_server->setLeaderboard(leaderboard, (ELeaderboardSortMethod)sort_method, (ELeaderboardDisplayType)display_type);
} else {
PRINT_DEBUG("Error adding leaderboard for: %s, are sort method %u or display type %u valid?\n", leaderboard.c_str(), sort_method, display_type);
}
}
}
}
{
std::string mod_path = Local_Storage::get_game_settings_path() + "mods";
std::vector<std::string> paths = Local_Storage::get_filenames_path(mod_path);
for (auto & p: paths) {
PRINT_DEBUG("mod directory %s\n", p.c_str());
try {
PublishedFileId_t id = std::stoull(p);
settings_client->addMod(id, p, mod_path + PATH_SEPARATOR + p);
settings_server->addMod(id, p, mod_path + PATH_SEPARATOR + p);
} catch (...) {}
}
}
network = new Networking(settings_server->get_local_steam_id(), appid, port, &custom_broadcasts);
network = new Networking(settings_server->get_local_steam_id(), appid, settings_server->get_port(), &(settings_server->custom_broadcasts));
callback_results_client = new SteamCallResults();
callback_results_server = new SteamCallResults();
@ -343,7 +52,7 @@ Steam_Client::Steam_Client()
callbacks_server = new SteamCallBacks(callback_results_server);
run_every_runcb = new RunEveryRunCB();
PRINT_DEBUG("steam client init: id: %llu server id: %llu appid: %u port: %u \n", user_id.ConvertToUint64(), settings_server->get_local_steam_id().ConvertToUint64(), appid, port);
PRINT_DEBUG("steam client init: id: %llu server id: %llu appid: %u port: %u \n", settings_client->get_local_steam_id().ConvertToUint64(), settings_server->get_local_steam_id().ConvertToUint64(), appid, settings_server->get_port());
steam_user = new Steam_User(settings_client, local_storage, network, callback_results_client, callbacks_client);
steam_friends = new Steam_Friends(settings_client, network, callback_results_client, callbacks_client, run_every_runcb);

View File

@ -361,7 +361,7 @@ void AdvertiseGame( CSteamID steamIDGameServer, uint32 unIPServer, uint16 usPort
STEAM_CALL_RESULT( EncryptedAppTicketResponse_t )
SteamAPICall_t RequestEncryptedAppTicket( void *pDataToInclude, int cbDataToInclude )
{
PRINT_DEBUG("Steam_User::RequestEncryptedAppTicket\n");
PRINT_DEBUG("Steam_User::RequestEncryptedAppTicket %i\n", cbDataToInclude);
std::lock_guard<std::recursive_mutex> lock(global_mutex);
EncryptedAppTicketResponse_t data;
data.m_eResult = k_EResultOK;

View File

@ -131,11 +131,21 @@ bool GetStat( const char *pchName, int32 *pData )
PRINT_DEBUG("GetStat int32 %s\n", pchName);
if (!pchName || !pData) return false;
std::lock_guard<std::recursive_mutex> lock(global_mutex);
auto stats_config = settings->getStats();
auto stats_data = stats_config.find(pchName);
if (stats_data != stats_config.end()) {
if (stats_data->second.type != Stat_Type::STAT_TYPE_INT) return false;
}
int read_data = local_storage->get_data(Local_Storage::stats_storage_folder, pchName, (char* )pData, sizeof(*pData));
if (read_data == sizeof(int32))
return true;
if (stats_data != stats_config.end()) {
*pData = stats_data->second.default_value_int;
return true;
}
return false;
}
@ -144,11 +154,21 @@ bool GetStat( const char *pchName, float *pData )
PRINT_DEBUG("GetStat float %s\n", pchName);
if (!pchName || !pData) return false;
std::lock_guard<std::recursive_mutex> lock(global_mutex);
auto stats_config = settings->getStats();
auto stats_data = stats_config.find(pchName);
if (stats_data != stats_config.end()) {
if (stats_data->second.type == Stat_Type::STAT_TYPE_INT) return false;
}
int read_data = local_storage->get_data(Local_Storage::stats_storage_folder, pchName, (char* )pData, sizeof(*pData));
if (read_data == sizeof(int32))
if (read_data == sizeof(float))
return true;
if (stats_data != stats_config.end()) {
*pData = stats_data->second.default_value_float;
return true;
}
return false;
}

View File

@ -0,0 +1,7 @@
lifetime_experience=int=0
experience=int=0
stat_example_name1=float=3.5
stat_example_name2=int=1337
stat_example_name3=int=0
stat_example_name4=float=0
stat_example_name5=avgrate=0