mirror of
https://github.com/shadps4-emu/shadPS4.git
synced 2025-04-22 04:24:44 +00:00
implement turtles review
This commit is contained in:
parent
c0c965cc7e
commit
677d959b1e
4 changed files with 287 additions and 352 deletions
|
@ -224,11 +224,11 @@ int PS4_SYSV_ABI sceNpTrophyGetGameIcon(OrbisNpTrophyContext context, OrbisNpTro
|
|||
}
|
||||
|
||||
struct GameTrophyInfo {
|
||||
uint32_t numGroups;
|
||||
uint32_t numTrophies;
|
||||
uint32_t numTrophiesByRarity[5];
|
||||
uint32_t unlockedTrophies;
|
||||
uint32_t unlockedTrophiesByRarity[5];
|
||||
uint32_t num_groups;
|
||||
uint32_t num_trophies;
|
||||
uint32_t num_trophies_by_rarity[5];
|
||||
uint32_t unlocked_trophies;
|
||||
uint32_t unlocked_trophies_by_rarity[5];
|
||||
};
|
||||
|
||||
int PS4_SYSV_ABI sceNpTrophyGetGameInfo(OrbisNpTrophyContext context, OrbisNpTrophyHandle handle,
|
||||
|
@ -248,68 +248,66 @@ int PS4_SYSV_ABI sceNpTrophyGetGameInfo(OrbisNpTrophyContext context, OrbisNpTro
|
|||
if (details->size != 0x4A0 || data->size != 0x20)
|
||||
return ORBIS_NP_TROPHY_ERROR_INVALID_ARGUMENT;
|
||||
|
||||
const auto trophyDir =
|
||||
const auto trophy_dir =
|
||||
Common::FS::GetUserPath(Common::FS::PathType::MetaDataDir) / game_serial / "TrophyFiles";
|
||||
|
||||
pugi::xml_document doc;
|
||||
pugi::xml_parse_result result =
|
||||
doc.load_file((trophyDir.string() + "/trophy00/Xml/TROP.XML").c_str());
|
||||
doc.load_file((trophy_dir / "trophy00" / "Xml" / "TROP.XML").c_str());
|
||||
|
||||
if (result) {
|
||||
ASSERT_MSG(result, "Couldnt parse trophy XML : {}", result.description());
|
||||
|
||||
GameTrophyInfo gameInfo;
|
||||
memset(&gameInfo, 0, sizeof(GameTrophyInfo));
|
||||
GameTrophyInfo game_info{};
|
||||
|
||||
auto trophyconf = doc.child("trophyconf");
|
||||
for (pugi::xml_node_iterator it = trophyconf.children().begin();
|
||||
it != trophyconf.children().end(); ++it) {
|
||||
auto trophyconf = doc.child("trophyconf");
|
||||
for (const pugi::xml_node& node : trophyconf.children()) {
|
||||
std::string_view node_name = node.name();
|
||||
|
||||
if (std::string(it->name()) == "title-name") {
|
||||
strncpy(details->title, it->text().as_string(),
|
||||
ORBIS_NP_TROPHY_GAME_TITLE_MAX_SIZE);
|
||||
}
|
||||
|
||||
if (std::string(it->name()) == "title-detail") {
|
||||
strncpy(details->description, it->text().as_string(),
|
||||
ORBIS_NP_TROPHY_GAME_DESCR_MAX_SIZE);
|
||||
}
|
||||
|
||||
if (std::string(it->name()) == "group")
|
||||
gameInfo.numGroups++;
|
||||
|
||||
if (std::string(it->name()) == "trophy") {
|
||||
std::string currentTrophyUnlockState = it->attribute("unlockstate").value();
|
||||
std::string currentTrophyGrade = it->attribute("ttype").value();
|
||||
|
||||
gameInfo.numTrophies++;
|
||||
if (!currentTrophyGrade.empty()) {
|
||||
int trophyGrade = GetTrophyGradeFromChar(currentTrophyGrade.at(0));
|
||||
gameInfo.numTrophiesByRarity[trophyGrade]++;
|
||||
if (currentTrophyUnlockState == "unlocked") {
|
||||
gameInfo.unlockedTrophies++;
|
||||
gameInfo.unlockedTrophiesByRarity[trophyGrade]++;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (node_name == "title-name") {
|
||||
strncpy(details->title, node.text().as_string(), ORBIS_NP_TROPHY_GAME_TITLE_MAX_SIZE);
|
||||
}
|
||||
|
||||
details->numGroups = gameInfo.numGroups;
|
||||
details->numTrophies = gameInfo.numTrophies;
|
||||
details->numPlatinum = gameInfo.numTrophiesByRarity[ORBIS_NP_TROPHY_GRADE_PLATINUM];
|
||||
details->numGold = gameInfo.numTrophiesByRarity[ORBIS_NP_TROPHY_GRADE_GOLD];
|
||||
details->numSilver = gameInfo.numTrophiesByRarity[ORBIS_NP_TROPHY_GRADE_SILVER];
|
||||
details->numBronze = gameInfo.numTrophiesByRarity[ORBIS_NP_TROPHY_GRADE_BRONZE];
|
||||
data->unlockedTrophies = gameInfo.unlockedTrophies;
|
||||
data->unlockedPlatinum = gameInfo.unlockedTrophiesByRarity[ORBIS_NP_TROPHY_GRADE_PLATINUM];
|
||||
data->unlockedGold = gameInfo.unlockedTrophiesByRarity[ORBIS_NP_TROPHY_GRADE_GOLD];
|
||||
data->unlockedSilver = gameInfo.unlockedTrophiesByRarity[ORBIS_NP_TROPHY_GRADE_SILVER];
|
||||
data->unlockedBronze = gameInfo.unlockedTrophiesByRarity[ORBIS_NP_TROPHY_GRADE_BRONZE];
|
||||
if (node_name == "title-detail") {
|
||||
strncpy(details->description, node.text().as_string(),
|
||||
ORBIS_NP_TROPHY_GAME_DESCR_MAX_SIZE);
|
||||
}
|
||||
|
||||
// maybe this should be 1 instead of 100?
|
||||
data->progressPercentage = 100;
|
||||
if (node_name == "group")
|
||||
game_info.num_groups++;
|
||||
|
||||
} else
|
||||
LOG_INFO(Lib_NpTrophy, "couldnt parse xml : {}", result.description());
|
||||
if (node_name == "trophy") {
|
||||
bool current_trophy_unlockstate = node.attribute("unlockstate").as_bool();
|
||||
std::string_view current_trophy_grade = node.attribute("ttype").value();
|
||||
|
||||
if (current_trophy_grade.empty()) {
|
||||
continue;
|
||||
}
|
||||
|
||||
game_info.num_trophies++;
|
||||
int trophy_grade = GetTrophyGradeFromChar(current_trophy_grade.at(0));
|
||||
game_info.num_trophies_by_rarity[trophy_grade]++;
|
||||
|
||||
if (current_trophy_unlockstate) {
|
||||
game_info.unlocked_trophies++;
|
||||
game_info.unlocked_trophies_by_rarity[trophy_grade]++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
details->num_groups = game_info.num_groups;
|
||||
details->num_trophies = game_info.num_trophies;
|
||||
details->num_platinum = game_info.num_trophies_by_rarity[ORBIS_NP_TROPHY_GRADE_PLATINUM];
|
||||
details->num_gold = game_info.num_trophies_by_rarity[ORBIS_NP_TROPHY_GRADE_GOLD];
|
||||
details->num_silver = game_info.num_trophies_by_rarity[ORBIS_NP_TROPHY_GRADE_SILVER];
|
||||
details->num_bronze = game_info.num_trophies_by_rarity[ORBIS_NP_TROPHY_GRADE_BRONZE];
|
||||
data->unlocked_trophies = game_info.unlocked_trophies;
|
||||
data->unlocked_platinum = game_info.unlocked_trophies_by_rarity[ORBIS_NP_TROPHY_GRADE_PLATINUM];
|
||||
data->unlocked_gold = game_info.unlocked_trophies_by_rarity[ORBIS_NP_TROPHY_GRADE_GOLD];
|
||||
data->unlocked_silver = game_info.unlocked_trophies_by_rarity[ORBIS_NP_TROPHY_GRADE_SILVER];
|
||||
data->unlocked_bronze = game_info.unlocked_trophies_by_rarity[ORBIS_NP_TROPHY_GRADE_BRONZE];
|
||||
|
||||
// maybe this should be 1 instead of 100?
|
||||
data->progress_percentage = 100;
|
||||
|
||||
return ORBIS_OK;
|
||||
}
|
||||
|
@ -321,10 +319,10 @@ int PS4_SYSV_ABI sceNpTrophyGetGroupIcon(OrbisNpTrophyContext context, OrbisNpTr
|
|||
}
|
||||
|
||||
struct GroupTrophyInfo {
|
||||
uint32_t numTrophies;
|
||||
uint32_t numTrophiesByRarity[5];
|
||||
uint32_t unlockedTrophies;
|
||||
uint32_t unlockedTrophiesByRarity[5];
|
||||
uint32_t num_trophies;
|
||||
uint32_t num_trophies_by_rarity[5];
|
||||
uint32_t unlocked_trophies;
|
||||
uint32_t unlocked_trophies_by_rarity[5];
|
||||
};
|
||||
|
||||
int PS4_SYSV_ABI sceNpTrophyGetGroupInfo(OrbisNpTrophyContext context, OrbisNpTrophyHandle handle,
|
||||
|
@ -345,78 +343,75 @@ int PS4_SYSV_ABI sceNpTrophyGetGroupInfo(OrbisNpTrophyContext context, OrbisNpTr
|
|||
if (details->size != 0x4A0 || data->size != 0x28)
|
||||
return ORBIS_NP_TROPHY_ERROR_INVALID_ARGUMENT;
|
||||
|
||||
const auto trophyDir =
|
||||
const auto trophy_dir =
|
||||
Common::FS::GetUserPath(Common::FS::PathType::MetaDataDir) / game_serial / "TrophyFiles";
|
||||
|
||||
pugi::xml_document doc;
|
||||
pugi::xml_parse_result result =
|
||||
doc.load_file((trophyDir.string() + "/trophy00/Xml/TROP.XML").c_str());
|
||||
doc.load_file((trophy_dir / "trophy00" / "Xml" / "TROP.XML").c_str());
|
||||
|
||||
if (result) {
|
||||
ASSERT_MSG(result, "Couldnt parse trophy XML : {}", result.description());
|
||||
|
||||
GroupTrophyInfo groupInfo;
|
||||
memset(&groupInfo, 0, sizeof(GroupTrophyInfo));
|
||||
GroupTrophyInfo group_info{};
|
||||
|
||||
auto trophyconf = doc.child("trophyconf");
|
||||
for (pugi::xml_node_iterator it = trophyconf.children().begin();
|
||||
it != trophyconf.children().end(); ++it) {
|
||||
auto trophyconf = doc.child("trophyconf");
|
||||
for (const pugi::xml_node& node : trophyconf.children()) {
|
||||
std::string_view node_name = node.name();
|
||||
|
||||
if (std::string(it->name()) == "group") {
|
||||
std::string currentGroupId = it->attribute("id").value();
|
||||
if (!currentGroupId.empty()) {
|
||||
if (std::stoi(currentGroupId) == groupId) {
|
||||
std::string currentGroupName = it->child("name").text().as_string();
|
||||
std::string currentGroupDescription =
|
||||
it->child("detail").text().as_string();
|
||||
if (node_name == "group") {
|
||||
int current_group_id = node.attribute("id").as_int(ORBIS_NP_TROPHY_INVALID_GROUP_ID);
|
||||
if (current_group_id != ORBIS_NP_TROPHY_INVALID_GROUP_ID) {
|
||||
if (current_group_id == groupId) {
|
||||
std::string_view current_group_name = node.child("name").text().as_string();
|
||||
std::string_view current_group_description =
|
||||
node.child("detail").text().as_string();
|
||||
|
||||
strncpy(details->title, currentGroupName.c_str(),
|
||||
ORBIS_NP_TROPHY_GROUP_TITLE_MAX_SIZE);
|
||||
strncpy(details->description, currentGroupDescription.c_str(),
|
||||
ORBIS_NP_TROPHY_GAME_DESCR_MAX_SIZE);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
details->groupId = groupId;
|
||||
data->groupId = groupId;
|
||||
|
||||
if (std::string(it->name()) == "trophy") {
|
||||
std::string currentTrophyUnlockState = it->attribute("unlockstate").value();
|
||||
std::string currentTrophyGrade = it->attribute("ttype").value();
|
||||
std::string currentTrophyGroupID = it->attribute("gid").value();
|
||||
|
||||
if (!currentTrophyGroupID.empty()) {
|
||||
if (std::stoi(currentTrophyGroupID) == groupId) {
|
||||
groupInfo.numTrophies++;
|
||||
if (!currentTrophyGrade.empty()) {
|
||||
int trophyGrade = GetTrophyGradeFromChar(currentTrophyGrade.at(0));
|
||||
groupInfo.numTrophiesByRarity[trophyGrade]++;
|
||||
if (currentTrophyUnlockState == "unlocked") {
|
||||
groupInfo.unlockedTrophies++;
|
||||
groupInfo.unlockedTrophiesByRarity[trophyGrade]++;
|
||||
}
|
||||
}
|
||||
}
|
||||
strncpy(details->title, current_group_name.data(),
|
||||
ORBIS_NP_TROPHY_GROUP_TITLE_MAX_SIZE);
|
||||
strncpy(details->description, current_group_description.data(),
|
||||
ORBIS_NP_TROPHY_GAME_DESCR_MAX_SIZE);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
details->numTrophies = groupInfo.numTrophies;
|
||||
details->numPlatinum = groupInfo.numTrophiesByRarity[ORBIS_NP_TROPHY_GRADE_PLATINUM];
|
||||
details->numGold = groupInfo.numTrophiesByRarity[ORBIS_NP_TROPHY_GRADE_GOLD];
|
||||
details->numSilver = groupInfo.numTrophiesByRarity[ORBIS_NP_TROPHY_GRADE_SILVER];
|
||||
details->numBronze = groupInfo.numTrophiesByRarity[ORBIS_NP_TROPHY_GRADE_BRONZE];
|
||||
data->unlockedTrophies = groupInfo.unlockedTrophies;
|
||||
data->unlockedPlatinum = groupInfo.unlockedTrophiesByRarity[ORBIS_NP_TROPHY_GRADE_PLATINUM];
|
||||
data->unlockedGold = groupInfo.unlockedTrophiesByRarity[ORBIS_NP_TROPHY_GRADE_GOLD];
|
||||
data->unlockedSilver = groupInfo.unlockedTrophiesByRarity[ORBIS_NP_TROPHY_GRADE_SILVER];
|
||||
data->unlockedBronze = groupInfo.unlockedTrophiesByRarity[ORBIS_NP_TROPHY_GRADE_BRONZE];
|
||||
details->group_id = groupId;
|
||||
data->group_id = groupId;
|
||||
|
||||
// maybe this should be 1 instead of 100?
|
||||
data->progressPercentage = 100;
|
||||
if (node_name == "trophy") {
|
||||
bool current_trophy_unlockstate = node.attribute("unlockstate").as_bool();
|
||||
std::string_view current_trophy_grade = node.attribute("ttype").value();
|
||||
int current_trophy_group_id = node.attribute("gid").as_int(-1);
|
||||
|
||||
} else
|
||||
LOG_INFO(Lib_NpTrophy, "couldnt parse xml : {}", result.description());
|
||||
if (current_trophy_grade.empty()) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (current_trophy_group_id == groupId) {
|
||||
group_info.num_trophies++;
|
||||
int trophyGrade = GetTrophyGradeFromChar(current_trophy_grade.at(0));
|
||||
group_info.num_trophies_by_rarity[trophyGrade]++;
|
||||
if (current_trophy_unlockstate) {
|
||||
group_info.unlocked_trophies++;
|
||||
group_info.unlocked_trophies_by_rarity[trophyGrade]++;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
details->num_trophies = group_info.num_trophies;
|
||||
details->num_platinum = group_info.num_trophies_by_rarity[ORBIS_NP_TROPHY_GRADE_PLATINUM];
|
||||
details->num_gold = group_info.num_trophies_by_rarity[ORBIS_NP_TROPHY_GRADE_GOLD];
|
||||
details->num_silver = group_info.num_trophies_by_rarity[ORBIS_NP_TROPHY_GRADE_SILVER];
|
||||
details->num_bronze = group_info.num_trophies_by_rarity[ORBIS_NP_TROPHY_GRADE_BRONZE];
|
||||
data->unlocked_trophies = group_info.unlocked_trophies;
|
||||
data->unlocked_platinum =
|
||||
group_info.unlocked_trophies_by_rarity[ORBIS_NP_TROPHY_GRADE_PLATINUM];
|
||||
data->unlocked_gold = group_info.unlocked_trophies_by_rarity[ORBIS_NP_TROPHY_GRADE_GOLD];
|
||||
data->unlocked_silver = group_info.unlocked_trophies_by_rarity[ORBIS_NP_TROPHY_GRADE_SILVER];
|
||||
data->unlocked_bronze = group_info.unlocked_trophies_by_rarity[ORBIS_NP_TROPHY_GRADE_BRONZE];
|
||||
|
||||
// maybe this should be 1 instead of 100?
|
||||
data->progress_percentage = 100;
|
||||
|
||||
return ORBIS_OK;
|
||||
}
|
||||
|
@ -447,87 +442,48 @@ int PS4_SYSV_ABI sceNpTrophyGetTrophyInfo(OrbisNpTrophyContext context, OrbisNpT
|
|||
if (details->size != 0x498 || data->size != 0x18)
|
||||
return ORBIS_NP_TROPHY_ERROR_INVALID_ARGUMENT;
|
||||
|
||||
const auto trophyDir =
|
||||
const auto trophy_dir =
|
||||
Common::FS::GetUserPath(Common::FS::PathType::MetaDataDir) / game_serial / "TrophyFiles";
|
||||
|
||||
pugi::xml_document doc;
|
||||
pugi::xml_parse_result result =
|
||||
doc.load_file((trophyDir.string() + "/trophy00/Xml/TROP.XML").c_str());
|
||||
doc.load_file((trophy_dir / "trophy00" / "Xml" / "TROP.XML").c_str());
|
||||
|
||||
if (result) {
|
||||
auto trophyconf = doc.child("trophyconf");
|
||||
for (pugi::xml_node_iterator it = trophyconf.children().begin();
|
||||
it != trophyconf.children().end(); ++it) {
|
||||
ASSERT_MSG(result, "Couldnt parse trophy XML : {}", result.description());
|
||||
|
||||
if (std::string(it->name()) == "trophy") {
|
||||
std::string currentTrophyId = it->attribute("id").value();
|
||||
if (std::stoi(currentTrophyId) == trophyId) {
|
||||
std::string currentTrophyUnlockState = it->attribute("unlockstate").value();
|
||||
std::string currentTrophyTimestamp = it->attribute("timestamp").value();
|
||||
std::string currentTrophyGrade = it->attribute("ttype").value();
|
||||
std::string currentTrophyGroupID = it->attribute("gid").value();
|
||||
std::string currentTrophyHidden = it->attribute("hidden").value();
|
||||
std::string currentTrophyName = it->child("name").text().as_string();
|
||||
std::string currentTrophyDescription = it->child("detail").text().as_string();
|
||||
auto trophyconf = doc.child("trophyconf");
|
||||
|
||||
if (currentTrophyUnlockState == "unlocked") {
|
||||
details->trophyId = trophyId;
|
||||
if (currentTrophyGrade.empty()) {
|
||||
details->trophyGrade = ORBIS_NP_TROPHY_GRADE_UNKNOWN;
|
||||
} else {
|
||||
details->trophyGrade = GetTrophyGradeFromChar(currentTrophyGrade.at(0));
|
||||
}
|
||||
if (currentTrophyGroupID.empty()) {
|
||||
details->groupId = ORBIS_NP_TROPHY_BASE_GAME_GROUP_ID;
|
||||
} else {
|
||||
details->groupId = std::stoi(currentTrophyGroupID);
|
||||
}
|
||||
if (currentTrophyHidden == "yes") {
|
||||
details->hidden = true;
|
||||
} else {
|
||||
details->hidden = false;
|
||||
}
|
||||
for (const pugi::xml_node& node : trophyconf.children()) {
|
||||
std::string_view node_name = node.name();
|
||||
|
||||
strncpy(details->name, currentTrophyName.c_str(),
|
||||
ORBIS_NP_TROPHY_NAME_MAX_SIZE);
|
||||
strncpy(details->description, currentTrophyDescription.c_str(),
|
||||
ORBIS_NP_TROPHY_DESCR_MAX_SIZE);
|
||||
if (node_name == "trophy") {
|
||||
int current_trophy_id = node.attribute("id").as_int(ORBIS_NP_TROPHY_INVALID_TROPHY_ID);
|
||||
if (current_trophy_id == trophyId) {
|
||||
bool current_trophy_unlockstate = node.attribute("unlockstate").as_bool();
|
||||
std::string_view current_trophy_grade = node.attribute("ttype").value();
|
||||
std::string_view current_trophy_name = node.child("name").text().as_string();
|
||||
std::string_view current_trophy_description =
|
||||
node.child("detail").text().as_string();
|
||||
|
||||
data->trophyId = trophyId;
|
||||
data->unlocked = true;
|
||||
data->timestamp.tick = std::stoull(currentTrophyTimestamp);
|
||||
} else {
|
||||
details->trophyId = trophyId;
|
||||
if (currentTrophyGrade.empty()) {
|
||||
details->trophyGrade = ORBIS_NP_TROPHY_GRADE_UNKNOWN;
|
||||
} else {
|
||||
details->trophyGrade = GetTrophyGradeFromChar(currentTrophyGrade.at(0));
|
||||
}
|
||||
if (currentTrophyGroupID.empty()) {
|
||||
details->groupId = ORBIS_NP_TROPHY_BASE_GAME_GROUP_ID;
|
||||
} else {
|
||||
details->groupId = std::stoi(currentTrophyGroupID);
|
||||
}
|
||||
if (currentTrophyHidden == "yes") {
|
||||
details->hidden = true;
|
||||
} else {
|
||||
details->hidden = false;
|
||||
}
|
||||
uint64_t current_trophy_timestamp = node.attribute("timestamp").as_ullong();
|
||||
int current_trophy_groupid = node.attribute("gid").as_int(-1);
|
||||
bool current_trophy_hidden = node.attribute("hidden").as_bool();
|
||||
|
||||
strncpy(details->name, currentTrophyName.c_str(),
|
||||
ORBIS_NP_TROPHY_NAME_MAX_SIZE);
|
||||
strncpy(details->description, currentTrophyDescription.c_str(),
|
||||
ORBIS_NP_TROPHY_DESCR_MAX_SIZE);
|
||||
details->trophy_id = trophyId;
|
||||
details->trophy_grade = GetTrophyGradeFromChar(current_trophy_grade.at(0));
|
||||
details->group_id = current_trophy_groupid;
|
||||
details->hidden = current_trophy_hidden;
|
||||
|
||||
data->trophyId = trophyId;
|
||||
data->unlocked = false;
|
||||
data->timestamp.tick = 0;
|
||||
}
|
||||
}
|
||||
strncpy(details->name, current_trophy_name.data(), ORBIS_NP_TROPHY_NAME_MAX_SIZE);
|
||||
strncpy(details->description, current_trophy_description.data(),
|
||||
ORBIS_NP_TROPHY_DESCR_MAX_SIZE);
|
||||
|
||||
data->trophy_id = trophyId;
|
||||
data->unlocked = current_trophy_unlockstate;
|
||||
data->timestamp.tick = current_trophy_timestamp;
|
||||
}
|
||||
}
|
||||
} else
|
||||
LOG_INFO(Lib_NpTrophy, "couldnt parse xml : {}", result.description());
|
||||
}
|
||||
|
||||
return ORBIS_OK;
|
||||
}
|
||||
|
@ -548,35 +504,33 @@ s32 PS4_SYSV_ABI sceNpTrophyGetTrophyUnlockState(OrbisNpTrophyContext context,
|
|||
|
||||
ORBIS_NP_TROPHY_FLAG_ZERO(flags);
|
||||
|
||||
const auto trophyDir =
|
||||
const auto trophy_dir =
|
||||
Common::FS::GetUserPath(Common::FS::PathType::MetaDataDir) / game_serial / "TrophyFiles";
|
||||
|
||||
pugi::xml_document doc;
|
||||
pugi::xml_parse_result result =
|
||||
doc.load_file((trophyDir.string() + "/trophy00/Xml/TROP.XML").c_str());
|
||||
doc.load_file((trophy_dir / "trophy00" / "Xml" / "TROP.XML").c_str());
|
||||
|
||||
int numTrophies = 0;
|
||||
ASSERT_MSG(result, "Couldnt parse trophy XML : {}", result.description());
|
||||
|
||||
if (result) {
|
||||
auto trophyconf = doc.child("trophyconf");
|
||||
for (pugi::xml_node_iterator it = trophyconf.children().begin();
|
||||
it != trophyconf.children().end(); ++it) {
|
||||
int num_trophies = 0;
|
||||
auto trophyconf = doc.child("trophyconf");
|
||||
|
||||
std::string currentTrophyId = it->attribute("id").value();
|
||||
std::string currentTrophyUnlockState = it->attribute("unlockstate").value();
|
||||
for (const pugi::xml_node& node : trophyconf.children()) {
|
||||
std::string_view node_name = node.name();
|
||||
int current_trophy_id = node.attribute("id").as_int(ORBIS_NP_TROPHY_INVALID_TROPHY_ID);
|
||||
bool current_trophy_unlockstate = node.attribute("unlockstate").as_bool();
|
||||
|
||||
if (std::string(it->name()) == "trophy") {
|
||||
numTrophies++;
|
||||
}
|
||||
|
||||
if (currentTrophyUnlockState == "unlocked") {
|
||||
ORBIS_NP_TROPHY_FLAG_SET(std::stoi(currentTrophyId), flags);
|
||||
}
|
||||
if (node_name == "trophy") {
|
||||
num_trophies++;
|
||||
}
|
||||
} else
|
||||
LOG_INFO(Lib_NpTrophy, "couldnt parse xml : {}", result.description());
|
||||
|
||||
*count = numTrophies;
|
||||
if (current_trophy_unlockstate) {
|
||||
ORBIS_NP_TROPHY_FLAG_SET(current_trophy_id, flags);
|
||||
}
|
||||
}
|
||||
|
||||
*count = num_trophies;
|
||||
return ORBIS_OK;
|
||||
}
|
||||
|
||||
|
@ -905,136 +859,116 @@ int PS4_SYSV_ABI sceNpTrophyUnlockTrophy(OrbisNpTrophyContext context, OrbisNpTr
|
|||
if (platinumId == nullptr)
|
||||
return ORBIS_NP_TROPHY_ERROR_INVALID_ARGUMENT;
|
||||
|
||||
const auto trophyDir =
|
||||
const auto trophy_dir =
|
||||
Common::FS::GetUserPath(Common::FS::PathType::MetaDataDir) / game_serial / "TrophyFiles";
|
||||
|
||||
pugi::xml_document doc;
|
||||
pugi::xml_parse_result result =
|
||||
doc.load_file((trophyDir.string() + "/trophy00/Xml/TROP.XML").c_str());
|
||||
doc.load_file((trophy_dir / "trophy00" / "Xml" / "TROP.XML").c_str());
|
||||
|
||||
ASSERT_MSG(result, "Couldnt parse trophy XML : {}", result.description());
|
||||
|
||||
*platinumId = ORBIS_NP_TROPHY_INVALID_TROPHY_ID;
|
||||
|
||||
int numTrophies = 0;
|
||||
int numTrophiesUnlocked = 0;
|
||||
int num_trophies = 0;
|
||||
int num_trophies_unlocked = 0;
|
||||
pugi::xml_node platinum_node;
|
||||
|
||||
pugi::xml_node_iterator platinumIt;
|
||||
auto trophyconf = doc.child("trophyconf");
|
||||
|
||||
if (result) {
|
||||
auto trophyconf = doc.child("trophyconf");
|
||||
for (pugi::xml_node_iterator it = trophyconf.children().begin();
|
||||
it != trophyconf.children().end(); ++it) {
|
||||
for (pugi::xml_node& node : trophyconf.children()) {
|
||||
int current_trophy_id = node.attribute("id").as_int(ORBIS_NP_TROPHY_INVALID_TROPHY_ID);
|
||||
bool current_trophy_unlockstate = node.attribute("unlockstate").as_bool();
|
||||
const char* current_trophy_name = node.child("name").text().as_string();
|
||||
std::string_view current_trophy_description = node.child("detail").text().as_string();
|
||||
std::string_view current_trophy_type = node.attribute("ttype").value();
|
||||
|
||||
std::string currentTrophyId = it->attribute("id").value();
|
||||
std::string currentTrophyName = it->child("name").text().as_string();
|
||||
std::string currentTrophyDescription = it->child("detail").text().as_string();
|
||||
std::string currentTrophyType = it->attribute("ttype").value();
|
||||
std::string currentTrophyUnlockState = it->attribute("unlockstate").value();
|
||||
std::string currentIconPath =
|
||||
trophyDir.string() + "/trophy00/Icons/TROP" + currentTrophyId + ".PNG";
|
||||
if (current_trophy_type == "P") {
|
||||
platinum_node = node;
|
||||
if (trophyId == current_trophy_id) {
|
||||
return ORBIS_NP_TROPHY_ERROR_PLATINUM_CANNOT_UNLOCK;
|
||||
}
|
||||
}
|
||||
|
||||
if (currentTrophyType == "P") {
|
||||
platinumIt = it;
|
||||
if (trophyId == std::stoi(currentTrophyId)) {
|
||||
return ORBIS_NP_TROPHY_ERROR_PLATINUM_CANNOT_UNLOCK;
|
||||
if (std::string_view(node.name()) == "trophy") {
|
||||
if (node.attribute("pid").as_int(-1) != ORBIS_NP_TROPHY_INVALID_TROPHY_ID) {
|
||||
num_trophies++;
|
||||
if (current_trophy_unlockstate) {
|
||||
num_trophies_unlocked++;
|
||||
}
|
||||
}
|
||||
|
||||
if (std::string(it->name()) == "trophy") {
|
||||
if (!std::string(it->attribute("pid").value()).empty()) {
|
||||
if (std::stoi(std::string(it->attribute("pid").value())) !=
|
||||
ORBIS_NP_TROPHY_INVALID_TROPHY_ID) {
|
||||
numTrophies++;
|
||||
if (currentTrophyUnlockState == "unlocked") {
|
||||
numTrophiesUnlocked++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (std::stoi(currentTrophyId) == trophyId) {
|
||||
LOG_INFO(Lib_NpTrophy, "Found trophy to unlock {} : {}",
|
||||
it->child("name").text().as_string(),
|
||||
it->child("detail").text().as_string());
|
||||
if (currentTrophyUnlockState == "unlocked") {
|
||||
LOG_INFO(Lib_NpTrophy, "Trophy already unlocked");
|
||||
return ORBIS_NP_TROPHY_ERROR_TROPHY_ALREADY_UNLOCKED;
|
||||
if (current_trophy_id == trophyId) {
|
||||
if (current_trophy_unlockstate) {
|
||||
LOG_INFO(Lib_NpTrophy, "Trophy already unlocked");
|
||||
return ORBIS_NP_TROPHY_ERROR_TROPHY_ALREADY_UNLOCKED;
|
||||
} else {
|
||||
if (node.attribute("unlockstate").empty()) {
|
||||
node.append_attribute("unlockstate") = "true";
|
||||
} else {
|
||||
if (std::string(it->attribute("unlockstate").value()).empty()) {
|
||||
it->append_attribute("unlockstate") = "unlocked";
|
||||
} else {
|
||||
it->attribute("unlockstate").set_value("unlocked");
|
||||
}
|
||||
|
||||
Rtc::OrbisRtcTick trophyTimestamp;
|
||||
Rtc::sceRtcGetCurrentTick(&trophyTimestamp);
|
||||
|
||||
if (std::string(it->attribute("timestamp").value()).empty()) {
|
||||
it->append_attribute("timestamp") =
|
||||
std::to_string(trophyTimestamp.tick).c_str();
|
||||
} else {
|
||||
it->attribute("timestamp")
|
||||
.set_value(std::to_string(trophyTimestamp.tick).c_str());
|
||||
}
|
||||
|
||||
g_trophy_ui.AddTrophyToQueue(currentIconPath, currentTrophyName);
|
||||
node.attribute("unlockstate").set_value("true");
|
||||
}
|
||||
|
||||
Rtc::OrbisRtcTick trophyTimestamp;
|
||||
Rtc::sceRtcGetCurrentTick(&trophyTimestamp);
|
||||
|
||||
if (node.attribute("timestamp").empty()) {
|
||||
node.append_attribute("timestamp") =
|
||||
std::to_string(trophyTimestamp.tick).c_str();
|
||||
} else {
|
||||
node.attribute("timestamp")
|
||||
.set_value(std::to_string(trophyTimestamp.tick).c_str());
|
||||
}
|
||||
|
||||
std::string trophy_icon_file = "TROP";
|
||||
trophy_icon_file.append(node.attribute("id").value());
|
||||
trophy_icon_file.append(".PNG");
|
||||
|
||||
std::filesystem::path current_icon_path =
|
||||
trophy_dir / "trophy00" / "Icons" / trophy_icon_file;
|
||||
|
||||
g_trophy_ui.AddTrophyToQueue(current_icon_path, current_trophy_name);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (std::string(platinumIt->attribute("unlockstate").value()).empty()) {
|
||||
if ((numTrophies - 1) == numTrophiesUnlocked) {
|
||||
|
||||
platinumIt->append_attribute("unlockstate") = "unlocked";
|
||||
|
||||
Rtc::OrbisRtcTick trophyTimestamp;
|
||||
Rtc::sceRtcGetCurrentTick(&trophyTimestamp);
|
||||
|
||||
if (std::string(platinumIt->attribute("timestamp").value()).empty()) {
|
||||
platinumIt->append_attribute("timestamp") =
|
||||
std::to_string(trophyTimestamp.tick).c_str();
|
||||
} else {
|
||||
platinumIt->attribute("timestamp")
|
||||
.set_value(std::to_string(trophyTimestamp.tick).c_str());
|
||||
}
|
||||
|
||||
std::string platinumTrophyId = platinumIt->attribute("id").value();
|
||||
std::string platinumTrophyName = platinumIt->child("name").text().as_string();
|
||||
std::string platinumIconPath =
|
||||
trophyDir.string() + "/trophy00/Icons/TROP" + platinumTrophyId + ".PNG";
|
||||
|
||||
*platinumId = std::stoi(platinumTrophyId);
|
||||
g_trophy_ui.AddTrophyToQueue(platinumIconPath, platinumTrophyName);
|
||||
if (!platinum_node.attribute("unlockstate").as_bool()) {
|
||||
if ((num_trophies - 1) == num_trophies_unlocked) {
|
||||
if (platinum_node.attribute("unlockstate").empty()) {
|
||||
platinum_node.append_attribute("unlockstate") = "true";
|
||||
} else {
|
||||
platinum_node.attribute("unlockstate").set_value("true");
|
||||
}
|
||||
} else if (std::string(platinumIt->attribute("unlockstate").value()) == "locked") {
|
||||
if ((numTrophies - 1) == numTrophiesUnlocked) {
|
||||
|
||||
platinumIt->attribute("unlockstate").set_value("unlocked");
|
||||
Rtc::OrbisRtcTick trophyTimestamp;
|
||||
Rtc::sceRtcGetCurrentTick(&trophyTimestamp);
|
||||
|
||||
Rtc::OrbisRtcTick trophyTimestamp;
|
||||
Rtc::sceRtcGetCurrentTick(&trophyTimestamp);
|
||||
|
||||
if (std::string(platinumIt->attribute("timestamp").value()).empty()) {
|
||||
platinumIt->append_attribute("timestamp") =
|
||||
std::to_string(trophyTimestamp.tick).c_str();
|
||||
} else {
|
||||
platinumIt->attribute("timestamp")
|
||||
.set_value(std::to_string(trophyTimestamp.tick).c_str());
|
||||
}
|
||||
|
||||
std::string platinumTrophyId = platinumIt->attribute("id").value();
|
||||
std::string platinumTrophyName = platinumIt->child("name").text().as_string();
|
||||
std::string platinumIconPath =
|
||||
trophyDir.string() + "/trophy00/Icons/TROP" + platinumTrophyId + ".PNG";
|
||||
|
||||
*platinumId = std::stoi(platinumTrophyId);
|
||||
g_trophy_ui.AddTrophyToQueue(platinumIconPath, platinumTrophyName);
|
||||
if (platinum_node.attribute("timestamp").empty()) {
|
||||
platinum_node.append_attribute("timestamp") =
|
||||
std::to_string(trophyTimestamp.tick).c_str();
|
||||
} else {
|
||||
platinum_node.attribute("timestamp")
|
||||
.set_value(std::to_string(trophyTimestamp.tick).c_str());
|
||||
}
|
||||
|
||||
int platinum_trophy_id =
|
||||
platinum_node.attribute("id").as_int(ORBIS_NP_TROPHY_INVALID_TROPHY_ID);
|
||||
const char* platinum_trophy_name = platinum_node.child("name").text().as_string();
|
||||
|
||||
std::string platinum_icon_file = "TROP";
|
||||
platinum_icon_file.append(platinum_node.attribute("id").value());
|
||||
platinum_icon_file.append(".PNG");
|
||||
|
||||
std::filesystem::path platinum_icon_path =
|
||||
trophy_dir / "trophy00" / "Icons" / platinum_icon_file;
|
||||
|
||||
*platinumId = platinum_trophy_id;
|
||||
g_trophy_ui.AddTrophyToQueue(platinum_icon_path, platinum_trophy_name);
|
||||
}
|
||||
}
|
||||
|
||||
doc.save_file((trophyDir.string() + "/trophy00/Xml/TROP.XML").c_str());
|
||||
|
||||
} else
|
||||
LOG_INFO(Lib_NpTrophy, "couldnt parse xml : {}", result.description());
|
||||
doc.save_file((trophy_dir.string() + "/trophy00/Xml/TROP.XML").c_str());
|
||||
|
||||
return ORBIS_OK;
|
||||
}
|
||||
|
|
|
@ -47,7 +47,7 @@ bool ORBIS_NP_TROPHY_FLAG_ISSET(int32_t trophyId, OrbisNpTrophyFlagArray* p);
|
|||
|
||||
struct OrbisNpTrophyData {
|
||||
size_t size;
|
||||
OrbisNpTrophyId trophyId;
|
||||
OrbisNpTrophyId trophy_id;
|
||||
bool unlocked;
|
||||
uint8_t reserved[3];
|
||||
Rtc::OrbisRtcTick timestamp;
|
||||
|
@ -66,9 +66,9 @@ constexpr int ORBIS_NP_TROPHY_INVALID_GROUP_ID = -2;
|
|||
|
||||
struct OrbisNpTrophyDetails {
|
||||
size_t size;
|
||||
OrbisNpTrophyId trophyId;
|
||||
OrbisNpTrophyGrade trophyGrade;
|
||||
OrbisNpTrophyGroupId groupId;
|
||||
OrbisNpTrophyId trophy_id;
|
||||
OrbisNpTrophyGrade trophy_grade;
|
||||
OrbisNpTrophyGroupId group_id;
|
||||
bool hidden;
|
||||
uint8_t reserved[3];
|
||||
char name[ORBIS_NP_TROPHY_NAME_MAX_SIZE];
|
||||
|
@ -77,46 +77,46 @@ struct OrbisNpTrophyDetails {
|
|||
|
||||
struct OrbisNpTrophyGameData {
|
||||
size_t size;
|
||||
uint32_t unlockedTrophies;
|
||||
uint32_t unlockedPlatinum;
|
||||
uint32_t unlockedGold;
|
||||
uint32_t unlockedSilver;
|
||||
uint32_t unlockedBronze;
|
||||
uint32_t progressPercentage;
|
||||
uint32_t unlocked_trophies;
|
||||
uint32_t unlocked_platinum;
|
||||
uint32_t unlocked_gold;
|
||||
uint32_t unlocked_silver;
|
||||
uint32_t unlocked_bronze;
|
||||
uint32_t progress_percentage;
|
||||
};
|
||||
|
||||
struct OrbisNpTrophyGameDetails {
|
||||
size_t size;
|
||||
uint32_t numGroups;
|
||||
uint32_t numTrophies;
|
||||
uint32_t numPlatinum;
|
||||
uint32_t numGold;
|
||||
uint32_t numSilver;
|
||||
uint32_t numBronze;
|
||||
uint32_t num_groups;
|
||||
uint32_t num_trophies;
|
||||
uint32_t num_platinum;
|
||||
uint32_t num_gold;
|
||||
uint32_t num_silver;
|
||||
uint32_t num_bronze;
|
||||
char title[ORBIS_NP_TROPHY_GAME_TITLE_MAX_SIZE];
|
||||
char description[ORBIS_NP_TROPHY_GAME_DESCR_MAX_SIZE];
|
||||
};
|
||||
|
||||
struct OrbisNpTrophyGroupData {
|
||||
size_t size;
|
||||
OrbisNpTrophyGroupId groupId;
|
||||
uint32_t unlockedTrophies;
|
||||
uint32_t unlockedPlatinum;
|
||||
uint32_t unlockedGold;
|
||||
uint32_t unlockedSilver;
|
||||
uint32_t unlockedBronze;
|
||||
uint32_t progressPercentage;
|
||||
OrbisNpTrophyGroupId group_id;
|
||||
uint32_t unlocked_trophies;
|
||||
uint32_t unlocked_platinum;
|
||||
uint32_t unlocked_gold;
|
||||
uint32_t unlocked_silver;
|
||||
uint32_t unlocked_bronze;
|
||||
uint32_t progress_percentage;
|
||||
uint8_t reserved[4];
|
||||
};
|
||||
|
||||
struct OrbisNpTrophyGroupDetails {
|
||||
size_t size;
|
||||
OrbisNpTrophyGroupId groupId;
|
||||
uint32_t numTrophies;
|
||||
uint32_t numPlatinum;
|
||||
uint32_t numGold;
|
||||
uint32_t numSilver;
|
||||
uint32_t numBronze;
|
||||
OrbisNpTrophyGroupId group_id;
|
||||
uint32_t num_trophies;
|
||||
uint32_t num_platinum;
|
||||
uint32_t num_gold;
|
||||
uint32_t num_silver;
|
||||
uint32_t num_bronze;
|
||||
char title[ORBIS_NP_TROPHY_GROUP_TITLE_MAX_SIZE];
|
||||
char description[ORBIS_NP_TROPHY_GROUP_DESCR_MAX_SIZE];
|
||||
};
|
||||
|
|
|
@ -19,12 +19,12 @@ TrophyUI::~TrophyUI() {
|
|||
Finish();
|
||||
}
|
||||
|
||||
void Libraries::NpTrophy::TrophyUI::AddTrophyToQueue(std::string trophyIconPath,
|
||||
void Libraries::NpTrophy::TrophyUI::AddTrophyToQueue(std::filesystem::path trophyIconPath,
|
||||
std::string trophyName) {
|
||||
TrophyInfo newInfo;
|
||||
newInfo.trophyIconPath = trophyIconPath;
|
||||
newInfo.trophyName = trophyName;
|
||||
trophyQueue.push_back(newInfo);
|
||||
newInfo.trophy_icon_path = trophyIconPath;
|
||||
newInfo.trophy_name = trophyName;
|
||||
trophy_queue.push_back(newInfo);
|
||||
}
|
||||
|
||||
void TrophyUI::Finish() {
|
||||
|
@ -44,7 +44,7 @@ void TrophyUI::Draw() {
|
|||
std::min(io.DisplaySize.y, 70.f),
|
||||
};
|
||||
|
||||
if (trophyQueue.size() != 0) {
|
||||
if (trophy_queue.size() != 0) {
|
||||
if (!displayingTrophy) {
|
||||
displayingTrophy = true;
|
||||
trophyStartedTime = std::chrono::steady_clock::now();
|
||||
|
@ -55,26 +55,27 @@ void TrophyUI::Draw() {
|
|||
std::chrono::duration_cast<std::chrono::seconds>(timeNow - trophyStartedTime);
|
||||
|
||||
if (duration.count() >= 5) {
|
||||
trophyQueue.erase(trophyQueue.begin());
|
||||
trophy_queue.erase(trophy_queue.begin());
|
||||
displayingTrophy = false;
|
||||
iconLoaded = false;
|
||||
}
|
||||
|
||||
if (trophyQueue.size() != 0) {
|
||||
if (trophy_queue.size() != 0) {
|
||||
SetNextWindowSize(window_size);
|
||||
SetNextWindowCollapsed(false);
|
||||
SetNextWindowPos(ImVec2(io.DisplaySize.x - 250, 50));
|
||||
KeepNavHighlight();
|
||||
|
||||
TrophyInfo currentTrophyInfo = trophyQueue[0];
|
||||
TrophyInfo currentTrophyInfo = trophy_queue[0];
|
||||
|
||||
if (!iconLoaded) {
|
||||
if (std::filesystem::exists(currentTrophyInfo.trophyIconPath)) {
|
||||
trophyIcon = RefCountedTexture::DecodePngFile(currentTrophyInfo.trophyIconPath);
|
||||
if (std::filesystem::exists(currentTrophyInfo.trophy_icon_path)) {
|
||||
trophyIcon =
|
||||
RefCountedTexture::DecodePngFile(currentTrophyInfo.trophy_icon_path);
|
||||
iconLoaded = true;
|
||||
} else {
|
||||
LOG_ERROR(Lib_NpTrophy, "Couldnt load trophy icon at {}",
|
||||
currentTrophyInfo.trophyIconPath);
|
||||
currentTrophyInfo.trophy_icon_path.string());
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -85,7 +86,7 @@ void TrophyUI::Draw() {
|
|||
Image(trophyIcon.GetTexture().im_id, ImVec2(50, 50));
|
||||
ImGui::SameLine();
|
||||
}
|
||||
TextWrapped("Trophy earned!\n%s", currentTrophyInfo.trophyName.c_str());
|
||||
TextWrapped("Trophy earned!\n%s", currentTrophyInfo.trophy_name.c_str());
|
||||
}
|
||||
End();
|
||||
}
|
||||
|
|
|
@ -15,18 +15,18 @@
|
|||
namespace Libraries::NpTrophy {
|
||||
|
||||
struct TrophyInfo {
|
||||
std::string trophyIconPath;
|
||||
std::string trophyName;
|
||||
std::filesystem::path trophy_icon_path;
|
||||
std::string trophy_name;
|
||||
};
|
||||
|
||||
class TrophyUI final : public ImGui::Layer {
|
||||
std::vector<TrophyInfo> trophyQueue;
|
||||
std::vector<TrophyInfo> trophy_queue;
|
||||
|
||||
public:
|
||||
TrophyUI();
|
||||
~TrophyUI() override;
|
||||
|
||||
void AddTrophyToQueue(std::string trophyIconPath, std::string trophyName);
|
||||
void AddTrophyToQueue(std::filesystem::path trophyIconPath, std::string trophyName);
|
||||
|
||||
void Finish();
|
||||
|
||||
|
|
Loading…
Add table
Reference in a new issue