/** * @file PermissionAPI.h * @author LiteLDev (https://github.com/LiteLDev) * @brief Permission APIs * * @copyright Copyright (c) 2021-present LiteLoaderBDS developers and all contributors * */ #pragma once #include "LLAPI.h" #include "PERM/Role.hpp" /** * @brief PermissionAPI (Dynamic dependency). * */ class DynPermissionAPI { using FuncCreateRole = void (*)(const std::string&, const std::string&, std::weak_ptr&); using FuncRoleExists = bool (*)(const std::string&); using FuncGetRole = void (*)(const std::string&, std::weak_ptr&); using FuncGetOrCreateRole = void (*)(const std::string&, std::weak_ptr&); using FuncDeleteRole = void(*)(const std::string&); using FuncRegisterPermission = void (*)(const std::string&, const std::string&); using FuncDeletePermission = void (*)(const std::string&); using FuncPermissionExists = bool (*)(const std::string&); using FuncCheckPermission = bool (*)(const xuid_t&, const std::string&); using FuncIsMemberOf = bool (*)(const xuid_t&, const std::string&); using FuncGetPlayerRoles = void (*)(const xuid_t&, PERM::Roles&); using FuncGetPlayerPermissions = void (*)(const xuid_t&, PERM::Permissions&); using FuncSaveData = void (*)(); HMODULE handle = nullptr; FuncCreateRole funcCreateRole = nullptr; FuncRoleExists funcRoleExists = nullptr; FuncGetRole funcGetRole = nullptr; FuncGetOrCreateRole funcGetOrCreateRole = nullptr; FuncDeleteRole funcDeleteRole = nullptr; FuncRegisterPermission funcRegisterPermission = nullptr; FuncDeletePermission funcDeletePermission = nullptr; FuncPermissionExists funcPermissionExists = nullptr; FuncCheckPermission funcCheckPermission = nullptr; FuncIsMemberOf funcIsMemberOf = nullptr; FuncGetPlayerRoles funcGetPlayerRoles = nullptr; FuncGetPlayerPermissions funcGetPlayerPermissions = nullptr; FuncSaveData funcSaveData = nullptr; template T getFunc(const std::string& name) { return (T)GetProcAddress(handle, name.c_str()); } public: DynPermissionAPI() = default; /** * @brief Init APIs by GetAddressProc. * */ void init(HMODULE hModule = nullptr) { if (!hModule) { auto pPtr = LL::getPlugin("PermissionAPI"); if (!pPtr) { throw std::runtime_error("Cannot get the plugin object"); } handle = pPtr->handle; } else { handle = hModule; } funcCreateRole = getFunc("PERM_CreateRole"); funcRoleExists = getFunc("PERM_RoleExists"); funcGetRole = getFunc("PERM_GetRole"); funcGetOrCreateRole = getFunc("PERM_GetOrCreateRole"); funcDeleteRole = getFunc("PERM_DeleteRole"); funcRegisterPermission = getFunc("PERM_RegisterPermission"); funcDeletePermission = getFunc("PERM_DeletePermission"); funcPermissionExists = getFunc("PERM_PermissionExists"); funcCheckPermission = getFunc("PERM_CheckPermission"); funcIsMemberOf = getFunc("PERM_IsMemberOf"); funcGetPlayerRoles = getFunc("PERM_GetPlayerRoles"); funcGetPlayerPermissions = getFunc("PERM_GetPlayerPermissions"); funcSaveData = getFunc("PERM_SaveData"); } /** * @brief Create a Role object. * * @param name The name of the role. * @param displayName The display name of the role. * @return std::weak_ptr The created role(weak ref). * @throws std::invalid_argument If the role already exists. * @par Example * @code * PermissionAPI api; * auto role = api.createRole("role1", "Role 1"); * ... * if (!role.expired()) { * auto rolePtr = role.lock(); * rolePtr->addMember("1145141919810"); * api.saveData(); * } * @endcode */ std::weak_ptr createRole(const std::string& name, const std::string& displayName) { if (funcCreateRole == nullptr) { throw std::runtime_error("Function not found"); } std::weak_ptr ptr{}; funcCreateRole(name, displayName, ptr); return ptr; } /** * @brief Check if a role exists. * * @param name The name of the role. * @return bool True If the role exists, false otherwise. */ bool roleExists(const std::string& name) { if (funcRoleExists == nullptr) { throw std::runtime_error("Function not found"); } return funcRoleExists(name); } /** * @brief Get a role object. * * @param name The name of the role. * @return std::weak_ptr The role(weak ref). * @throws std::invalid_argument If the role does not exist. */ std::weak_ptr getRole(const std::string& name) { if (funcGetRole == nullptr) { throw std::runtime_error("Function not found"); } std::weak_ptr ptr{}; funcGetRole(name, ptr); return ptr; } /** * @brief Get a role object. If the role does not exist, it will be created. * * @param name The name of the role. * @return std::weak_ptr The role(weak ref). */ std::weak_ptr getOrCreateRole(const std::string& name) { if (funcGetOrCreateRole == nullptr) { throw std::runtime_error("Function not found"); } std::weak_ptr ptr{}; funcGetOrCreateRole(name, ptr); return ptr; } /** * @brief Delete a role. * * @param name The name of the role. */ void deleteRole(const std::string& name) { if (funcDeleteRole == nullptr) { throw std::runtime_error("Function not found"); } funcDeleteRole(name); } /** * @brief Register an permission. * * @param name The name of the permission. * @param desc The description name of the permission. */ void registerPermission(const std::string& name, const std::string& desc) { if (funcRegisterPermission == nullptr) { throw std::runtime_error("Function not found"); } funcRegisterPermission(name, desc); } /** * @brief Delete a permission. * * @param name The name of the permission. * @warning This function will also delete the permission instances in roles. */ void deletePermission(const std::string& name) { if (funcDeletePermission == nullptr) { throw std::runtime_error("Function not found"); } funcDeletePermission(name); } /** * @brief Check if a permission exists. * * @param name The name of the permission. * @return bool True If the permission exists, false otherwise. */ bool permissionExists(const std::string& name) { if (funcPermissionExists == nullptr) { throw std::runtime_error("Function not found"); } return funcPermissionExists(name); } /** * @brief Check whether the player has the Permission or not. * * @param xuid The xuid of the player. * @param name The name of the Permission. * @return bool True If the player has the Permission, false otherwise. */ bool checkPermission(const xuid_t& xuid, const std::string& name) { if (funcCheckPermission == nullptr) { throw std::runtime_error("Function not found"); } return funcCheckPermission(xuid, name); } /** * @brief Check if a player is a member of a role. * * @param xuid The xuid of the player. * @param name The name of the role. * @return bool True If the player is a member of the role, false otherwise. */ bool isMemberOf(const xuid_t& xuid, const std::string& name) { if (funcIsMemberOf == nullptr) { throw std::runtime_error("Function not found"); } return funcIsMemberOf(xuid, name); } /** * @brief Get the roles of a player. * * @param xuid The xuid of the player. * @return PERM::Roles The roles of the player. */ PERM::Roles getPlayerRoles(const xuid_t& xuid) { if (funcGetPlayerRoles == nullptr) { throw std::runtime_error("Function not found"); } PERM::Roles roles; funcGetPlayerRoles(xuid, roles); return roles; } /** * @brief Get the permissions of a player. * * @param xuid The xuid of the player. * @return PERM::Permissions The permissions of the player. */ PERM::Permissions getPlayerPermissions(const xuid_t& xuid) { if (funcGetPlayerPermissions == nullptr) { throw std::runtime_error("Function not found"); } PERM::Permissions permissions; funcGetPlayerPermissions(xuid, permissions); return permissions; } /** * @brief Save the data. */ void saveData() { if (funcSaveData == nullptr) { throw std::runtime_error("Function not found"); } funcSaveData(); } }; /** * @brief Permission APIs. * */ class Permission { public: static LIAPI DynPermissionAPI api; static void init(HMODULE hModule = nullptr) { api.init(hModule); } /** * @brief Create a Role object. * * @param name The name of the role. * @param displayName The display name of the role. * @return std::weak_ptr The created role(weak ref). * @throws std::invalid_argument If the role already exists. * @par Example * @code * auto role = Permission::createRole("role1", "Role 1"); * ... * if (!role.expired()) { * auto rolePtr = role.lock(); * rolePtr->addMember("1145141919810"); * api.saveData(); * } * @endcode */ static std::weak_ptr createRole(const std::string& name, const std::string& displayName) { return api.createRole(name, displayName); } /** * @brief Get a role object. * * @param name The name of the role. * @return std::weak_ptr The role(weak ref). * @throws std::invalid_argument If the role does not exist. * @par Example * @code * auto role = Permission::getRole("role1"); * ... * if (!role.expired()) { * auto rolePtr = role.lock(); * rolePtr->addMember("1145141919810"); * api.saveData(); * } * @endcode */ static std::weak_ptr getRole(const std::string& name) { return api.getRole(name); } /** * @brief Get or create a role object. * * @param name The name of the role. * @return std::weak_ptr The role(weak ref). */ static std::weak_ptr getOrCreateRole(const std::string& name) { return api.getOrCreateRole(name); } /** * @brief Delete a role. * * @param name The name of the role. * @throws std::invalid_argument If the role does not exist. * @par Example * @code * Permission::deleteRole("role1"); * @endcode */ static void deleteRole(const std::string& name) { api.deleteRole(name); } /** * @brief Check whether a role exists. * * @param name The name of the role. * @return bool True If the role exists, false otherwise. */ static bool roleExists(const std::string& name) { return api.roleExists(name); } /** * @brief Register an permission. * * @param name The name of the permission. * @param desc The description name of the permission. * @throws std::invalid_argument If the permission already exists. * @par Example * @code * Permission::registerPermission("MyPlugin:destroy", "Destroy permission for MyPlugin"); * @endcode */ static void registerPermission(const std::string& name, const std::string& desc) { api.registerPermission(name, desc); } /** * @brief Delete a permission. * * @param name The name of the permission. * @throws std::invalid_argument If the permission does not exist. * @note This function will also delete the permission instances in roles. * @par Example * @code * Permission::deletePermission("MyPlugin:destroy"); * @endcode */ static void deletePermission(const std::string& name) { api.deletePermission(name); } /** * @brief Check whether a permission exists. * * @param name The name of the permission. * @return bool True If the permission exists, false otherwise. */ static bool permissionExists(const std::string& name) { return api.permissionExists(name); } /** * @brief Check whether a player has a permission. * * @param xuid The xuid of the player. * @param name The name of the permission. * @return bool True If the player has the permission, false otherwise. * @throws std::invalid_argument If the permission does not exist. * @par Example * @code * if (Permission::checkPermission(pl->getXuid(), "MyPlugin:destroy")) { * // Do something * } * @endcode */ static bool checkPermission(const xuid_t& xuid, const std::string& name) { return api.checkPermission(xuid, name); } /** * @brief Check whether a player is member of a role. * * @param xuid The xuid of the player. * @param name The name of the role. * @return bool True If the player is member of the role, false otherwise. * @throws std::invalid_argument If the role does not exist. */ static bool isMemberOf(const xuid_t& xuid, const std::string& name) { return api.isMemberOf(xuid, name); } /** * @brief Get the roles of a player. * * @param xuid The xuid of the player. * @return PERM::Roles The roles of the player. */ static PERM::Roles getPlayerRoles(const xuid_t& xuid) { return api.getPlayerRoles(xuid); } /** * @brief Get the permissions of a player. * * @param xuid The xuid of the player. * @return PERM::Permissions The permissions of the player. */ static PERM::Permissions getPlayerPermissions(const xuid_t& xuid) { return api.getPlayerPermissions(xuid); } /** * @brief Save the data. * */ static void saveData() { api.saveData(); } };