From d1f2c2a22e55d503ff5207a5a87acd52a5f855a7 Mon Sep 17 00:00:00 2001 From: LA_DI_DA <11174151+0O0o0oOoO00@users.noreply.github.com> Date: Tue, 25 Mar 2025 18:39:21 +0800 Subject: [PATCH] add: add the function of obtaining player resources and scanning warehouses --- blcrack/cracker/cracker.cpp | 152 +++++++++++++++++++++++++++++++++++- blcrack/cracker/cracker.hpp | 38 +++++++++ blcrack/cracker/server.cpp | 148 +++++++++++++++++++++++++++++++++++ 3 files changed, 337 insertions(+), 1 deletion(-) diff --git a/blcrack/cracker/cracker.cpp b/blcrack/cracker/cracker.cpp index a7746e5df..ee2a4471d 100644 --- a/blcrack/cracker/cracker.cpp +++ b/blcrack/cracker/cracker.cpp @@ -3,17 +3,167 @@ #include #include #include +#include #include "utils.hpp" Cracker::Cracker() - : m_state(lua_newthread(Utils::get_lua_state())) {} + : m_state(lua_newthread(Utils::get_lua_state())) { + Lua::Table proxies = m_state["pg"]["proxyRegister"]["data"]; + for (int i = 1; i <= proxies.size(); ++i) { + Lua::Table proxy = proxies[i]; + std::string proxy_name = proxy["proxyName"]; + if (proxy_name == "PlayerProxy") { + Lua::Table proxy_map = proxy["facade"]["model"]["proxyMap"]; + m_data_proxy.player = proxy_map["PlayerProxy"]; + m_data_proxy.dock = proxy_map["BayProxy"]; + m_data_proxy.storage = proxy_map["BagProxy"]; + } else if (proxy_name == "WorldProxy") { + m_data_proxy.world = proxy["facade"]["model"]["proxyMap"]["WorldProxy"]; + } + } +} Cracker& Cracker::Instance() { static auto* instance = new Cracker; return *instance; } +int Cracker::get_coin() { + double coin = m_data_proxy.player["data"]["gold"]; + return static_cast(coin); +} + +int Cracker::get_oil() { + double oil = m_data_proxy.player["data"]["oil"]; + return static_cast(oil); +} + +int Cracker::get_gems() { + double gems = m_data_proxy.player["data"]["awardGem"]; + return static_cast(gems); +} + +int Cracker::get_level() { + double level = m_data_proxy.player["data"]["level"]; + return static_cast(level); +} + +int Cracker::get_exp() { + double exp = m_data_proxy.player["data"]["exp"]; + return static_cast(exp); +} + +int Cracker::get_merit() { + double merit = m_data_proxy.player["data"]["exploit"]; + return static_cast(merit); +} + +int Cracker::get_guild_coin() { + double guild_coin = m_data_proxy.player["data"]["guildCoin"]; + return static_cast(guild_coin); +} + +int Cracker::get_design_prt() { + double design_prt = m_data_proxy.player["data"]["design_prt"]; + return static_cast(design_prt); +} + +#define CORE_DATA_ITEM_ID 59900 + +int Cracker::get_core_data() { + Lua::Table storage = m_data_proxy.storage["data"]; + double core_data = storage.get(CORE_DATA_ITEM_ID)["count"]; + return static_cast(core_data); +} + +#define MEDAL_ITEM_ID 15001 + +int Cracker::get_medal() { + Lua::Table storage = m_data_proxy.storage["data"]; + double medal = storage.get(MEDAL_ITEM_ID)["count"]; + return static_cast(medal); +} + +int Cracker::get_pt() { + double pt = m_data_proxy.player["data"]["pt"]; + return static_cast(pt); +} + +#define SPECIALIZED_CORE_ITEM_ID 59010 + +int Cracker::get_specialized_core() { + Lua::Table storage = m_data_proxy.storage["data"]; + double specialized_core = storage.get(SPECIALIZED_CORE_ITEM_ID)["count"]; + return static_cast(specialized_core); +} + +int Cracker::get_curr_action_point() { + double curr_action_point = m_data_proxy.world["world"]["fields"]["staminaMgr"]["fields"]["stamina"]; + return static_cast(curr_action_point); +} + +std::map Cracker::scan_dock() { + std::map ships; + Lua::Table dock = m_data_proxy.dock["data"]; + for (auto& [ship_id, ship_info] : dock) { + Lua::Table ship_data = ship_info.as(); + double id = ship_data["id"]; + ships[static_cast(id)] = { + .config_id = static_cast(ship_data.get("configId")), + .emotion = static_cast(ship_data.get("energy")), + .rarity = static_cast(ship_data.get("star")), + .level = static_cast(ship_data.get("level")), + .exp = static_cast(ship_data.get("exp")), + .curr_star = static_cast(ship_data.get("state")), + }; + } + return ships; +} + +std::map Cracker::scan_storage() { + std::map items; + Lua::Table storage = m_data_proxy.storage["data"]; + for (auto& [item_id, item_info] : storage) { + Lua::Table item_data = item_info.as(); + double config_id = item_data["configId"]; + double count = item_data["count"]; + items[static_cast(config_id)] = static_cast(count); + } + return items; +} + +std::optional Cracker::get_ship_info(ShipId ship_id) { + double id = static_cast(ship_id); + Lua::Table dock = m_data_proxy.dock["data"]; + try { + Lua::Table ship_data = dock.get(id); + return ShipInfo{ + .config_id = static_cast(ship_data.get("configId")), + .emotion = static_cast(ship_data.get("energy")), + .rarity = static_cast(ship_data.get("star")), + .level = static_cast(ship_data.get("level")), + .exp = static_cast(ship_data.get("exp")), + .curr_star = static_cast(ship_data.get("state")), + }; + } catch (const std::exception& e) { + return std::nullopt; + } + return std::nullopt; +} + +std::optional Cracker::get_storage_item_count(StorageItemId item_id) { + double id = static_cast(item_id); + Lua::Table storage = m_data_proxy.storage["data"]; + try { + Lua::Table item_data = storage.get(id); + return static_cast(item_data.get("count")); + } catch (const std::exception& e) { + return std::nullopt; + } + return std::nullopt; +} + void Cracker::disable_all() { disable_global_ship_properties_crack(); disable_fast_stage_move(); diff --git a/blcrack/cracker/cracker.hpp b/blcrack/cracker/cracker.hpp index bb952ed9b..0c5043779 100644 --- a/blcrack/cracker/cracker.hpp +++ b/blcrack/cracker/cracker.hpp @@ -33,6 +33,8 @@ class Cracker { public: using FunctionId = int; using ShipId = int; + using StorageItemId = int; + using StorageItemCount = int; // -1 means disabled struct ShipProperties { @@ -64,11 +66,40 @@ public: std::string level; }; + struct ShipInfo { + int config_id; + int emotion; + int rarity; + int level; + int exp; + int curr_star; + }; + public: Cracker(); static Cracker& Instance(); + int get_coin(); + int get_oil(); + int get_gems(); + int get_level(); + int get_exp(); + int get_merit(); + int get_guild_coin(); + int get_design_prt(); + int get_core_data(); + int get_medal(); + int get_pt(); + int get_specialized_core(); + int get_curr_action_point(); + std::map scan_dock(); + std::map scan_storage(); + + std::optional get_ship_info(ShipId ship_id); + std::optional get_storage_item_count(StorageItemId item_id); + + void disable_all(); void enable_opsi_fast_move(); @@ -108,6 +139,13 @@ private: static void modify_ship_properties(Lua::Table& properties, const ShipProperties& new_properties); static void clear_hard_mode_ship_properties_limit(Lua::Table& t); + struct { + Lua::Table player; + Lua::Table world; + Lua::Table dock; + Lua::Table storage; + } m_data_proxy; + std::map m_functions; sol::state_view m_state; struct { diff --git a/blcrack/cracker/server.cpp b/blcrack/cracker/server.cpp index 09a8ddc64..29764d56d 100644 --- a/blcrack/cracker/server.cpp +++ b/blcrack/cracker/server.cpp @@ -167,6 +167,154 @@ CrackerServer::CrackerServer() { res.status = 200; }); + Get("/get_coin", [](const httplib::Request& req, httplib::Response& res) { + auto coin = Cracker::Instance().get_coin(); + res.body = std::to_string(coin); + res.status = 200; + }); + + Get("/get_oil", [](const httplib::Request& req, httplib::Response& res) { + auto oil = Cracker::Instance().get_oil(); + res.body = std::to_string(oil); + res.status = 200; + }); + + Get("/get_gems", [](const httplib::Request& req, httplib::Response& res) { + auto gems = Cracker::Instance().get_gems(); + res.body = std::to_string(gems); + res.status = 200; + }); + + Get("/get_level", [](const httplib::Request& req, httplib::Response& res) { + auto level = Cracker::Instance().get_level(); + res.body = std::to_string(level); + res.status = 200; + }); + + Get("/get_exp", [](const httplib::Request& req, httplib::Response& res) { + auto exp = Cracker::Instance().get_exp(); + res.body = std::to_string(exp); + res.status = 200; + }); + + Get("/get_merit", [](const httplib::Request& req, httplib::Response& res) { + auto merit = Cracker::Instance().get_merit(); + res.body = std::to_string(merit); + res.status = 200; + }); + + Get("/get_guild_coin", [](const httplib::Request& req, httplib::Response& res) { + auto guild_coin = Cracker::Instance().get_guild_coin(); + res.body = std::to_string(guild_coin); + res.status = 200; + }); + + Get("/get_design_prt", [](const httplib::Request& req, httplib::Response& res) { + auto design_prt = Cracker::Instance().get_design_prt(); + res.body = std::to_string(design_prt); + res.status = 200; + }); + + Get("/get_core_data", [](const httplib::Request& req, httplib::Response& res) { + auto core_data = Cracker::Instance().get_core_data(); + res.body = std::to_string(core_data); + res.status = 200; + }); + + Get("/get_medal", [](const httplib::Request& req, httplib::Response& res) { + auto medal = Cracker::Instance().get_medal(); + res.body = std::to_string(medal); + res.status = 200; + }); + + Get("/get_pt", [](const httplib::Request& req, httplib::Response& res) { + auto pt = Cracker::Instance().get_pt(); + res.body = std::to_string(pt); + res.status = 200; + }); + + Get("/get_specialized_core", [](const httplib::Request& req, httplib::Response& res) { + auto specialized_core = Cracker::Instance().get_specialized_core(); + res.body = std::to_string(specialized_core); + res.status = 200; + }); + + Get("/get_curr_action_point", [](const httplib::Request& req, httplib::Response& res) { + auto curr_action_point = Cracker::Instance().get_curr_action_point(); + res.body = std::to_string(curr_action_point); + res.status = 200; + }); + + Get("/scan_dock", [](const httplib::Request& req, httplib::Response& res) { + auto dock = Cracker::Instance().scan_dock(); + Json::Value j; + for (auto& ship : dock) { + Json::Value ship_info_j; + ship_info_j["config_id"] = ship.second.config_id; + ship_info_j["emotion"] = ship.second.emotion; + ship_info_j["rarity"] = ship.second.rarity; + ship_info_j["level"] = ship.second.level; + ship_info_j["exp"] = ship.second.exp; + ship_info_j["curr_star"] = ship.second.curr_star; + j[std::to_string(ship.first)] = ship_info_j; + } + Json::FastWriter writer; + res.body = writer.write(j); + res.status = 200; + }); + + Get("/scan_storage", [](const httplib::Request& req, httplib::Response& res) { + auto storage = Cracker::Instance().scan_storage(); + Json::Value j; + for (auto& item : storage) { + j[std::to_string(item.first)] = item.second; + } + Json::FastWriter writer; + res.body = writer.write(j); + res.status = 200; + }); + + Get("/get_ship_info", [](const httplib::Request& req, httplib::Response& res) { + auto id = req.get_param_value("id"); + if (id.empty()) { + res.status = 400; + return; + } + auto ship_info = Cracker::Instance().get_ship_info(std::stoi(id)); + if (ship_info.has_value()) { + Cracker::ShipInfo& info = ship_info.value(); + Json::Value j; + j["config_id"] = info.config_id; + j["emotion"] = info.emotion; + j["rarity"] = info.rarity; + j["level"] = info.level; + j["exp"] = info.exp; + j["curr_star"] = info.curr_star; + Json::FastWriter writer; + res.body = writer.write(j); + res.status = 200; + } else { + res.status = 400; + return; + } + }); + + Get("/get_storage_item_count", [](const httplib::Request& req, httplib::Response& res) { + auto item_id = req.get_param_value("item_id"); + if (item_id.empty()) { + res.status = 400; + return; + } + auto count = Cracker::Instance().get_storage_item_count(std::stoi(item_id)); + if (count.has_value()) { + res.body = std::to_string(count.value()); + res.status = 200; + } else { + res.status = 400; + return; + } + }); + std::thread([this] { SPDLOG_INFO("Start server on port 23897"); listen("0.0.0.0", 23897);