Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions dll/dll/settings.h
Original file line number Diff line number Diff line change
Expand Up @@ -219,6 +219,7 @@ class Settings {
std::set<AppId_t> installed_app_ids{};

std::map<AppId_t, std::string> app_paths{};
std::map<AppId_t, std::string> purchased_keys{};
std::vector<struct Mod_entry> mods{};
std::map<std::string, Leaderboard_config> leaderboards{};
std::map<std::string, Stat_config> stats{};
Expand Down Expand Up @@ -429,6 +430,10 @@ class Settings {
void setAppInstallPath(AppId_t appID, const std::string &path);
bool getAppInstallPath(AppId_t appID, std::string &path);

//Purchased keys
void setPurchasedKey(AppId_t appID, const std::string &key);
bool getPurchasedKey(AppId_t appID, std::string &key) const;

//mod stuff
void addMod(PublishedFileId_t id, const std::string &title, const std::string &path);
void addModDetails(PublishedFileId_t id, const Mod_entry &details);
Expand Down
17 changes: 17 additions & 0 deletions dll/settings.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -361,6 +361,23 @@ bool Settings::getAppInstallPath(AppId_t appID, std::string &path)
return false;
}

void Settings::setPurchasedKey(AppId_t appID, const std::string &key)
{
purchased_keys[appID] = key;
}

bool Settings::getPurchasedKey(AppId_t appID, std::string &key) const
{
auto it = purchased_keys.find(appID);
if (purchased_keys.end() != it)
{
key = it->second;
return true;
}

return false;
}

void Settings::setLeaderboard(const std::string &leaderboard, enum ELeaderboardSortMethod sort_method, enum ELeaderboardDisplayType display_type)
{
Leaderboard_config leader{};
Expand Down
36 changes: 36 additions & 0 deletions dll/settings_parser.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -989,6 +989,41 @@ static void parse_subscribed_groups(class Settings *settings_client, class Setti

}

// purchased_keys.txt
static void parse_purchased_keys(class Settings *settings_client, class Settings *settings_server)
{
std::string purchased_keys_path = Local_Storage::get_game_settings_path() + "purchased_keys.txt";
std::ifstream input( std::filesystem::u8path(purchased_keys_path) );
if (input.is_open()) {
PRINT_DEBUG("Reading purchased keys");
common_helpers::consume_bom(input);
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();
}

// skip empty lines and comments
if (line.empty() || line[0] == '#') continue;

try {
size_t delimiter = line.find('=');
if (delimiter != std::string::npos) {
AppId_t app_id = std::stoul(line.substr(0, delimiter));
std::string key = line.substr(delimiter + 1);
settings_client->setPurchasedKey(app_id, key);
settings_server->setPurchasedKey(app_id, key);
PRINT_DEBUG("Added purchased key for app ID %u", app_id);
}
} catch (...) {}
}
}

}

// installed_app_ids.txt
static void parse_installed_app_Ids(class Settings *settings_client, class Settings *settings_server)
{
Expand Down Expand Up @@ -1896,6 +1931,7 @@ uint32 create_localstorage_settings(Settings **settings_client_out, Settings **s
parse_dlc(settings_client, settings_server);
parse_installed_app_Ids(settings_client, settings_server);
parse_app_paths(settings_client, settings_server, program_path);
parse_purchased_keys(settings_client, settings_server);

parse_leaderboards(settings_client, settings_server);
parse_stats(settings_client, settings_server, local_storage);
Expand Down
48 changes: 32 additions & 16 deletions dll/steam_apps.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -23,9 +23,6 @@ void Steam_Apps::FillProofOfPurchaseKey( AppProofOfPurchaseKeyResponse_t& data,
{
data.m_nAppID = nAppID;
if (ok_result) {
// TODO maybe read this from a config file "purchased_keys.txt":
// 480=AAAAA-BBBBB-CCCCC-DDDDD
// 218620=XYZFJ-13370-98765
size_t min_len = key.size() < k_cubAppProofOfPurchaseKeyMax
? key.size()
: k_cubAppProofOfPurchaseKeyMax - 1; // -1 because we need space for null
Expand All @@ -45,9 +42,6 @@ void Steam_Apps::FillProofOfPurchaseKey( AppProofOfPurchaseKeyResponse007_t& dat
{
data.m_nAppID = nAppID;
if (ok_result) {
// TODO maybe read this from a config file "purchased_keys.txt":
// 480=AAAAA-BBBBB-CCCCC-DDDDD
// 218620=XYZFJ-13370-98765
size_t min_len = key.size() < k_cubAppProofOfPurchaseKeyMax
? key.size()
: k_cubAppProofOfPurchaseKeyMax - 1; // -1 because we need space for null
Expand Down Expand Up @@ -272,7 +266,7 @@ void Steam_Apps::UninstallDLC( AppId_t nAppID )
// the key is available (which may be immediately).
void Steam_Apps::RequestAppProofOfPurchaseKey( AppId_t nAppID )
{
PRINT_DEBUG_TODO();
PRINT_DEBUG("%u", nAppID);
std::lock_guard<std::recursive_mutex> lock(global_mutex);

AppProofOfPurchaseKeyResponse_t data{};
Expand All @@ -282,9 +276,14 @@ void Steam_Apps::RequestAppProofOfPurchaseKey( AppId_t nAppID )
if (nAppID == 0 || nAppID == UINT32_MAX) {
FillProofOfPurchaseKey(data, nAppID, false);
} else if (nAppID == settings->get_local_game_id().AppID() || settings->hasDLC(nAppID)) {
FillProofOfPurchaseKey(data, nAppID, true);
std::string key{};
settings->getPurchasedKey(nAppID, key);
if (!key.empty()) {
FillProofOfPurchaseKey(data, nAppID, true, key);
} else {
FillProofOfPurchaseKey(data, nAppID, true);
}
} else {
//TODO what to do here?
FillProofOfPurchaseKey(data, nAppID, false);
}

Expand All @@ -293,7 +292,7 @@ void Steam_Apps::RequestAppProofOfPurchaseKey( AppId_t nAppID )

void Steam_Apps::RequestAppProofOfPurchaseKey_OLD( AppId_t nAppID )
{
PRINT_DEBUG_TODO();
PRINT_DEBUG("%u", nAppID);
std::lock_guard<std::recursive_mutex> lock(global_mutex);

AppProofOfPurchaseKeyResponse007_t data{};
Expand All @@ -303,9 +302,14 @@ void Steam_Apps::RequestAppProofOfPurchaseKey_OLD( AppId_t nAppID )
if (nAppID == 0 || nAppID == UINT32_MAX) {
FillProofOfPurchaseKey(data, nAppID, false);
} else if (nAppID == settings->get_local_game_id().AppID() || settings->hasDLC(nAppID)) {
FillProofOfPurchaseKey(data, nAppID, true);
std::string key{};
settings->getPurchasedKey(nAppID, key);
if (!key.empty()) {
FillProofOfPurchaseKey(data, nAppID, true, key);
} else {
FillProofOfPurchaseKey(data, nAppID, true);
}
} else {
//TODO what to do here?
FillProofOfPurchaseKey(data, nAppID, false);
}

Expand Down Expand Up @@ -457,24 +461,36 @@ int Steam_Apps::GetAppBuildId()
// member is k_uAppIdInvalid (zero).
void Steam_Apps::RequestAllProofOfPurchaseKeys()
{
PRINT_DEBUG_TODO();
PRINT_DEBUG_ENTRY();
std::lock_guard<std::recursive_mutex> lock(global_mutex);
// current app
{
AppProofOfPurchaseKeyResponse_t data{};
FillProofOfPurchaseKey(data, settings->get_local_game_id().AppID(), true);
std::string key{};
AppId_t app_id = settings->get_local_game_id().AppID();
settings->getPurchasedKey(app_id, key);
if (!key.empty()) {
FillProofOfPurchaseKey(data, app_id, true, key);
} else {
FillProofOfPurchaseKey(data, app_id, true);
}
callbacks->addCBResult(data.k_iCallback, &data, sizeof(data));
}

// DLCs
const auto count = settings->DLCCount();
for (unsigned i = 0; i < settings->DLCCount(); i++) {
AppId_t app_id{};
bool available{};
std::string name{};
if (settings->getDLC(i, app_id, available, name)) {
AppProofOfPurchaseKeyResponse_t data{};
FillProofOfPurchaseKey(data, app_id, true);
std::string key{};
settings->getPurchasedKey(app_id, key);
if (!key.empty()) {
FillProofOfPurchaseKey(data, app_id, true, key);
} else {
FillProofOfPurchaseKey(data, app_id, true);
}
callbacks->addCBResult(data.k_iCallback, &data, sizeof(data));
}
}
Expand Down
10 changes: 10 additions & 0 deletions post_build/README.release.md
Original file line number Diff line number Diff line change
Expand Up @@ -98,6 +98,16 @@ See `steam_settings.EXAMPLE\subscribed_groups_clans.EXAMPLE.txt` for an example.

---

## Purchased Keys:
Some games request CD keys or proof-of-purchase keys for installed apps and DLCs.
You can provide these keys to the game with a `steam_settings\purchased_keys.txt` file.

The format is `appid=KEY` with one entry per line. Comments start with `#`.

See `steam_settings.EXAMPLE\purchased_keys.EXAMPLE.txt` for an example.

---

## App paths:
Some rare games might need to be provided one or more paths to app ids.
For example the path to where a dlc is installed.
Expand Down
12 changes: 12 additions & 0 deletions post_build/steam_settings.EXAMPLE/purchased_keys.EXAMPLE.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
# Rename this to: purchased_keys.txt
# This file allows you to specify CD keys or proof-of-purchase keys for games and DLCs
# These keys will be returned when the game calls RequestAppProofOfPurchaseKey() or RequestAllProofOfPurchaseKeys()
#
# Format: appid=KEY
# Each line should contain one app ID and its corresponding key, separated by an equals sign
# Lines starting with # are treated as comments
# Empty lines are ignored
#
# Examples:
# 480=AAAAA-BBBBB-CCCCC-DDDDD
# 218620=XYZFJ-13370-98765