config_emu improvements

This commit is contained in:
igor725 2024-04-12 02:54:50 +03:00
parent 4ff5dc4a34
commit 586f5da72c
No known key found for this signature in database
GPG Key ID: 46F13BBE46F8569D
4 changed files with 136 additions and 24 deletions

View File

@ -5,4 +5,12 @@ project(${libName})
add_library(${libName} SHARED entry.cpp)
target_link_directories(${libName} PRIVATE
${CMAKE_BINARY_DIR}/third_party/install/lib
)
add_dependencies(${libName} boost config_emu)
target_compile_definitions(${libName} PUBLIC BOOST_ALL_NO_LIB)
target_link_libraries(${libName} PUBLIC libboost_thread config_emu.lib)
setupModule(${libName})

View File

@ -11,3 +11,5 @@ constexpr int USER_SERVICE_ERROR_NO_EVENT = -2137653241; /* 0x809
constexpr int USER_SERVICE_ERROR_NOT_LOGGED_IN = -2137653239; /* 0x80960009 */
constexpr int USER_SERVICE_ERROR_BUFFER_TOO_SHORT = -2137653238; /* 0x8096000A */
} // namespace Err
constexpr size_t USER_SERVICE_MAX_USER_NAME_LENGTH = 16;

View File

@ -1,7 +1,10 @@
#include "codes.h"
#include "common.h"
#include "errorcodes.h"
#include "config_emu.h"
#include "logging.h"
#include <unordered_map>
LOG_DEFINE_MODULE(libSceUserService);
namespace {
@ -17,6 +20,20 @@ struct UserServiceEvent {
};
enum UserServiceUserColor { USER_COLOR_BLUE, USER_COLOR_RED, USER_COLOR_GREEN, USER_COLOR_PINK };
static std::unordered_map<std::string_view, UserServiceUserColor> colors = {
{"blue", USER_COLOR_BLUE},
{"red", USER_COLOR_RED},
{"green", USER_COLOR_GREEN},
{"pink", USER_COLOR_PINK},
};
static UserServiceUserColor map_user_color(std::string_view str) {
auto it = colors.find(str);
if (it != colors.end()) return it->second;
return USER_COLOR_BLUE;
}
} // namespace
extern "C" {
@ -36,8 +53,8 @@ EXPORT SYSV_ABI int32_t sceUserServiceTerminate() {
}
EXPORT SYSV_ABI int sceUserServiceGetInitialUser(int* userId) {
*userId = 1;
auto [lock, jData] = accessConfig()->accessModule(ConfigModFlag::GENERAL);
if (!getJsonParam(jData, "userIndex", *userId) || (*userId < 1 || *userId > 3)) *userId = 1;
return Ok;
}
@ -47,7 +64,7 @@ EXPORT SYSV_ABI int sceUserServiceGetEvent(UserServiceEvent* event) {
if (!logged_in) {
logged_in = true;
event->eventType = UserServiceEventTypeLogin;
event->userId = 1;
sceUserServiceGetInitialUser(&event->userId);
return Ok;
}
@ -55,7 +72,7 @@ EXPORT SYSV_ABI int sceUserServiceGetEvent(UserServiceEvent* event) {
}
EXPORT SYSV_ABI int sceUserServiceGetLoginUserIdList(UserServiceLoginUserIdList* userId_list) {
userId_list->userId[0] = 1;
sceUserServiceGetInitialUser(&userId_list->userId[0]);
userId_list->userId[1] = -1;
userId_list->userId[2] = -1;
userId_list->userId[3] = -1;
@ -64,14 +81,36 @@ EXPORT SYSV_ABI int sceUserServiceGetLoginUserIdList(UserServiceLoginUserIdList*
}
EXPORT SYSV_ABI int sceUserServiceGetUserName(int userId, char* name, size_t size) {
if (userId < 1 || userId > 3) return Err::USER_SERVICE_ERROR_INVALID_ARGUMENT;
std::string username = "Anon";
auto const count = username.copy(name, size - 1);
auto [lock, jData] = accessConfig()->accessModule(ConfigModFlag::GENERAL);
try {
auto& profiles = (*jData)["profiles"];
auto& cprofile = profiles[userId - 1];
cprofile["name"].get_to(username);
} catch (json::exception& ex) {
}
auto const count = username.copy(name, std::min(USER_SERVICE_MAX_USER_NAME_LENGTH, size - 1));
name[count] = '\0';
return Ok;
}
EXPORT SYSV_ABI int32_t sceUserServiceGetUserColor(int userId, UserServiceUserColor* color) {
*color = USER_COLOR_BLUE;
auto [lock, jData] = accessConfig()->accessModule(ConfigModFlag::GENERAL);
std::string _scolor;
try {
auto& profiles = (*jData)["profiles"];
auto& cprofile = profiles[userId - 1];
cprofile["color"].get_to(_scolor);
} catch (json::exception& ex) {
}
*color = map_user_color(_scolor);
return Ok;
}
}

View File

@ -106,21 +106,81 @@ Config::Config() {
should_backup = true;
}
for (auto& [dkey, dval]: defaults.items()) {
if ((item->_json)[dkey].is_null() && !dval.is_null()) {
(item->_json)[dkey] = dval;
should_resave = true;
printf("%s: missing parameter \"%s\" has been added!\n", item->_name.data(), dkey.c_str());
std::function<bool(json&, json&)> fixMissing;
std::function<bool(json&, json&)> removeUnused;
/**
* @brief This function is necessary since json.items()
* translates every key to string. Even the array indexes,
* so we have to translate it back to number for arrays.
*
*/
auto getVal = [](json& _o, std::string_view key) -> json& {
if (_o.is_array()) {
int _tempi;
auto res = std::from_chars(key.data(), key.data() + key.size(), _tempi);
if (res.ec == std::errc::invalid_argument) {
printf("Unreachable scenario!\n"); // At least it should be
exit(1);
}
return _o[_tempi];
}
return _o[key];
};
fixMissing = [&should_backup, &getVal, &fixMissing](json& obj, json& def) -> bool {
bool missing = false;
for (auto& [dkey, dval]: def.items()) {
json& cval = getVal(obj, dkey);
if (cval.is_null() && !dval.is_null()) {
cval = dval;
missing = true;
} else if (dval.is_structured()) {
if (cval.is_structured()) { // Function calls itself if json element is array or object
missing |= fixMissing(cval, dval);
continue;
}
should_backup = true;
cval = dval;
missing = true;
}
}
for (auto& [ckey, cval]: item->_json.items()) {
if (defaults[ckey].is_null()) {
item->_json.erase(ckey);
return missing;
};
if (fixMissing(item->_json, defaults)) {
should_resave = true;
printf("%s: some missing parameters has been added!\n", item->_name.data());
}
// Just the same thing as above, but for removing unused keys this time
removeUnused = [&getVal, &removeUnused](json& obj, json& def) -> bool {
bool unused = false;
for (auto& [ckey, cval]: obj.items()) {
json& dval = getVal(def, ckey);
if (dval.is_null()) {
obj.erase(ckey);
unused = true;
} else if (dval.is_structured()) {
unused |= removeUnused(cval, dval);
continue;
}
}
return unused;
};
if (removeUnused(item->_json, defaults)) {
should_backup = true;
should_resave = true;
printf("%s: unused parameter \"%s\" has been removed!\n", item->_name.data(), ckey.c_str());
}
printf("%s: some unused parameters has been removed!\n", item->_name.data());
}
if (should_backup == true && std::filesystem::exists(path)) {
@ -137,6 +197,7 @@ Config::Config() {
};
const json defaultpad = {{"type", "gamepad"}, {"deadzones", {{"left_stick", {{"x", 0.0f}, {"y", 0.0f}}}, {"right_stick", {{"x", 0.0f}, {"y", 0.0f}}}}}};
const json defaultprof = {{"name", "Anon"}, {"color", "blue"}};
m_logging._future =
std::async(std::launch::async | std::launch::deferred, load, &m_logging, json({{"sink", "FileBin"}, {"verbosity", 1}}), ConfigModFlag::LOGGING);
@ -160,5 +221,7 @@ Config::Config() {
}}}),
ConfigModFlag::CONTROLS);
m_general._future = std::async(std::launch::async, load, &m_general, json({{"systemlang", 1}}), ConfigModFlag::GENERAL);
m_general._future =
std::async(std::launch::async, load, &m_general,
json({{"systemlang", 1}, {"userIndex", 1}, {"profiles", json::array({defaultprof, defaultprof, defaultprof})}}), ConfigModFlag::GENERAL);
}