From b74a9e371e0e099d3c7b473c704b8da3f2291c49 Mon Sep 17 00:00:00 2001 From: Yimura <24669514+Yimura@users.noreply.github.com> Date: Fri, 28 Oct 2022 16:54:33 +0200 Subject: [PATCH] feat: remove network related content (#510) --- BigBaseV2/src/api/api.hpp | 199 ----- BigBaseV2/src/api/http_request.hpp | 772 ------------------ BigBaseV2/src/api/remote.hpp | 92 --- BigBaseV2/src/backend/backend.cpp | 8 - .../src/backend/looped/api/login_session.cpp | 13 - BigBaseV2/src/gta_util.hpp | 12 + .../current_profile_general.cpp | 10 +- .../current_profile/current_profile_tabs.hpp | 1 - .../gui/handling/handling_current_profile.cpp | 20 +- .../src/gui/handling/handling_my_profiles.cpp | 58 -- .../gui/handling/handling_saved_profiles.cpp | 50 +- .../src/gui/handling/handling_search.cpp | 87 -- .../src/gui/handling/modals/save_handling.cpp | 50 +- .../gui/handling/modals/update_handling.cpp | 93 --- BigBaseV2/src/main.cpp | 6 +- BigBaseV2/src/services/gui/gui_service.hpp | 2 - .../src/services/vehicle/handling_profile.cpp | 21 + .../src/services/vehicle/handling_profile.hpp | 19 + .../src/services/vehicle/handling_service.cpp | 108 +++ .../src/services/vehicle/handling_service.hpp | 40 + .../src/services/vehicle/vehicle_service.cpp | 307 ------- .../src/services/vehicle/vehicle_service.hpp | 144 ---- BigBaseV2/src/views/view.hpp | 2 - 23 files changed, 232 insertions(+), 1882 deletions(-) delete mode 100644 BigBaseV2/src/api/api.hpp delete mode 100644 BigBaseV2/src/api/http_request.hpp delete mode 100644 BigBaseV2/src/api/remote.hpp delete mode 100644 BigBaseV2/src/backend/looped/api/login_session.cpp delete mode 100644 BigBaseV2/src/gui/handling/handling_my_profiles.cpp delete mode 100644 BigBaseV2/src/gui/handling/handling_search.cpp delete mode 100644 BigBaseV2/src/gui/handling/modals/update_handling.cpp create mode 100644 BigBaseV2/src/services/vehicle/handling_profile.cpp create mode 100644 BigBaseV2/src/services/vehicle/handling_profile.hpp create mode 100644 BigBaseV2/src/services/vehicle/handling_service.cpp create mode 100644 BigBaseV2/src/services/vehicle/handling_service.hpp delete mode 100644 BigBaseV2/src/services/vehicle/vehicle_service.cpp delete mode 100644 BigBaseV2/src/services/vehicle/vehicle_service.hpp diff --git a/BigBaseV2/src/api/api.hpp b/BigBaseV2/src/api/api.hpp deleted file mode 100644 index c0e8ae4a..00000000 --- a/BigBaseV2/src/api/api.hpp +++ /dev/null @@ -1,199 +0,0 @@ -#pragma once -#include "http_request.hpp" - -namespace big::api -{ - const std::string domain = "http://home.damon.sh:8089/api/v1"; - //const std::string domain = "http://localhost:8080/api/v1"; - inline std::string session_id; - - namespace util - { - static std::string authorization_header() - { - return std::string("Authorization: ") + api::session_id; - } - - static bool parse_body(http::Response& res, nlohmann::json& out) - { - try - { - out = nlohmann::json::parse(res.body.begin(), res.body.end()); - - return out["status"] == std::string("success"); - } - catch (const std::exception& e) - { - out = nullptr; - - LOG(INFO) << "Failed to parse request body: " << std::endl << e.what(); - - return false; - } - } - - static bool signed_in() - { - return !session_id.empty(); - } - } - - namespace auth - { - static bool create_session() - { - static std::atomic_bool busy = false; - if (busy || g_local_player == nullptr) return false; - busy = true; - - const std::string path = "/auth/create_session"; - - http::Request request(domain + path); - - auto player_info = g_local_player->m_player_info; - auto& netData = player_info->m_net_player_data; - - nlohmann::json body = { - { "username", std::string(netData.m_name) }, - { "rockstar_id", netData.m_gamer_handle_2.m_rockstar_id } - }; - - try - { - http::Response res = request.send("POST", body.dump(), { - "Content-Type: application/json" - }, 10000ms); - - nlohmann::json json; - if (util::parse_body(res, json)) - { - session_id = json["data"]["sessionId"].get(); - - LOG(INFO) << "Create session and received ID: " << session_id.c_str(); - - busy = false; - return true; - } - } - catch (const std::exception&) - { - LOG(INFO) << "Host is down, unable to create session."; - - busy = false; - return false; - } - - LOG(INFO) << "Failed to create a session."; - - busy = false; - return false; - } - } - - namespace vehicle - { - namespace handling - { - static bool create_profile(uint32_t handling_hash, const char* name, const char* description, nlohmann::json& handling_data, nlohmann::json& out) - { - if (!util::signed_in()) return false; - - const std::string path = "/vehicle/handling/create"; - - http::Request request(domain + path); - - out["handling_hash"] = handling_hash; - out["name"] = std::string(name); - out["description"] = std::string(description); - out["data"] = handling_data; - - http::Response res = request.send("POST", out.dump(), { - util::authorization_header() - }); - return util::parse_body(res, out); - } - - static bool get_by_share_code(std::string share_code, nlohmann::json& out) - { - if (!util::signed_in()) return false; - - const std::string path = "/vehicle/handling/get_by_share_code?share_code="; - - http::Request request(domain + path + share_code); - - http::Response res = request.send("GET", "", { - util::authorization_header() - }); - - return util::parse_body(res, out); - } - - static bool get_my_handling(uint32_t handling_hash, nlohmann::json &out) - { - if (!util::signed_in()) return false; - - const std::string path = "/vehicle/handling/get_mine?handling_hash="; - - http::Request request(domain + path + std::to_string(handling_hash)); - - http::Response res = request.send("GET", "", { - util::authorization_header() - }); - - return util::parse_body(res, out); - } - - static bool get_saved_handling(uint32_t handling_hash, nlohmann::json& out) - { - if (!util::signed_in()) return false; - - const std::string path = "/vehicle/handling/get_saved?handling_hash="; - - http::Request request(domain + path + std::to_string(handling_hash)); - - http::Response res = request.send("GET", "", { - util::authorization_header() - }); - - return util::parse_body(res, out); - } - - static bool save_profile(std::string share_code) - { - if (!util::signed_in()) return false; - - const std::string path = "/vehicle/handling/save_profile"; - - http::Request request(domain + path); - - nlohmann::json body = { { "share_code", share_code } }; - - http::Response res = request.send("POST", body.dump(), { - util::authorization_header() - }); - return util::parse_body(res, body); - } - - static bool update(uint32_t handling_hash, const char* name, const char* description, std::string share_code, nlohmann::json &update) - { - if (!util::signed_in()) return false; - - const std::string path = "/vehicle/handling/update"; - - http::Request request(domain + path); - - nlohmann::json json; - json["handling_hash"] = handling_hash; - json["name"] = std::string(name); - json["description"] = std::string(description); - json["data"] = update; - json["share_code"] = share_code; - - http::Response res = request.send("POST", json.dump(), { - util::authorization_header() - }); - return util::parse_body(res, update); - } - } - } -} \ No newline at end of file diff --git a/BigBaseV2/src/api/http_request.hpp b/BigBaseV2/src/api/http_request.hpp deleted file mode 100644 index 5cc702d6..00000000 --- a/BigBaseV2/src/api/http_request.hpp +++ /dev/null @@ -1,772 +0,0 @@ -// -// HTTPRequest -// - -#ifndef HTTPREQUEST_HPP -#define HTTPREQUEST_HPP -#pragma comment(lib, "ws2_32.lib") - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#ifdef _WIN32 -# pragma push_macro("WIN32_LEAN_AND_MEAN") -# pragma push_macro("NOMINMAX") -# ifndef WIN32_LEAN_AND_MEAN -# define WIN32_LEAN_AND_MEAN -# endif // WIN32_LEAN_AND_MEAN -# ifndef NOMINMAX -# define NOMINMAX -# endif // NOMINMAX -# include -# if _WIN32_WINNT < _WIN32_WINNT_WINXP -extern "C" char* _strdup(const char* strSource); -# define strdup _strdup -# include -# endif // _WIN32_WINNT < _WIN32_WINNT_WINXP -# include -# pragma pop_macro("WIN32_LEAN_AND_MEAN") -# pragma pop_macro("NOMINMAX") -#else -# include -# include -# include -# include -# include -# include -# include -#endif // _WIN32 - -namespace http -{ - class RequestError final : public std::logic_error - { - public: - explicit RequestError(const char* str) : std::logic_error{ str } {} - explicit RequestError(const std::string& str) : std::logic_error{ str } {} - }; - - class ResponseError final : public std::runtime_error - { - public: - explicit ResponseError(const char* str) : std::runtime_error{ str } {} - explicit ResponseError(const std::string& str) : std::runtime_error{ str } {} - }; - - enum class InternetProtocol : std::uint8_t - { - V4, - V6 - }; - - inline namespace detail - { -#ifdef _WIN32 - class WinSock final - { - public: - WinSock() - { - WSADATA wsaData; - const auto error = WSAStartup(MAKEWORD(2, 2), &wsaData); - if (error != 0) - throw std::system_error(error, std::system_category(), "WSAStartup failed"); - - if (LOBYTE(wsaData.wVersion) != 2 || HIBYTE(wsaData.wVersion) != 2) - { - WSACleanup(); - throw std::runtime_error("Invalid WinSock version"); - } - - started = true; - } - - ~WinSock() - { - if (started) WSACleanup(); - } - - WinSock(WinSock&& other) noexcept : - started{ other.started } - { - other.started = false; - } - - WinSock& operator=(WinSock&& other) noexcept - { - if (&other == this) return *this; - if (started) WSACleanup(); - started = other.started; - other.started = false; - return *this; - } - - private: - bool started = false; - }; -#endif // _WIN32 - - inline int getLastError() noexcept - { -#ifdef _WIN32 - return WSAGetLastError(); -#else - return errno; -#endif // _WIN32 - } - - constexpr int getAddressFamily(InternetProtocol internetProtocol) - { - return (internetProtocol == InternetProtocol::V4) ? AF_INET : - (internetProtocol == InternetProtocol::V6) ? AF_INET6 : - throw RequestError("Unsupported protocol"); - } - - class Socket final - { - public: -#ifdef _WIN32 - using Type = SOCKET; - static constexpr Type invalid = INVALID_SOCKET; -#else - using Type = int; - static constexpr Type invalid = -1; -#endif // _WIN32 - - explicit Socket(InternetProtocol internetProtocol) : - endpoint{ socket(getAddressFamily(internetProtocol), SOCK_STREAM, IPPROTO_TCP) } - { - if (endpoint == invalid) - throw std::system_error(getLastError(), std::system_category(), "Failed to create socket"); - -#ifdef _WIN32 - unsigned long mode = 1; - if (ioctlsocket(endpoint, FIONBIO, &mode) != 0) - { - close(); - throw std::system_error(WSAGetLastError(), std::system_category(), "Failed to get socket flags"); - } -#else - const auto flags = fcntl(endpoint, F_GETFL); - if (flags == -1) - { - close(); - throw std::system_error(errno, std::system_category(), "Failed to get socket flags"); - } - - if (fcntl(endpoint, F_SETFL, flags | O_NONBLOCK) == -1) - { - close(); - throw std::system_error(errno, std::system_category(), "Failed to set socket flags"); - } -#endif // _WIN32 - -#ifdef __APPLE__ - const int value = 1; - if (setsockopt(endpoint, SOL_SOCKET, SO_NOSIGPIPE, &value, sizeof(value)) == -1) - { - close(); - throw std::system_error(errno, std::system_category(), "Failed to set socket option"); - } -#endif // __APPLE__ - } - - ~Socket() - { - if (endpoint != invalid) close(); - } - - Socket(Socket&& other) noexcept : - endpoint{ other.endpoint } - { - other.endpoint = invalid; - } - - Socket& operator=(Socket&& other) noexcept - { - if (&other == this) return *this; - if (endpoint != invalid) close(); - endpoint = other.endpoint; - other.endpoint = invalid; - return *this; - } - - void connect(const struct sockaddr* address, const socklen_t addressSize, const std::int64_t timeout) - { -#ifdef _WIN32 - auto result = ::connect(endpoint, address, addressSize); - while (result == -1 && WSAGetLastError() == WSAEINTR) - result = ::connect(endpoint, address, addressSize); - - if (result == -1) - { - if (WSAGetLastError() == WSAEWOULDBLOCK) - { - select(SelectType::write, timeout); - - char socketErrorPointer[sizeof(int)]; - socklen_t optionLength = sizeof(socketErrorPointer); - if (getsockopt(endpoint, SOL_SOCKET, SO_ERROR, socketErrorPointer, &optionLength) == -1) - throw std::system_error(WSAGetLastError(), std::system_category(), "Failed to get socket option"); - - int socketError; - std::memcpy(&socketError, socketErrorPointer, sizeof(socketErrorPointer)); - - if (socketError != 0) - throw std::system_error(socketError, std::system_category(), "Failed to connect"); - } - else - throw std::system_error(WSAGetLastError(), std::system_category(), "Failed to connect"); - } -#else - auto result = ::connect(endpoint, address, addressSize); - while (result == -1 && errno == EINTR) - result = ::connect(endpoint, address, addressSize); - - if (result == -1) - { - if (errno == EINPROGRESS) - { - select(SelectType::write, timeout); - - int socketError; - socklen_t optionLength = sizeof(socketError); - if (getsockopt(endpoint, SOL_SOCKET, SO_ERROR, &socketError, &optionLength) == -1) - throw std::system_error(errno, std::system_category(), "Failed to get socket option"); - - if (socketError != 0) - throw std::system_error(socketError, std::system_category(), "Failed to connect"); - } - else - throw std::system_error(errno, std::system_category(), "Failed to connect"); - } -#endif // _WIN32 - } - - std::size_t send(const void* buffer, const std::size_t length, const std::int64_t timeout) - { - select(SelectType::write, timeout); -#ifdef _WIN32 - auto result = ::send(endpoint, reinterpret_cast(buffer), - static_cast(length), 0); - - while (result == -1 && WSAGetLastError() == WSAEINTR) - result = ::send(endpoint, reinterpret_cast(buffer), - static_cast(length), 0); - - if (result == -1) - throw std::system_error(WSAGetLastError(), std::system_category(), "Failed to send data"); -#else - auto result = ::send(endpoint, reinterpret_cast(buffer), - length, noSignal); - - while (result == -1 && errno == EINTR) - result = ::send(endpoint, reinterpret_cast(buffer), - length, noSignal); - - if (result == -1) - throw std::system_error(errno, std::system_category(), "Failed to send data"); -#endif // _WIN32 - return static_cast(result); - } - - std::size_t recv(void* buffer, const std::size_t length, const std::int64_t timeout) - { - select(SelectType::read, timeout); -#ifdef _WIN32 - auto result = ::recv(endpoint, reinterpret_cast(buffer), - static_cast(length), 0); - - while (result == -1 && WSAGetLastError() == WSAEINTR) - result = ::recv(endpoint, reinterpret_cast(buffer), - static_cast(length), 0); - - if (result == -1) - throw std::system_error(WSAGetLastError(), std::system_category(), "Failed to read data"); -#else - auto result = ::recv(endpoint, reinterpret_cast(buffer), - length, noSignal); - - while (result == -1 && errno == EINTR) - result = ::recv(endpoint, reinterpret_cast(buffer), - length, noSignal); - - if (result == -1) - throw std::system_error(errno, std::system_category(), "Failed to read data"); -#endif // _WIN32 - return static_cast(result); - } - - operator Type() const noexcept { return endpoint; } - - private: - enum class SelectType - { - read, - write - }; - - void select(const SelectType type, const std::int64_t timeout) - { - fd_set descriptorSet; - FD_ZERO(&descriptorSet); - FD_SET(endpoint, &descriptorSet); - - timeval selectTimeout{ - static_cast(timeout / 1000), - static_cast((timeout % 1000) * 1000) - }; -#ifdef _WIN32 - auto count = ::select(0, - (type == SelectType::read) ? &descriptorSet : nullptr, - (type == SelectType::write) ? &descriptorSet : nullptr, - nullptr, - (timeout >= 0) ? &selectTimeout : nullptr); - - while (count == -1 && WSAGetLastError() == WSAEINTR) - count = ::select(0, - (type == SelectType::read) ? &descriptorSet : nullptr, - (type == SelectType::write) ? &descriptorSet : nullptr, - nullptr, - (timeout >= 0) ? &selectTimeout : nullptr); - - if (count == -1) - throw std::system_error(WSAGetLastError(), std::system_category(), "Failed to select socket"); - else if (count == 0) - throw ResponseError("Request timed out"); -#else - auto count = ::select(endpoint + 1, - (type == SelectType::read) ? &descriptorSet : nullptr, - (type == SelectType::write) ? &descriptorSet : nullptr, - nullptr, - (timeout >= 0) ? &selectTimeout : nullptr); - - while (count == -1 && errno == EINTR) - count = ::select(endpoint + 1, - (type == SelectType::read) ? &descriptorSet : nullptr, - (type == SelectType::write) ? &descriptorSet : nullptr, - nullptr, - (timeout >= 0) ? &selectTimeout : nullptr); - - if (count == -1) - throw std::system_error(errno, std::system_category(), "Failed to select socket"); - else if (count == 0) - throw ResponseError("Request timed out"); -#endif // _WIN32 - } - - void close() noexcept - { -#ifdef _WIN32 - closesocket(endpoint); -#else - ::close(endpoint); -#endif // _WIN32 - } - -#if defined(__unix__) && !defined(__APPLE__) - static constexpr int noSignal = MSG_NOSIGNAL; -#else - static constexpr int noSignal = 0; -#endif // defined(__unix__) && !defined(__APPLE__) - - Type endpoint = invalid; - }; - } - - struct Response final - { - enum Status - { - Continue = 100, - SwitchingProtocol = 101, - Processing = 102, - EarlyHints = 103, - - Ok = 200, - Created = 201, - Accepted = 202, - NonAuthoritativeInformation = 203, - NoContent = 204, - ResetContent = 205, - PartialContent = 206, - MultiStatus = 207, - AlreadyReported = 208, - ImUsed = 226, - - MultipleChoice = 300, - MovedPermanently = 301, - Found = 302, - SeeOther = 303, - NotModified = 304, - UseProxy = 305, - TemporaryRedirect = 307, - PermanentRedirect = 308, - - BadRequest = 400, - Unauthorized = 401, - PaymentRequired = 402, - Forbidden = 403, - NotFound = 404, - MethodNotAllowed = 405, - NotAcceptable = 406, - ProxyAuthenticationRequired = 407, - RequestTimeout = 408, - Conflict = 409, - Gone = 410, - LengthRequired = 411, - PreconditionFailed = 412, - PayloadTooLarge = 413, - UriTooLong = 414, - UnsupportedMediaType = 415, - RangeNotSatisfiable = 416, - ExpectationFailed = 417, - MisdirectedRequest = 421, - UnprocessableEntity = 422, - Locked = 423, - FailedDependency = 424, - TooEarly = 425, - UpgradeRequired = 426, - PreconditionRequired = 428, - TooManyRequests = 429, - RequestHeaderFieldsTooLarge = 431, - UnavailableForLegalReasons = 451, - - InternalServerError = 500, - NotImplemented = 501, - BadGateway = 502, - ServiceUnavailable = 503, - GatewayTimeout = 504, - HttpVersionNotSupported = 505, - VariantAlsoNegotiates = 506, - InsufficientStorage = 507, - LoopDetected = 508, - NotExtended = 510, - NetworkAuthenticationRequired = 511 - }; - - int status = 0; - std::string description; - std::vector headers; - std::vector body; - }; - - class Request final - { - public: - explicit Request(const std::string& url, - const InternetProtocol protocol = InternetProtocol::V4) : - internetProtocol{ protocol } - { - const auto schemeEndPosition = url.find("://"); - - if (schemeEndPosition != std::string::npos) - { - scheme = url.substr(0, schemeEndPosition); - path = url.substr(schemeEndPosition + 3); - } - else - { - scheme = "http"; - path = url; - } - - const auto fragmentPosition = path.find('#'); - - // remove the fragment part - if (fragmentPosition != std::string::npos) - path.resize(fragmentPosition); - - const auto pathPosition = path.find('/'); - - if (pathPosition == std::string::npos) - { - domain = path; - path = "/"; - } - else - { - domain = path.substr(0, pathPosition); - path = path.substr(pathPosition); - } - - const auto portPosition = domain.find(':'); - - if (portPosition != std::string::npos) - { - port = domain.substr(portPosition + 1); - domain.resize(portPosition); - } - else - port = "80"; - } - - Response send(const std::string& method = "GET", - const std::string& body = "", - const std::vector& headers = {}, - const std::chrono::milliseconds timeout = std::chrono::milliseconds{ -1 }) - { - return send(method, - std::vector(body.begin(), body.end()), - headers, - timeout); - } - - Response send(const std::string& method, - const std::vector& body, - const std::vector& headers, - const std::chrono::milliseconds timeout = std::chrono::milliseconds{ -1 }) - { - const auto stopTime = std::chrono::steady_clock::now() + timeout; - - if (scheme != "http") - throw RequestError("Only HTTP scheme is supported"); - - addrinfo hints = {}; - hints.ai_family = getAddressFamily(internetProtocol); - hints.ai_socktype = SOCK_STREAM; - - addrinfo* info; - if (getaddrinfo(domain.c_str(), port.c_str(), &hints, &info) != 0) - throw std::system_error(getLastError(), std::system_category(), "Failed to get address info of " + domain); - - std::unique_ptr addressInfo(info, freeaddrinfo); - - // RFC 7230, 3.1.1. Request Line - std::string headerData = method + " " + path + " HTTP/1.1\r\n"; - - for (const auto& header : headers) - headerData += header + "\r\n"; - - // RFC 7230, 3.2. Header Fields - headerData += "Host: " + domain + "\r\n" - "Content-Length: " + std::to_string(body.size()) + "\r\n" - "\r\n"; - - std::vector requestData(headerData.begin(), headerData.end()); - requestData.insert(requestData.end(), body.begin(), body.end()); - - Socket socket(internetProtocol); - - // take the first address from the list - socket.connect(addressInfo->ai_addr, static_cast(addressInfo->ai_addrlen), - (timeout.count() >= 0) ? getRemainingMilliseconds(stopTime) : -1); - - auto remaining = requestData.size(); - auto sendData = requestData.data(); - - // send the request - while (remaining > 0) - { - const auto size = socket.send(sendData, remaining, - (timeout.count() >= 0) ? getRemainingMilliseconds(stopTime) : -1); - remaining -= size; - sendData += size; - } - - std::array tempBuffer; - constexpr std::array crlf = { '\r', '\n' }; - Response response; - std::vector responseData; - enum class State - { - statusLine, - headers, - body - } state = State::statusLine; - bool contentLengthReceived = false; - std::size_t contentLength = 0; - bool chunkedResponse = false; - std::size_t expectedChunkSize = 0; - bool removeCrlfAfterChunk = false; - - // read the response - for (;;) - { - const auto size = socket.recv(tempBuffer.data(), tempBuffer.size(), - (timeout.count() >= 0) ? getRemainingMilliseconds(stopTime) : -1); - - if (size == 0) - { - // download complete - return response; - } - else if (size < 0) - { - throw ResponseError("Socket error"); - } - - responseData.insert(responseData.end(), tempBuffer.begin(), tempBuffer.begin() + size); - - if (state != State::body) - for (;;) - { - // RFC 7230, 3. Message Format - const auto i = std::search(responseData.begin(), responseData.end(), crlf.begin(), crlf.end()); - - // didn't find a newline - if (i == responseData.end()) break; - - const std::string line(responseData.begin(), i); - responseData.erase(responseData.begin(), i + 2); - - // empty line indicates the end of the header section - if (line.empty()) - { - state = State::body; - break; - } - else if (state == State::statusLine) // RFC 7230, 3.1.2. Status Line - { - state = State::headers; - std::size_t partNum = 0; - - // tokenize the status line - for (auto beginIterator = line.begin(); beginIterator != line.end();) - { - const auto endIterator = std::find(beginIterator, line.end(), ' '); - const std::string part{ beginIterator, endIterator }; - - switch (++partNum) - { - case 2: response.status = std::stoi(part); break; - case 3: response.description = part; break; - } - - if (endIterator == line.end()) break; - beginIterator = endIterator + 1; - } - } - else if (state == State::headers) // RFC 7230, 3.2. Header Fields - { - response.headers.push_back(line); - - const auto loumnPosition = line.find(':'); - - if (loumnPosition == std::string::npos) - throw ResponseError("Invalid header: " + line); - - const auto headerName = line.substr(0, loumnPosition); - auto headerValue = line.substr(loumnPosition + 1); - - // RFC 7230, Appendix B. Collected ABNF - auto isNotWhiteSpace = [](char c) { - return c != ' ' && c != '\t'; - }; - - // ltrim - headerValue.erase(headerValue.begin(), std::find_if(headerValue.begin(), headerValue.end(), isNotWhiteSpace)); - - // rtrim - headerValue.erase(std::find_if(headerValue.rbegin(), headerValue.rend(), isNotWhiteSpace).base(), headerValue.end()); - - if (headerName == "Content-Length") - { - contentLength = std::stoul(headerValue); - contentLengthReceived = true; - response.body.reserve(contentLength); - } - else if (headerName == "Transfer-Encoding") - { - if (headerValue == "chunked") - chunkedResponse = true; - else - throw ResponseError("Unsupported transfer encoding: " + headerValue); - } - } - } - - if (state == State::body) - { - if (method == "HEAD") // Body must be ignored for HEAD requests - { - return response; - } - else if (chunkedResponse) // Content-Length must be ignored if Transfer-Encoding is received - { - for (;;) - { - if (expectedChunkSize > 0) - { - const auto toWrite = (std::min)(expectedChunkSize, responseData.size()); - response.body.insert(response.body.end(), responseData.begin(), responseData.begin() + static_cast(toWrite)); - responseData.erase(responseData.begin(), responseData.begin() + static_cast(toWrite)); - expectedChunkSize -= toWrite; - - if (expectedChunkSize == 0) removeCrlfAfterChunk = true; - if (responseData.empty()) break; - } - else - { - if (removeCrlfAfterChunk) - { - if (responseData.size() < 2) break; - - if (!std::equal(crlf.begin(), crlf.end(), responseData.begin())) - throw ResponseError("Invalid chunk"); - - removeCrlfAfterChunk = false; - responseData.erase(responseData.begin(), responseData.begin() + 2); - } - - const auto i = std::search(responseData.begin(), responseData.end(), crlf.begin(), crlf.end()); - - if (i == responseData.end()) break; - - const std::string line(responseData.begin(), i); - responseData.erase(responseData.begin(), i + 2); - - expectedChunkSize = std::stoul(line, nullptr, 16); - if (expectedChunkSize == 0) - return response; - } - } - } - else - { - response.body.insert(response.body.end(), responseData.begin(), responseData.end()); - responseData.clear(); - - // got the whole content - if (contentLengthReceived && response.body.size() >= contentLength) - return response; - } - } - } - - return response; - } - - private: - static std::int64_t getRemainingMilliseconds(const std::chrono::steady_clock::time_point time) - { - const auto now = std::chrono::steady_clock::now(); - const auto remainingTime = std::chrono::duration_cast(time - now); - return (remainingTime.count() > 0) ? remainingTime.count() : 0; - } - -#ifdef _WIN32 - WinSock winSock; -#endif // _WIN32 - InternetProtocol internetProtocol; - std::string scheme; - std::string domain; - std::string port; - std::string path; - }; -} - -#endif // HTTPREQUEST_HPP \ No newline at end of file diff --git a/BigBaseV2/src/api/remote.hpp b/BigBaseV2/src/api/remote.hpp deleted file mode 100644 index 053ee6c9..00000000 --- a/BigBaseV2/src/api/remote.hpp +++ /dev/null @@ -1,92 +0,0 @@ -#pragma once -#include "api/http_request.hpp" - -namespace big::remote -{ - inline std::string get_etag_from_headers(std::vector headers) - { - std::string remote_etag = ""; - - for (auto& header : headers) - { - if (header.rfind("ETag", 0) == 0) - { - remote_etag = header; - break; - } - } - - return remote_etag; - } - - - inline bool update_binary(const std::string_view file_url, const std::filesystem::path& file_location, const std::filesystem::path& etag_location) - { - std::string local_etag = ""; - std::string remote_etag = ""; - - try { - - { - std::ifstream file_etag_ifstream(etag_location, std::ios::binary); - std::stringstream file_etag_stringstream; - file_etag_stringstream << file_etag_ifstream.rdbuf(); - local_etag = file_etag_stringstream.str(); - } - - if (!local_etag.empty()) - { - http::Request req(file_url.data()); - http::Response res = req.send("HEAD", "", {}, 20s); - - if (res.status == http::Response::Status::Ok) - { - remote_etag = get_etag_from_headers(res.headers); - - if (remote_etag == local_etag) - { - return true; - } - } - else - { - throw std::exception(std::to_string(res.status).c_str()); - } - } - } - catch (const std::exception& e) - { - LOG(WARNING) << "Update Error (HEAD): " << e.what(); - } - - try - { - http::Request req(file_url.data()); - http::Response res = req.send("GET", "", {}, 20s); - - if (res.status == http::Response::Status::Ok) - { - std::ofstream file_ofstream(file_location, std::ios::binary | std::ios::trunc); - std::ostream_iterator file_out_iter(file_ofstream); - std::copy(res.body.begin(), res.body.end(), file_out_iter); - - remote_etag = get_etag_from_headers(res.headers); - - std::ofstream file_etag_ofstream(etag_location, std::ios::binary | std::ios::trunc); - file_etag_ofstream << remote_etag; - - return true; - } - else - { - throw std::exception(std::to_string(res.status).c_str()); - } - } - catch (const std::exception& e) - { - LOG(WARNING) << "Update Error (GET): " << e.what(); - } - - return false; - } -} \ No newline at end of file diff --git a/BigBaseV2/src/backend/backend.cpp b/BigBaseV2/src/backend/backend.cpp index 8a7c9bdd..afc6e62b 100644 --- a/BigBaseV2/src/backend/backend.cpp +++ b/BigBaseV2/src/backend/backend.cpp @@ -1,7 +1,6 @@ #include "backend.hpp" #include "script.hpp" #include "thread_pool.hpp" -#include "api/api.hpp" #include "looped/looped.hpp" #include "services/context_menu/context_menu_service.hpp" @@ -15,13 +14,6 @@ namespace big looped::system_update_pointers(); looped::system_desync_kick_protection(); - if (g_local_player != nullptr && !api::util::signed_in()) - { - g_thread_pool->push([] - { - looped::api_login_session(); - }); - } script::get_current()->yield(); } } diff --git a/BigBaseV2/src/backend/looped/api/login_session.cpp b/BigBaseV2/src/backend/looped/api/login_session.cpp deleted file mode 100644 index d799975f..00000000 --- a/BigBaseV2/src/backend/looped/api/login_session.cpp +++ /dev/null @@ -1,13 +0,0 @@ -#include "api/api.hpp" -#include "backend/looped/looped.hpp" - -namespace big -{ - void looped::api_login_session() - { - if (g_local_player == nullptr || api::util::signed_in()) - return; - - api::auth::create_session(); - } -} \ No newline at end of file diff --git a/BigBaseV2/src/gta_util.hpp b/BigBaseV2/src/gta_util.hpp index f5a7fc5a..ec96c64b 100644 --- a/BigBaseV2/src/gta_util.hpp +++ b/BigBaseV2/src/gta_util.hpp @@ -17,6 +17,18 @@ namespace big::gta_util return nullptr; } + inline CVehicle* get_local_vehicle() + { + if (const auto ped = get_local_ped(); ped) + { + if (const auto veh = ped->m_vehicle; veh) + { + return veh; + } + } + return nullptr; + } + inline CPlayerInfo *get_local_playerinfo() { if (auto ped_factory = *g_pointers->m_ped_factory) diff --git a/BigBaseV2/src/gui/handling/current_profile/current_profile_general.cpp b/BigBaseV2/src/gui/handling/current_profile/current_profile_general.cpp index b8f2b7aa..3aa5c95f 100644 --- a/BigBaseV2/src/gui/handling/current_profile/current_profile_general.cpp +++ b/BigBaseV2/src/gui/handling/current_profile/current_profile_general.cpp @@ -13,10 +13,12 @@ namespace big ImGui::SliderFloat("##Mass", &g_local_player->m_vehicle->m_handling_data->m_mass, 0.f, 50000.f); ImGui::Text("Centre of mass"); - float fCenterOfMass[3]; - fCenterOfMass[0] = g_local_player->m_vehicle->m_handling_data->m_centre_of_mass.x; - fCenterOfMass[1] = g_local_player->m_vehicle->m_handling_data->m_centre_of_mass.y; - fCenterOfMass[2] = g_local_player->m_vehicle->m_handling_data->m_centre_of_mass.z; + float fCenterOfMass[3] + { + g_local_player->m_vehicle->m_handling_data->m_centre_of_mass.x, + g_local_player->m_vehicle->m_handling_data->m_centre_of_mass.y, + g_local_player->m_vehicle->m_handling_data->m_centre_of_mass.z + }; if (ImGui::SliderFloat3("##centre_of_mass", fCenterOfMass, -10.f, 10.f)) { g_local_player->m_vehicle->m_handling_data->m_centre_of_mass.x = fCenterOfMass[0]; diff --git a/BigBaseV2/src/gui/handling/current_profile/current_profile_tabs.hpp b/BigBaseV2/src/gui/handling/current_profile/current_profile_tabs.hpp index f8b6e0c5..cb926c3d 100644 --- a/BigBaseV2/src/gui/handling/current_profile/current_profile_tabs.hpp +++ b/BigBaseV2/src/gui/handling/current_profile/current_profile_tabs.hpp @@ -21,6 +21,5 @@ namespace big namespace modal_handling { void modal_save_handling(); - void modal_update_handling(); } } \ No newline at end of file diff --git a/BigBaseV2/src/gui/handling/handling_current_profile.cpp b/BigBaseV2/src/gui/handling/handling_current_profile.cpp index bcd43441..9cd98c47 100644 --- a/BigBaseV2/src/gui/handling/handling_current_profile.cpp +++ b/BigBaseV2/src/gui/handling/handling_current_profile.cpp @@ -1,5 +1,5 @@ #include "current_profile/current_profile_tabs.hpp" -#include "services/vehicle/vehicle_service.hpp" +#include "services/vehicle/handling_service.hpp" #include "views/view.hpp" namespace big @@ -11,27 +11,17 @@ namespace big ImGui::Text("Please enter a vehicle."); return; } + g_handling_service->backup_vehicle(); - if (g_vehicle_service->get_active_profile(g_local_player->m_vehicle->m_handling_data->m_model_hash).empty()) + if (components::button("Save Profile")) { - if (components::button("Save Profile")) - { - ImGui::OpenPopup("Save Handling"); - } - } - else - { - if (components::button("Update Profile")) - { - ImGui::OpenPopup("Update Handling"); - } + ImGui::OpenPopup("Save Handling"); } modal_handling::modal_save_handling(); - modal_handling::modal_update_handling(); ImGui::SameLine(); if (components::button("Restore Handling")) - g_vehicle_service->restore_vehicle(); + g_handling_service->restore_vehicle(); ImGui::Separator(); diff --git a/BigBaseV2/src/gui/handling/handling_my_profiles.cpp b/BigBaseV2/src/gui/handling/handling_my_profiles.cpp deleted file mode 100644 index 3d921c7e..00000000 --- a/BigBaseV2/src/gui/handling/handling_my_profiles.cpp +++ /dev/null @@ -1,58 +0,0 @@ -#include "services/vehicle/vehicle_service.hpp" -#include "views/view.hpp" - -namespace big -{ - void view::handling_my_profiles() - { - if (g_local_player == nullptr || g_local_player->m_vehicle == nullptr || g_local_player->m_ped_task_flag & (int)ePedTask::TASK_FOOT) - { - ImGui::Text("Please enter a vehicle."); - return; - } - - if (!g_vehicle_service->update_mine()) - ImGui::Text("Loading profiles..."); - else - { - if (g_vehicle_service->m_my_profiles.size() == 0) - ImGui::Text("You have no profiles available for this vehicle."); - for (auto& key : g_vehicle_service->m_my_profiles) - { - if (auto it = g_vehicle_service->m_handling_profiles.find(key); it != g_vehicle_service->m_handling_profiles.end()) - { - auto& profile = it->second; - - if (profile.share_code == g_vehicle_service->get_active_profile(profile.handling_hash)) - ImGui::TextColored({ 0.1254f,0.8039f,0.3137f,1.f }, "Active"); - - ImGui::BeginTable("table", 3, ImGuiTableFlags_SizingStretchProp); - - ImGui::TableNextRow(); - - ImGui::TableNextColumn(); - ImGui::Text("Name:"); - ImGui::TableNextColumn(); - ImGui::Text(profile.name.c_str()); - ImGui::TableNextColumn(); - ImGui::Text("Share Code: %s", profile.share_code.c_str()); - - ImGui::TableNextRow(); - - ImGui::TableNextColumn(); - ImGui::Text("Description:"); - ImGui::TableNextColumn(); - ImGui::TextWrapped(profile.description.c_str()); - ImGui::TableNextColumn(); - if (components::button("Load Profile")) - g_vehicle_service->set_handling_profile(profile); - - ImGui::EndTable(); - - ImGui::Separator(); - } - } - } - - } -} diff --git a/BigBaseV2/src/gui/handling/handling_saved_profiles.cpp b/BigBaseV2/src/gui/handling/handling_saved_profiles.cpp index 831672da..6dc29906 100644 --- a/BigBaseV2/src/gui/handling/handling_saved_profiles.cpp +++ b/BigBaseV2/src/gui/handling/handling_saved_profiles.cpp @@ -1,4 +1,4 @@ -#include "services/vehicle/vehicle_service.hpp" +#include "services/vehicle/handling_service.hpp" #include "views/view.hpp" namespace big @@ -10,48 +10,24 @@ namespace big ImGui::Text("Please enter a vehicle."); return; } + g_handling_service->backup_vehicle(); - if (!g_vehicle_service->load_saved_profiles()) - ImGui::Text("Loading profiles..."); - else + if (components::button("Reload Profiles")) { - if (g_vehicle_service->m_saved_profiles.size() == 0) - ImGui::Text("You have no saved profiles available for this vehicle."); - for (auto& key : g_vehicle_service->m_saved_profiles) + g_handling_service->load_files(); + } + + + if (ImGui::ListBoxHeader("##handling_profiles")) + { + for (const auto& [name, profile] : g_handling_service->profiles()) { - if (auto it = g_vehicle_service->m_handling_profiles.find(key); it != g_vehicle_service->m_handling_profiles.end()) + if (components::selectable(name, profile.get() == g_handling_service->active_profile())) { - auto& profile = it->second; - - if (profile.share_code == g_vehicle_service->get_active_profile(profile.handling_hash)) - ImGui::TextColored({ 0.1254f,0.8039f,0.3137f,1.f }, "Active"); - - ImGui::BeginTable("table", 3, ImGuiTableFlags_SizingStretchProp); - - ImGui::TableNextRow(); - - ImGui::TableNextColumn(); - ImGui::Text("Name:"); - ImGui::TableNextColumn(); - ImGui::Text(profile.name.c_str()); - ImGui::TableNextColumn(); - ImGui::Text("Share Code: %s", profile.share_code.c_str()); - - ImGui::TableNextRow(); - - ImGui::TableNextColumn(); - ImGui::Text("Description:"); - ImGui::TableNextColumn(); - ImGui::TextWrapped(profile.description.c_str()); - ImGui::TableNextColumn(); - if (components::button("Load Profile")) - g_vehicle_service->set_handling_profile(profile); - - ImGui::EndTable(); - - ImGui::Separator(); + g_handling_service->apply_profile(profile.get()); } } + ImGui::EndListBox(); } } } diff --git a/BigBaseV2/src/gui/handling/handling_search.cpp b/BigBaseV2/src/gui/handling/handling_search.cpp deleted file mode 100644 index 5119fc93..00000000 --- a/BigBaseV2/src/gui/handling/handling_search.cpp +++ /dev/null @@ -1,87 +0,0 @@ -#include "api/api.hpp" -#include "fiber_pool.hpp" -#include "natives.hpp" -#include "script.hpp" -#include "thread_pool.hpp" -#include "services/vehicle/vehicle_service.hpp" -#include "views/view.hpp" - -namespace big -{ - void view::handling_search() - { - if (g_local_player == nullptr || g_local_player->m_vehicle == nullptr || g_local_player->m_ped_task_flag & (int)ePedTask::TASK_FOOT) - { - ImGui::Text("Please enter a vehicle."); - return; - } - - static char search[13]; - components::input_text_with_hint("##search_share_code", "Search by share code", search, sizeof(search), ImGuiInputTextFlags_EnterReturnsTrue, [] - { - g_thread_pool->push([&] { g_vehicle_service->get_by_share_code(search); }); - }); - ImGui::SameLine(); - if (components::button("Search")) - g_thread_pool->push([&] { g_vehicle_service->get_by_share_code(search); }); - - switch (g_vehicle_service->m_search_status) - { - case SearchStatus::SEARCHING: - ImGui::Text("Searching..."); - - break; - case SearchStatus::NO_RESULT: - ImGui::Text("No results found for %s", search); - - break; - case SearchStatus::FAILED: - ImGui::Text("Search failed, host is down or response body is invalid..."); - - break; - case SearchStatus::FOUND: - if (auto it = g_vehicle_service->m_handling_profiles.find(search); it != g_vehicle_service->m_handling_profiles.end()) - { - auto& profile = it->second; - - if (profile.share_code == g_vehicle_service->get_active_profile(profile.handling_hash)) - ImGui::TextColored({ 0.1254f,0.8039f,0.3137f,1.f }, "Active"); - - ImGui::BeginTable("table", 3, ImGuiTableFlags_SizingStretchProp); - - ImGui::TableNextRow(); - - ImGui::TableNextColumn(); - ImGui::Text("Name:"); - ImGui::TableNextColumn(); - ImGui::Text(profile.name.c_str()); - ImGui::TableNextColumn(); - ImGui::Text("Share Code: %s", profile.share_code.c_str()); - - ImGui::TableNextRow(); - - ImGui::TableNextColumn(); - ImGui::Text("Description:"); - ImGui::TableNextColumn(); - ImGui::TextWrapped(profile.description.c_str()); - ImGui::TableNextColumn(); - if (components::button("Load Profile")) - g_vehicle_service->set_handling_profile(profile); - ImGui::SameLine(); - if (components::button("Save Profile")) - { - g_thread_pool->push([&] - { - api::vehicle::handling::save_profile(profile.share_code); - - g_vehicle_service->load_saved_profiles(true); - }); - } - - ImGui::EndTable(); - } - - break; - } - } -} diff --git a/BigBaseV2/src/gui/handling/modals/save_handling.cpp b/BigBaseV2/src/gui/handling/modals/save_handling.cpp index e621ba5f..f6a952f2 100644 --- a/BigBaseV2/src/gui/handling/modals/save_handling.cpp +++ b/BigBaseV2/src/gui/handling/modals/save_handling.cpp @@ -1,9 +1,8 @@ #include "../current_profile/current_profile_tabs.hpp" #include "fiber_pool.hpp" #include "thread_pool.hpp" -#include "natives.hpp" #include "script.hpp" -#include "services/vehicle/vehicle_service.hpp" +#include "services/vehicle/handling_service.hpp" #include "views/view.hpp" namespace big @@ -13,53 +12,13 @@ namespace big ImGui::SetNextWindowSize({ 520, 325 }, ImGuiCond_FirstUseEver); if (ImGui::BeginPopupModal("Save Handling")) { - static char name[32], description[256] = "No description."; + static char name[32]; - switch (g_vehicle_service->publish_status()) - { - case PublishStatus::SAVING: - ImGui::Text("Saving..."); - - return ImGui::EndPopup(); - case PublishStatus::SAVED: - strcpy(name, ""); - strcpy(description, "No description."); - - g_vehicle_service->publish_status(PublishStatus::IDLE); - g_vehicle_service->update_mine(true); - - ImGui::CloseCurrentPopup(); - - return ImGui::EndPopup(); - case PublishStatus::FAILED: - ImGui::TextColored({ 255, 0, 0, 1 }, "Failed to save handling profile."); - - ImGui::Separator(); - } - - QUEUE_JOB_BEGIN_CLAUSE() - { - PAD::DISABLE_ALL_CONTROL_ACTIONS(0); - }QUEUE_JOB_END_CLAUSE - - ImGui::BeginGroup(); - - ImGui::Text("Name:"); - ImGui::Text("Description:"); - - ImGui::EndGroup(); - ImGui::SameLine(); - ImGui::BeginGroup(); - - ImGui::InputText("##modal_handling_name", name, sizeof(name)); - ImGui::InputTextMultiline("##modal_handling_description", description, sizeof(description)); - - ImGui::EndGroup(); + components::input_text_with_hint("Name", "Name", name, sizeof(name)); if (components::button("Cancel")) { strcpy(name, ""); - strcpy(description, "No description."); ImGui::CloseCurrentPopup(); } @@ -68,8 +27,9 @@ namespace big { g_thread_pool->push([&] { - g_vehicle_service->publish_profile(name, description); + g_handling_service->save_profile(name); }); + ImGui::CloseCurrentPopup(); } ImGui::EndPopup(); diff --git a/BigBaseV2/src/gui/handling/modals/update_handling.cpp b/BigBaseV2/src/gui/handling/modals/update_handling.cpp deleted file mode 100644 index 1be9b35c..00000000 --- a/BigBaseV2/src/gui/handling/modals/update_handling.cpp +++ /dev/null @@ -1,93 +0,0 @@ -#include "../current_profile/current_profile_tabs.hpp" -#include "fiber_pool.hpp" -#include "thread_pool.hpp" -#include "natives.hpp" -#include "script.hpp" -#include "services/vehicle/vehicle_service.hpp" -#include "views/view.hpp" - -namespace big -{ - void modal_handling::modal_update_handling() - { - ImGui::SetNextWindowSize({ 520, 325 }, ImGuiCond_FirstUseEver); - if (ImGui::BeginPopupModal("Update Handling")) - { - auto share_code = g_vehicle_service->get_active_profile(g_local_player->m_vehicle->m_handling_data->m_model_hash); - if (share_code.empty()) - { - // should be impossible to trigger but still - - return ImGui::EndPopup(); - } - auto it = g_vehicle_service->m_handling_profiles.find(share_code); - if (it == g_vehicle_service->m_handling_profiles.end()) - return ImGui::EndPopup(); - auto profile = it->second; - - static char name[32], description[256] = "No description."; - - strcpy(name, profile.name.c_str()); - strcpy(description, profile.description.c_str()); - - switch (g_vehicle_service->publish_status()) - { - case PublishStatus::SAVING: - ImGui::Text("Saving..."); - - return ImGui::EndPopup(); - case PublishStatus::SAVED: - strcpy(name, ""); - strcpy(description, "No description."); - - g_vehicle_service->publish_status(PublishStatus::IDLE); - g_vehicle_service->update_mine(true); - - ImGui::CloseCurrentPopup(); - - return ImGui::EndPopup(); - case PublishStatus::FAILED: - ImGui::TextColored({ 255, 0, 0, 1 }, "Failed to update handling profile."); - - ImGui::Separator(); - } - - QUEUE_JOB_BEGIN_CLAUSE() - { - PAD::DISABLE_ALL_CONTROL_ACTIONS(0); - }QUEUE_JOB_END_CLAUSE - - ImGui::BeginGroup(); - - ImGui::Text("Name:"); - ImGui::Text("Description:"); - - ImGui::EndGroup(); - ImGui::SameLine(); - ImGui::BeginGroup(); - - ImGui::InputText("##modal_handling_name", name, sizeof(name)); - ImGui::InputTextMultiline("##modal_handling_description", description, sizeof(description)); - - ImGui::EndGroup(); - - if (components::button("Cancel")) - { - strcpy(name, ""); - strcpy(description, "No description."); - - ImGui::CloseCurrentPopup(); - } - ImGui::SameLine(); - if (components::button("Update")) - { - g_thread_pool->push([&] - { - g_vehicle_service->publish_profile(name, description, profile.share_code); - }); - } - - ImGui::EndPopup(); - } - } -} \ No newline at end of file diff --git a/BigBaseV2/src/main.cpp b/BigBaseV2/src/main.cpp index bfbd2034..28cfcc0c 100644 --- a/BigBaseV2/src/main.cpp +++ b/BigBaseV2/src/main.cpp @@ -21,7 +21,7 @@ #include "services/players/player_service.hpp" #include "services/notifications/notification_service.hpp" #include "services/model_preview/model_preview_service.hpp" -#include "services/vehicle/vehicle_service.hpp" +#include "services/vehicle/handling_service.hpp" BOOL APIENTRY DllMain(HMODULE hmod, DWORD reason, PVOID) { @@ -82,7 +82,7 @@ BOOL APIENTRY DllMain(HMODULE hmod, DWORD reason, PVOID) auto player_service_instance = std::make_unique(); auto gta_data_service_instance = std::make_unique(); auto model_preview_service_instance = std::make_unique(); - auto vehicle_service_instance = std::make_unique(); + auto handling_service_instance = std::make_unique(); auto gui_service_instance = std::make_unique(); LOG(INFO) << "Registered service instances..."; @@ -135,7 +135,7 @@ BOOL APIENTRY DllMain(HMODULE hmod, DWORD reason, PVOID) LOG(INFO) << "Gui Service reset."; gta_data_service_instance.reset(); LOG(INFO) << "GTA Data Service reset."; - vehicle_service_instance.reset(); + handling_service_instance.reset(); LOG(INFO) << "Vehicle Service reset."; model_preview_service_instance.reset(); LOG(INFO) << "Model Preview Service reset."; diff --git a/BigBaseV2/src/services/gui/gui_service.hpp b/BigBaseV2/src/services/gui/gui_service.hpp index 9e0fac6a..c41d2aad 100644 --- a/BigBaseV2/src/services/gui/gui_service.hpp +++ b/BigBaseV2/src/services/gui/gui_service.hpp @@ -63,9 +63,7 @@ namespace big {tabs::VEHICLE, { "Vehicle", view::vehicle, { { tabs::HANDLING, {"Handling", view::handling_current_profile, { { tabs::HANDLING_CURRENT_PROFILE, {"Current Profile", view::handling_current_profile } }, - { tabs::HANDLING_MY_PROFILES, {"My Profiles", view::handling_my_profiles } }, { tabs::HANDLING_SAVED_PROFILE, {"Saved Profiles", view::handling_saved_profiles } }, - { tabs::HANDLING_SEARCH, {"Search Handling", view::handling_search } }, }}}, { tabs::LSC, { "LS Customs", view::lsc }}, { tabs::SPAWN_VEHICLE, { "Spawn Vehicle", view::spawn_vehicle }}, diff --git a/BigBaseV2/src/services/vehicle/handling_profile.cpp b/BigBaseV2/src/services/vehicle/handling_profile.cpp new file mode 100644 index 00000000..399d28c1 --- /dev/null +++ b/BigBaseV2/src/services/vehicle/handling_profile.cpp @@ -0,0 +1,21 @@ +#include "handling_profile.hpp" + +namespace big +{ + handling_profile::handling_profile(CVehicle* vehicle) + { + m_gravity = vehicle->m_gravity; + m_handling_data = *vehicle->m_handling_data; + } + + void handling_profile::apply_to(CVehicle* vehicle, bool restore_hash) const + { + const auto hash = vehicle->m_handling_data->m_model_hash; + + vehicle->m_gravity = m_gravity; + *vehicle->m_handling_data = m_handling_data; + + if (restore_hash) + vehicle->m_handling_data->m_model_hash = hash; + } +} \ No newline at end of file diff --git a/BigBaseV2/src/services/vehicle/handling_profile.hpp b/BigBaseV2/src/services/vehicle/handling_profile.hpp new file mode 100644 index 00000000..196b72ef --- /dev/null +++ b/BigBaseV2/src/services/vehicle/handling_profile.hpp @@ -0,0 +1,19 @@ +#pragma once +#include "vehicle/CVehicle.hpp" + +namespace big +{ + class handling_profile final + { + public: + handling_profile(CVehicle* vehicle); + handling_profile() = default; + + void apply_to(CVehicle* vehicle, bool restore_hash = true) const; + + private: + float m_gravity; + CHandlingData m_handling_data; + + }; +} \ No newline at end of file diff --git a/BigBaseV2/src/services/vehicle/handling_service.cpp b/BigBaseV2/src/services/vehicle/handling_service.cpp new file mode 100644 index 00000000..332cbef1 --- /dev/null +++ b/BigBaseV2/src/services/vehicle/handling_service.cpp @@ -0,0 +1,108 @@ +#include "gta_util.hpp" +#include "handling_service.hpp" + +namespace big +{ + handling_service::handling_service() : + m_profiles_folder(g_file_manager->get_project_folder("./handling_profiles")) + { + g_handling_service = this; + + load_files(); + } + + handling_service::~handling_service() + { + g_handling_service = nullptr; + } + + std::size_t handling_service::load_files() + { + std::size_t files_loaded{}; + + for (const auto& item : std::filesystem::directory_iterator(m_profiles_folder.get_path())) + { + if (!item.is_regular_file()) + continue; + if (auto file_path = item.path(); file_path.extension() == ".bin") + { + auto profile = std::make_unique(); + auto profile_file = std::ifstream(file_path, std::ios::binary); + profile_file.read(reinterpret_cast(profile.get()), sizeof(handling_profile)); + profile_file.close(); + + m_handling_profiles.emplace(file_path.stem().string(), std::move(profile)); + + ++files_loaded; + } + } + + return files_loaded; + } + + handling_profiles& handling_service::profiles() + { + return m_handling_profiles; + } + + handling_profile* handling_service::active_profile() + { + return m_active_profile; + } + + void handling_service::apply_profile(handling_profile* profile) + { + if (const auto vehicle = gta_util::get_local_vehicle(); vehicle) + { + profile->apply_to(vehicle); + m_active_profile = profile; + } + } + + bool handling_service::save_profile(std::string name) + { + const auto vehicle = gta_util::get_local_vehicle(); + if (!vehicle) + return false; + + name += ".bin"; + const auto save = m_profiles_folder.get_file(name); + + auto profile = std::make_unique(vehicle); + + auto save_file = std::ofstream(save.get_path(), std::ios::binary); + save_file.write(reinterpret_cast(profile.get()), sizeof(handling_profile)); + save_file.close(); + + m_handling_profiles.emplace(name, std::move(profile)); + + return true; + } + + bool handling_service::backup_vehicle() + { + const auto vehicle = gta_util::get_local_vehicle(); + if (!vehicle) + return false; + + const auto hash = vehicle->m_handling_data->m_model_hash; + if (const auto& it = m_vehicle_backups.find(hash); it != m_vehicle_backups.end()) + return false; + + m_vehicle_backups.emplace(hash, std::make_unique(vehicle)); + + return true; + } + + void handling_service::restore_vehicle() const + { + const auto vehicle = gta_util::get_local_vehicle(); + if (!vehicle) + return; + + if (const auto& it = m_vehicle_backups.find(vehicle->m_handling_data->m_model_hash); it != m_vehicle_backups.end()) + { + it->second->apply_to(vehicle); + } + } +} \ No newline at end of file diff --git a/BigBaseV2/src/services/vehicle/handling_service.hpp b/BigBaseV2/src/services/vehicle/handling_service.hpp new file mode 100644 index 00000000..7862c9a7 --- /dev/null +++ b/BigBaseV2/src/services/vehicle/handling_service.hpp @@ -0,0 +1,40 @@ +#pragma once +#include "handling_profile.hpp" + +namespace big +{ + using handling_profiles = std::map>; + class handling_service final + { + public: + handling_service(); + ~handling_service(); + + handling_service(const handling_service&) = delete; + handling_service(handling_service&&) noexcept = delete; + handling_service& operator=(const handling_service&) = delete; + handling_service& operator=(handling_service&&) noexcept = delete; + + std::size_t load_files(); + handling_profiles& profiles(); + + handling_profile* active_profile(); + void apply_profile(handling_profile* profile); + bool save_profile(std::string name); + + bool backup_vehicle(); + void restore_vehicle() const; + + private: + const folder m_profiles_folder; + + handling_profile* m_active_profile; + handling_profiles m_handling_profiles; + + // contains the handling profiles of a vehicles before they're been modified + std::unordered_map> m_vehicle_backups; + + }; + + inline handling_service* g_handling_service{}; +} \ No newline at end of file diff --git a/BigBaseV2/src/services/vehicle/vehicle_service.cpp b/BigBaseV2/src/services/vehicle/vehicle_service.cpp deleted file mode 100644 index a7a452ae..00000000 --- a/BigBaseV2/src/services/vehicle/vehicle_service.cpp +++ /dev/null @@ -1,307 +0,0 @@ -#include "api/api.hpp" -#include "thread_pool.hpp" -#include "vehicle_service.hpp" - -namespace big -{ - bool safe_to_modify() - { - return !(g_local_player == nullptr || g_local_player->m_vehicle == nullptr); - } - - vehicle_service::vehicle_service() - { - g_vehicle_service = this; - } - - vehicle_service::~vehicle_service() - { - g_vehicle_service = nullptr; - } - - int vehicle_service::attempt_save() - { - if (g_local_player == nullptr || g_local_player->m_ped_task_flag & (int)ePedTask::TASK_FOOT || g_local_player->m_vehicle == nullptr) - return -1; - if (m_handling_backup.find(g_local_player->m_vehicle->m_handling_data->m_model_hash) != m_handling_backup.end()) - return 0; - - CHandlingData handling = *g_local_player->m_vehicle->m_handling_data; - - m_handling_backup.emplace(g_local_player->m_vehicle->m_handling_data->m_model_hash, handling); - - return 1; - } - - std::string vehicle_service::get_active_profile(std::uint32_t hash) - { - if (auto it = this->m_active_profiles.find(hash); it != this->m_active_profiles.end()) - return it->second; - return std::string(""); - } - - bool vehicle_service::get_by_share_code(const char* share_code) - { - static std::string up_to_date = ""; - - if (m_search_status == SearchStatus::SEARCHING) - return false; - - if (!safe_to_modify()) - return false; - - if (up_to_date == share_code) - return true; - m_search_status = SearchStatus::SEARCHING; - - nlohmann::json json; - if (api::vehicle::handling::get_by_share_code(std::string(share_code), json)) - { - if (json["data"].is_null()) - m_search_status = SearchStatus::NO_RESULT; - else - { - auto& data = json["data"]; - - HandlingProfile profile = HandlingProfile(data, g_local_player->m_vehicle->m_handling_data); - - if (auto it = m_handling_profiles.find(data["share_code"]); it != m_handling_profiles.end()) - it->second = profile; - else m_handling_profiles.emplace(data["share_code"], profile); - - up_to_date = data["share_code"]; - m_search_status = SearchStatus::FOUND; - } - } - else m_search_status = SearchStatus::FAILED; - - return true; - } - - bool vehicle_service::handling_data_to_json(CHandlingData& handling_data, nlohmann::json& out) - { - out = { - { "centre_of_mass", - { - { "x", handling_data.m_centre_of_mass.x }, - { "y", handling_data.m_centre_of_mass.y }, - { "z", handling_data.m_centre_of_mass.z } - } - }, - { "inertia_mult", - { - { "x", handling_data.m_inertia_mult.x }, - { "y", handling_data.m_inertia_mult.y }, - { "z", handling_data.m_inertia_mult.z } - } - }, - { "mass", handling_data.m_mass }, - { "downforce_mult", handling_data.m_downforce_multiplier }, - { "buoyancy", handling_data.m_buoyancy }, - { "drive_bias_rear", handling_data.m_drive_bias_rear }, - { "drive_bias_front", handling_data.m_drive_bias_front }, - { "acceleration_mult", handling_data.m_acceleration }, - { "initial_drive_gears", handling_data.m_initial_drive_gears }, - { "upshift", handling_data.m_upshift }, - { "downshift", handling_data.m_downshift }, - { "drive_inertia", handling_data.m_drive_inertia }, - { "initial_drive_force", handling_data.m_initial_drive_force }, - { "drive_max_flat_vel", handling_data.m_drive_max_flat_velocity }, - { "brake_force", handling_data.m_brake_force }, - { "brake_bias_front", handling_data.m_brake_bias_front }, - { "brake_bias_rear", handling_data.m_brake_bias_rear }, - { "handbrake_force", handling_data.m_handbrake_force }, - { "steering_lock", handling_data.m_steering_lock }, - { "steering_lock_ratio", handling_data.m_steering_lock_ratio }, - { "traction_curve_max", handling_data.m_traction_curve_max }, - { "traction_curve_lateral", handling_data.m_traction_curve_lateral }, - { "traction_curve_min", handling_data.m_traction_curve_min }, - { "traction_curve_ratio", handling_data.m_traction_curve_ratio }, - { "traction_bias_front", handling_data.m_traction_bias_front }, - { "traction_bias_rear", handling_data.m_traction_bias_rear }, - { "traction_loss_mult", handling_data.m_traction_loss_mult }, - { "curve_lateral", handling_data.m_curve_lateral }, - { "curve_lateral_ratio", handling_data.m_curve_lateral_ratio }, - { "traction_spring_delta_max", handling_data.m_traction_spring_delta_max }, - { "traction_spring_delta_max_ratio", handling_data.m_traction_spring_delta_max_ratio }, - { "low_speed_traction_loss_mult", handling_data.m_low_speed_traction_loss_mult }, - { "camber_stiffness", handling_data.m_camber_stiffness }, - { "suspension_force", handling_data.m_suspension_force }, - { "suspension_comp_damp", handling_data.m_suspension_comp_damp }, - { "suspension_rebound_damp", handling_data.m_suspension_rebound_damp }, - { "suspension_upper_limit", handling_data.m_suspension_upper_limit }, - { "suspension_lower_limit", handling_data.m_suspension_lower_limit }, - { "suspension_raise", handling_data.m_suspension_raise }, - { "suspension_bias_front", handling_data.m_suspension_bias_front }, - { "suspension_bias_rear", handling_data.m_suspension_bias_rear }, - { "anti_rollbar_force", handling_data.m_anti_rollbar_force }, - { "anti_rollbar_bias_front", handling_data.m_anti_rollbar_bias_front }, - { "anti_rollbar_bias_rear", handling_data.m_anti_rollbar_bias_rear }, - { "roll_centre_height_front", handling_data.m_roll_centre_height_front }, - { "roll_centre_height_rear", handling_data.m_roll_centre_height_rear } - }; - - return true; - } - - bool vehicle_service::load_saved_profiles(bool force_update) - { - static bool busy = false; - static uint32_t up_to_date = -1; - - if (busy) - return false; - - if (!safe_to_modify()) - return false; - - if (!force_update && up_to_date == g_local_player->m_vehicle->m_handling_data->m_model_hash) - return true; - - busy = true; - - g_thread_pool->push([&]() - { - nlohmann::json json; - if (!api::vehicle::handling::get_saved_handling(g_local_player->m_vehicle->m_handling_data->m_model_hash, json) || json == nullptr) - { - busy = false; - - return; - } - - this->m_saved_profiles.clear(); - for (auto& el : json["data"]) - { - LOG(INFO) << "Registered profile '" << el["name"].get().c_str() << "' with share code " << el["share_code"].get().c_str(); - - HandlingProfile profile = HandlingProfile(el, g_local_player->m_vehicle->m_handling_data); - - if (auto it = this->m_handling_profiles.find(el["share_code"]); it != this->m_handling_profiles.end()) - it->second = profile; - else this->m_handling_profiles.emplace(el["share_code"], profile); - this->m_saved_profiles.push_back(el["share_code"]); - } - - busy = false; - up_to_date = g_local_player->m_vehicle->m_handling_data->m_model_hash; - }); - - return false; - } - - bool vehicle_service::publish_profile(const char* name, const char* description, std::string share_code) - { - if (this->m_publish_status == PublishStatus::SAVED) - return true; - if (this->m_publish_status == PublishStatus::SAVING) - return false; - - if (!safe_to_modify()) return false; - - this->m_publish_status = PublishStatus::SAVING; - - CHandlingData handling_data = *g_local_player->m_vehicle->m_handling_data; - uint32_t hash = handling_data.m_model_hash; - - nlohmann::json data; - this->handling_data_to_json(handling_data, data); - - nlohmann::json json; - if (!share_code.empty() && api::vehicle::handling::update(hash, name, description, share_code, data)) - m_publish_status = PublishStatus::SAVED; - else if (api::vehicle::handling::create_profile(hash, name, description, data, json)) - { - this->set_active_profile(hash, json["data"]["share_code"]); - - m_publish_status = PublishStatus::SAVED; - } - else m_publish_status = PublishStatus::FAILED; - - return false; - } - - PublishStatus vehicle_service::publish_status(PublishStatus new_status) - { - if (new_status != PublishStatus::NONE) - this->m_publish_status = new_status; - - return this->m_publish_status; - } - - bool vehicle_service::restore_vehicle() - { - if (auto it = m_handling_backup.find(g_local_player->m_vehicle->m_handling_data->m_model_hash); it != m_handling_backup.end()) - { - if (safe_to_modify()) - *g_local_player->m_vehicle->m_handling_data = it->second; - this->m_active_profiles.erase(g_local_player->m_vehicle->m_handling_data->m_model_hash); - - return true; - } - - return false; - } - - void vehicle_service::set_active_profile(std::uint32_t hash, std::string share_code) - { - if (const auto& it = this->m_active_profiles.find(hash); it != this->m_active_profiles.end()) - it->second = share_code; - else - this->m_active_profiles.emplace(hash, share_code); - } - - void vehicle_service::set_handling_profile(HandlingProfile& profile) - { - if (!safe_to_modify()) - return; - *g_local_player->m_vehicle->m_handling_data = profile.data; - - this->set_active_profile(profile.handling_hash, profile.share_code); - } - - bool vehicle_service::update_mine(bool force_update) - { - static bool busy = false; - static uint32_t up_to_date = 0; - - if (busy) - return false; - - if (!safe_to_modify()) - return false; - - if (!force_update && up_to_date == g_local_player->m_vehicle->m_handling_data->m_model_hash) - return true; - - busy = true; - - g_thread_pool->push([&] { - nlohmann::json json; - if (!api::vehicle::handling::get_my_handling(g_local_player->m_vehicle->m_handling_data->m_model_hash, json) || json == nullptr) - { - busy = false; - - return; - } - - this->m_my_profiles.clear(); - for (auto& el : json["data"]) - { - LOG(INFO) << "Registered profile '" << el["name"].get().c_str() << "' with share code " << el["share_code"].get().c_str(); - - HandlingProfile profile = HandlingProfile(el, g_local_player->m_vehicle->m_handling_data); - - if (auto it = this->m_handling_profiles.find(el["share_code"]); it != this->m_handling_profiles.end()) - it->second = profile; - else this->m_handling_profiles.emplace(el["share_code"], profile); - this->m_my_profiles.push_back(el["share_code"]); - } - - busy = false; - up_to_date = g_local_player->m_vehicle->m_handling_data->m_model_hash; - }); - - return false; - } -} \ No newline at end of file diff --git a/BigBaseV2/src/services/vehicle/vehicle_service.hpp b/BigBaseV2/src/services/vehicle/vehicle_service.hpp deleted file mode 100644 index 8886094f..00000000 --- a/BigBaseV2/src/services/vehicle/vehicle_service.hpp +++ /dev/null @@ -1,144 +0,0 @@ -#pragma once - -namespace big -{ - enum class PublishStatus { - NONE = -2, - IDLE = -1, - SAVING, - SAVED, - FAILED - }; - - enum class SearchStatus { - NONE = -2, - IDLE = -1, - SEARCHING, - FOUND, - NO_RESULT, - FAILED - }; - - class vehicle_service - { - private: - - class HandlingProfile - { - public: - HandlingProfile(nlohmann::json &in, CHandlingData *handling_data) - { - this->handling_hash = in["handling_hash"]; - this->share_code = in["share_code"]; - - this->name = in["name"]; - this->description = in["description"]; - - nlohmann::json& data = in["data"]; - - // Make sure we copy the values that we don't modify to prevent corrupting the handling - this->data = *handling_data; - - this->data.m_centre_of_mass.x = data["centre_of_mass"]["x"]; - this->data.m_centre_of_mass.y = data["centre_of_mass"]["y"]; - this->data.m_centre_of_mass.z = data["centre_of_mass"]["z"]; - - this->data.m_inertia_mult.x = data["inertia_mult"]["x"]; - this->data.m_inertia_mult.y = data["inertia_mult"]["y"]; - this->data.m_inertia_mult.z = data["inertia_mult"]["z"]; - - this->data.m_mass = data["mass"]; - this->data.m_downforce_multiplier = data["downforce_mult"]; - this->data.m_buoyancy = data["buoyancy"]; - - this->data.m_drive_bias_rear = data["drive_bias_rear"]; - this->data.m_drive_bias_front = data["drive_bias_front"]; - - this->data.m_acceleration = data["acceleration_mult"]; - - this->data.m_initial_drive_gears = data["initial_drive_gears"]; - this->data.m_upshift = data["upshift"]; - this->data.m_downshift = data["downshift"]; - - this->data.m_drive_inertia = data["drive_inertia"]; - - this->data.m_drive_max_flat_velocity = data["drive_max_flat_vel"]; - - this->data.m_brake_force = data["brake_force"]; - this->data.m_brake_bias_front = data["brake_bias_front"]; - this->data.m_brake_bias_rear = data["brake_bias_rear"]; - this->data.m_handbrake_force = data["handbrake_force"]; - - this->data.m_steering_lock = data["steering_lock"]; - this->data.m_steering_lock_ratio = data["steering_lock_ratio"]; - - this->data.m_traction_curve_max = data["traction_curve_max"]; - this->data.m_traction_curve_lateral = data["traction_curve_lateral"]; - this->data.m_traction_curve_min = data["traction_curve_min"]; - this->data.m_traction_curve_ratio = data["traction_curve_ratio"]; - - this->data.m_curve_lateral = data["curve_lateral"]; - this->data.m_curve_lateral_ratio = data["curve_lateral_ratio"]; - - this->data.m_traction_spring_delta_max = data["traction_spring_delta_max"]; - this->data.m_traction_spring_delta_max_ratio = data["traction_spring_delta_max_ratio"]; - - this->data.m_low_speed_traction_loss_mult = data["low_speed_traction_loss_mult"]; - this->data.m_camber_stiffness = data["camber_stiffness"]; - - this->data.m_suspension_force = data["suspension_force"]; - this->data.m_suspension_comp_damp = data["suspension_comp_damp"]; - this->data.m_suspension_rebound_damp = data["suspension_rebound_damp"]; - this->data.m_suspension_upper_limit = data["suspension_upper_limit"]; - this->data.m_suspension_lower_limit = data["suspension_lower_limit"]; - this->data.m_suspension_raise = data["suspension_raise"]; - this->data.m_suspension_bias_front = data["suspension_bias_front"]; - this->data.m_suspension_bias_rear = data["suspension_bias_rear"]; - - this->data.m_anti_rollbar_force = data["anti_rollbar_force"]; - this->data.m_anti_rollbar_bias_front = data["anti_rollbar_bias_front"]; - this->data.m_anti_rollbar_bias_rear = data["anti_rollbar_bias_rear"]; - - this->data.m_roll_centre_height_front = data["roll_centre_height_front"]; - this->data.m_roll_centre_height_rear = data["roll_centre_height_rear"]; - } - - CHandlingData data; - - uint32_t handling_hash; - std::string share_code; - - std::string name; - std::string description; - }; - - public: - vehicle_service(); - ~vehicle_service(); - - int attempt_save(); - std::string get_active_profile(std::uint32_t hash); - bool get_by_share_code(const char* share_code); - bool handling_data_to_json(CHandlingData& handling_data, nlohmann::json& out); - bool load_saved_profiles(bool force_update = false); - bool publish_profile(const char* name, const char* description, std::string share_code = ""); - PublishStatus publish_status(PublishStatus new_status = PublishStatus::NONE); - bool restore_vehicle(); - void set_active_profile(std::uint32_t hash, std::string share_code); - void set_handling_profile(HandlingProfile& profile); - bool update_mine(bool force_update = false); - - inline static std::unordered_map m_active_profiles; - inline static std::vector m_my_profiles; - inline static std::vector m_saved_profiles; - inline static std::unordered_map m_handling_profiles; - - SearchStatus m_search_status = SearchStatus::IDLE; - private: - PublishStatus m_publish_status = PublishStatus::IDLE; - - inline static std::unordered_map m_handling_backup; - }; - - inline vehicle_service* g_vehicle_service; -} \ No newline at end of file diff --git a/BigBaseV2/src/views/view.hpp b/BigBaseV2/src/views/view.hpp index 6df5afdd..fc008c1a 100644 --- a/BigBaseV2/src/views/view.hpp +++ b/BigBaseV2/src/views/view.hpp @@ -18,9 +18,7 @@ namespace big static void context_menu_settings(); static void gui_settings(); static void handling_current_profile(); - static void handling_my_profiles(); static void handling_saved_profiles(); - static void handling_search(); static void notification_settings(); static void protection_settings(); static void heading();