mirror of
https://github.com/MaaAssistantArknights/MaaAssistantArknights.git
synced 2026-07-16 09:50:40 +08:00
styles: format all cpp
This commit is contained in:
@@ -399,7 +399,7 @@ namespace asst
|
||||
bool full_match = false; // 是否需要全匹配,否则搜索到子串就算匹配上了
|
||||
bool is_ascii = false; // 是否启用字符数字模型
|
||||
bool without_det = false; // 是否不使用检测模型
|
||||
bool replace_full = false; // 匹配之后,是否将整个字符串replace(false是只替换match的部分)
|
||||
bool replace_full = false; // 匹配之后,是否将整个字符串replace(false是只替换match的部分)
|
||||
std::unordered_map<std::string, std::string>
|
||||
replace_map; // 部分文字容易识别错,字符串强制replace之后,再进行匹配
|
||||
};
|
||||
|
||||
@@ -27,5 +27,4 @@ namespace asst
|
||||
|
||||
std::vector<equivalence_class> m_eq_classes;
|
||||
};
|
||||
|
||||
} // namespace asst
|
||||
|
||||
@@ -11,15 +11,13 @@ ASST_SUPPRESS_CV_WARNINGS_END
|
||||
|
||||
#include "Config/GeneralConfig.h"
|
||||
#include "Utils/Demangle.hpp"
|
||||
#include "Utils/File.hpp"
|
||||
#include "Utils/Logger.hpp"
|
||||
#include "Utils/Platform.hpp"
|
||||
#include "Utils/Ranges.hpp"
|
||||
#include "Utils/StringMisc.hpp"
|
||||
#include "Utils/File.hpp"
|
||||
|
||||
|
||||
asst::OcrPack::OcrPack()
|
||||
: m_det(nullptr), m_rec(nullptr), m_ocr(nullptr)
|
||||
asst::OcrPack::OcrPack() : m_det(nullptr), m_rec(nullptr), m_ocr(nullptr)
|
||||
{
|
||||
LogTraceFunction;
|
||||
}
|
||||
@@ -52,7 +50,8 @@ bool asst::OcrPack::load(const std::filesystem::path& path)
|
||||
if (std::filesystem::exists(dst_model_file)) {
|
||||
auto det_model = asst::utils::read_file<std::string>(dst_model_file);
|
||||
option.SetModelBuffer(det_model.data(), det_model.size(), nullptr, 0, fastdeploy::ModelFormat::ONNX);
|
||||
m_det = std::make_unique<fastdeploy::vision::ocr::DBDetector>("dummy.onnx", std::string(), option, fastdeploy::ModelFormat::ONNX);
|
||||
m_det = std::make_unique<fastdeploy::vision::ocr::DBDetector>("dummy.onnx", std::string(), option,
|
||||
fastdeploy::ModelFormat::ONNX);
|
||||
}
|
||||
else if (!m_det) {
|
||||
break;
|
||||
@@ -63,7 +62,8 @@ bool asst::OcrPack::load(const std::filesystem::path& path)
|
||||
auto rec_model = asst::utils::read_file<std::string>(rec_model_file);
|
||||
auto label = asst::utils::read_file<std::string>(rec_label_file);
|
||||
option.SetModelBuffer(rec_model.data(), rec_model.size(), nullptr, 0, fastdeploy::ModelFormat::ONNX);
|
||||
m_rec = std::make_unique<fastdeploy::vision::ocr::Recognizer>("dummy.onnx", std::string(), label, option, fastdeploy::ModelFormat::ONNX);
|
||||
m_rec = std::make_unique<fastdeploy::vision::ocr::Recognizer>("dummy.onnx", std::string(), label, option,
|
||||
fastdeploy::ModelFormat::ONNX);
|
||||
}
|
||||
else if (!m_rec) {
|
||||
break;
|
||||
@@ -78,7 +78,6 @@ bool asst::OcrPack::load(const std::filesystem::path& path)
|
||||
}
|
||||
} while (false);
|
||||
|
||||
|
||||
return m_det != nullptr && m_rec != nullptr && m_ocr != nullptr && m_det->Initialized() && m_rec->Initialized() &&
|
||||
m_ocr->Initialized();
|
||||
}
|
||||
|
||||
@@ -84,7 +84,6 @@ bool asst::TilePack::load(const std::filesystem::path& path)
|
||||
}
|
||||
|
||||
for (const auto& entry : std::filesystem::directory_iterator(path)) {
|
||||
|
||||
if (eoq.load()) break; // this means parsing went wrong
|
||||
|
||||
const auto& file_path = entry.path();
|
||||
|
||||
@@ -31,22 +31,19 @@ asst::ControlScaleProxy::ControlScaleProxy(std::shared_ptr<ControllerAPI> contro
|
||||
}
|
||||
|
||||
/* calc ratio */
|
||||
{
|
||||
constexpr double DefaultRatio =
|
||||
static_cast<double>(WindowWidthDefault) / static_cast<double>(WindowHeightDefault);
|
||||
double cur_ratio = static_cast<double>(width) / static_cast<double>(height);
|
||||
constexpr double DefaultRatio = static_cast<double>(WindowWidthDefault) / static_cast<double>(WindowHeightDefault);
|
||||
double cur_ratio = static_cast<double>(width) / static_cast<double>(height);
|
||||
|
||||
if (cur_ratio >= DefaultRatio // 说明是宽屏或默认16:9,按照高度计算缩放
|
||||
|| std::fabs(cur_ratio - DefaultRatio) < DoubleDiff) {
|
||||
int scale_width = static_cast<int>(cur_ratio * WindowHeightDefault);
|
||||
m_scale_size = std::make_pair(scale_width, WindowHeightDefault);
|
||||
m_control_scale = static_cast<double>(height) / static_cast<double>(WindowHeightDefault);
|
||||
}
|
||||
else { // 否则可能是偏正方形的屏幕,按宽度计算
|
||||
int scale_height = static_cast<int>(WindowWidthDefault / cur_ratio);
|
||||
m_scale_size = std::make_pair(WindowWidthDefault, scale_height);
|
||||
m_control_scale = static_cast<double>(width) / static_cast<double>(WindowWidthDefault);
|
||||
}
|
||||
if (cur_ratio >= DefaultRatio // 说明是宽屏或默认16:9,按照高度计算缩放
|
||||
|| std::fabs(cur_ratio - DefaultRatio) < DoubleDiff) {
|
||||
int scale_width = static_cast<int>(cur_ratio * WindowHeightDefault);
|
||||
m_scale_size = std::make_pair(scale_width, WindowHeightDefault);
|
||||
m_control_scale = static_cast<double>(height) / static_cast<double>(WindowHeightDefault);
|
||||
}
|
||||
else { // 否则可能是偏正方形的屏幕,按宽度计算
|
||||
int scale_height = static_cast<int>(WindowWidthDefault / cur_ratio);
|
||||
m_scale_size = std::make_pair(WindowWidthDefault, scale_height);
|
||||
m_control_scale = static_cast<double>(width) / static_cast<double>(WindowWidthDefault);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -14,7 +14,6 @@
|
||||
|
||||
namespace asst
|
||||
{
|
||||
|
||||
#ifdef _WIN32
|
||||
using NativeIO = asst::Win32IO;
|
||||
#else
|
||||
|
||||
@@ -7,7 +7,6 @@
|
||||
|
||||
namespace asst
|
||||
{
|
||||
|
||||
class IOHandler;
|
||||
|
||||
enum class PlatformType
|
||||
|
||||
@@ -13,92 +13,94 @@ using tcp_endpoints = tcp::resolver::results_type;
|
||||
using adb::protocol::send_host_request;
|
||||
using adb::protocol::send_sync_request;
|
||||
|
||||
namespace adb {
|
||||
namespace adb
|
||||
{
|
||||
static inline std::string version(asio::io_context& context, const tcp_endpoints& endpoints)
|
||||
{
|
||||
tcp::socket socket(context);
|
||||
asio::connect(socket, endpoints);
|
||||
|
||||
static inline std::string version(asio::io_context& context,
|
||||
const tcp_endpoints& endpoints) {
|
||||
tcp::socket socket(context);
|
||||
asio::connect(socket, endpoints);
|
||||
const auto request = "host:version";
|
||||
send_host_request(socket, request);
|
||||
|
||||
const auto request = "host:version";
|
||||
send_host_request(socket, request);
|
||||
|
||||
return protocol::host_message(socket);
|
||||
}
|
||||
|
||||
static inline std::string devices(asio::io_context& context,
|
||||
const tcp_endpoints& endpoints) {
|
||||
tcp::socket socket(context);
|
||||
asio::connect(socket, endpoints);
|
||||
|
||||
const auto request = "host:devices";
|
||||
send_host_request(socket, request);
|
||||
|
||||
return protocol::host_message(socket);
|
||||
}
|
||||
|
||||
std::string version() {
|
||||
asio::io_context context;
|
||||
tcp::resolver resolver(context);
|
||||
const auto endpoints = resolver.resolve("127.0.0.1", "5037");
|
||||
return version(context, endpoints);
|
||||
}
|
||||
|
||||
std::string devices() {
|
||||
asio::io_context context;
|
||||
tcp::resolver resolver(context);
|
||||
const auto endpoints = resolver.resolve("127.0.0.1", "5037");
|
||||
return devices(context, endpoints);
|
||||
}
|
||||
|
||||
void kill_server() {
|
||||
asio::io_context context;
|
||||
tcp::resolver resolver(context);
|
||||
const auto endpoints = resolver.resolve("127.0.0.1", "5037");
|
||||
|
||||
tcp::socket socket(context);
|
||||
asio::connect(socket, endpoints);
|
||||
|
||||
const auto request = "host:kill";
|
||||
send_host_request(socket, request);
|
||||
}
|
||||
|
||||
class io_handle_impl : public io_handle {
|
||||
public:
|
||||
io_handle_impl(std::unique_ptr<asio::io_context> context,
|
||||
tcp::socket socket);
|
||||
void write(const std::string_view data) override;
|
||||
std::string read(unsigned timeout = 0) override;
|
||||
|
||||
private:
|
||||
friend class client_impl;
|
||||
|
||||
const std::unique_ptr<asio::io_context> m_context;
|
||||
asio::ip::tcp::socket m_socket;
|
||||
};
|
||||
|
||||
io_handle_impl::io_handle_impl(std::unique_ptr<asio::io_context> context,
|
||||
tcp::socket socket)
|
||||
: m_context(std::move(context)), m_socket(std::move(socket)) {
|
||||
asio::socket_base::keep_alive option(true);
|
||||
m_socket.set_option(option);
|
||||
}
|
||||
|
||||
std::string io_handle_impl::read(unsigned timeout) {
|
||||
std::array<char, 1024> buffer;
|
||||
|
||||
if (timeout == 0) {
|
||||
const auto bytes_read = m_socket.read_some(asio::buffer(buffer));
|
||||
return std::string(buffer.data(), bytes_read);
|
||||
return protocol::host_message(socket);
|
||||
}
|
||||
|
||||
std::error_code ec;
|
||||
size_t bytes_read = 0;
|
||||
asio::steady_timer timer(*m_context, std::chrono::seconds(timeout));
|
||||
static inline std::string devices(asio::io_context& context, const tcp_endpoints& endpoints)
|
||||
{
|
||||
tcp::socket socket(context);
|
||||
asio::connect(socket, endpoints);
|
||||
|
||||
m_socket.async_read_some(
|
||||
asio::buffer(buffer),
|
||||
[&](const asio::error_code& error, size_t bytes_transferred) {
|
||||
const auto request = "host:devices";
|
||||
send_host_request(socket, request);
|
||||
|
||||
return protocol::host_message(socket);
|
||||
}
|
||||
|
||||
std::string version()
|
||||
{
|
||||
asio::io_context context;
|
||||
tcp::resolver resolver(context);
|
||||
const auto endpoints = resolver.resolve("127.0.0.1", "5037");
|
||||
return version(context, endpoints);
|
||||
}
|
||||
|
||||
std::string devices()
|
||||
{
|
||||
asio::io_context context;
|
||||
tcp::resolver resolver(context);
|
||||
const auto endpoints = resolver.resolve("127.0.0.1", "5037");
|
||||
return devices(context, endpoints);
|
||||
}
|
||||
|
||||
void kill_server()
|
||||
{
|
||||
asio::io_context context;
|
||||
tcp::resolver resolver(context);
|
||||
const auto endpoints = resolver.resolve("127.0.0.1", "5037");
|
||||
|
||||
tcp::socket socket(context);
|
||||
asio::connect(socket, endpoints);
|
||||
|
||||
const auto request = "host:kill";
|
||||
send_host_request(socket, request);
|
||||
}
|
||||
|
||||
class io_handle_impl : public io_handle
|
||||
{
|
||||
public:
|
||||
io_handle_impl(std::unique_ptr<asio::io_context> context, tcp::socket socket);
|
||||
void write(const std::string_view data) override;
|
||||
std::string read(unsigned timeout = 0) override;
|
||||
|
||||
private:
|
||||
friend class client_impl;
|
||||
|
||||
const std::unique_ptr<asio::io_context> m_context;
|
||||
asio::ip::tcp::socket m_socket;
|
||||
};
|
||||
|
||||
io_handle_impl::io_handle_impl(std::unique_ptr<asio::io_context> context, tcp::socket socket)
|
||||
: m_context(std::move(context)), m_socket(std::move(socket))
|
||||
{
|
||||
asio::socket_base::keep_alive option(true);
|
||||
m_socket.set_option(option);
|
||||
}
|
||||
|
||||
std::string io_handle_impl::read(unsigned timeout)
|
||||
{
|
||||
std::array<char, 1024> buffer;
|
||||
|
||||
if (timeout == 0) {
|
||||
const auto bytes_read = m_socket.read_some(asio::buffer(buffer));
|
||||
return std::string(buffer.data(), bytes_read);
|
||||
}
|
||||
|
||||
std::error_code ec;
|
||||
size_t bytes_read = 0;
|
||||
asio::steady_timer timer(*m_context, std::chrono::seconds(timeout));
|
||||
|
||||
m_socket.async_read_some(asio::buffer(buffer), [&](const asio::error_code& error, size_t bytes_transferred) {
|
||||
if (error) {
|
||||
ec = error;
|
||||
return;
|
||||
@@ -107,225 +109,235 @@ std::string io_handle_impl::read(unsigned timeout) {
|
||||
timer.cancel();
|
||||
});
|
||||
|
||||
timer.async_wait([&](const asio::error_code& error) {
|
||||
if (error) {
|
||||
ec = error;
|
||||
return;
|
||||
}
|
||||
m_socket.cancel(ec);
|
||||
});
|
||||
timer.async_wait([&](const asio::error_code& error) {
|
||||
if (error) {
|
||||
ec = error;
|
||||
return;
|
||||
}
|
||||
m_socket.cancel(ec);
|
||||
});
|
||||
|
||||
m_context->restart();
|
||||
while (m_context->run_one()) {
|
||||
if (ec == asio::error::eof) {
|
||||
break;
|
||||
} else if (ec == asio::error::operation_aborted) {
|
||||
break;
|
||||
} else if (ec) {
|
||||
throw std::system_error(ec);
|
||||
m_context->restart();
|
||||
while (m_context->run_one()) {
|
||||
if (ec == asio::error::eof) {
|
||||
break;
|
||||
}
|
||||
else if (ec == asio::error::operation_aborted) {
|
||||
break;
|
||||
}
|
||||
else if (ec) {
|
||||
throw std::system_error(ec);
|
||||
}
|
||||
}
|
||||
|
||||
return std::string(buffer.data(), bytes_read);
|
||||
}
|
||||
|
||||
void io_handle_impl::write(const std::string_view data)
|
||||
{
|
||||
m_socket.write_some(asio::buffer(data));
|
||||
}
|
||||
|
||||
class client_impl : public client
|
||||
{
|
||||
public:
|
||||
client_impl(const std::string_view serial);
|
||||
std::string connect() override;
|
||||
std::string disconnect() override;
|
||||
std::string version() override;
|
||||
std::string devices() override;
|
||||
std::string shell(const std::string_view command) override;
|
||||
std::string exec(const std::string_view command) override;
|
||||
bool push(const std::string_view src, const std::string_view dst, int perm) override;
|
||||
std::shared_ptr<io_handle> interactive_shell(const std::string_view command) override;
|
||||
std::string root() override;
|
||||
std::string unroot() override;
|
||||
void wait_for_device() override;
|
||||
|
||||
private:
|
||||
friend class client;
|
||||
|
||||
std::string m_serial;
|
||||
asio::io_context m_context;
|
||||
tcp_endpoints m_endpoints;
|
||||
|
||||
/// Switch the connection to the device.
|
||||
/**
|
||||
* @param socket Opened adb connection.
|
||||
* @note Should be used only by the client class.
|
||||
* @note Local services (e.g. shell, push) can be requested after this.
|
||||
*/
|
||||
void switch_to_device(asio::ip::tcp::socket& socket);
|
||||
};
|
||||
|
||||
std::shared_ptr<client> client::create(const std::string_view serial)
|
||||
{
|
||||
return std::make_shared<client_impl>(serial);
|
||||
}
|
||||
|
||||
client_impl::client_impl(const std::string_view serial)
|
||||
{
|
||||
m_serial = serial;
|
||||
|
||||
tcp::resolver resolver(m_context);
|
||||
m_endpoints = resolver.resolve("127.0.0.1", "5037");
|
||||
}
|
||||
|
||||
std::string client_impl::connect()
|
||||
{
|
||||
tcp::socket socket(m_context);
|
||||
asio::connect(socket, m_endpoints);
|
||||
|
||||
const auto request = "host:connect:" + m_serial;
|
||||
send_host_request(socket, request);
|
||||
|
||||
return protocol::host_message(socket);
|
||||
}
|
||||
|
||||
std::string client_impl::disconnect()
|
||||
{
|
||||
tcp::socket socket(m_context);
|
||||
asio::connect(socket, m_endpoints);
|
||||
|
||||
const auto request = "host:disconnect:" + m_serial;
|
||||
send_host_request(socket, request);
|
||||
|
||||
return protocol::host_message(socket);
|
||||
}
|
||||
|
||||
std::string client_impl::version()
|
||||
{
|
||||
return adb::version(m_context, m_endpoints);
|
||||
}
|
||||
|
||||
std::string client_impl::devices()
|
||||
{
|
||||
return adb::devices(m_context, m_endpoints);
|
||||
}
|
||||
|
||||
std::string client_impl::shell(const std::string_view command)
|
||||
{
|
||||
tcp::socket socket(m_context);
|
||||
asio::connect(socket, m_endpoints);
|
||||
|
||||
switch_to_device(socket);
|
||||
|
||||
const auto request = std::string("shell:") + command.data();
|
||||
send_host_request(socket, request);
|
||||
|
||||
return protocol::host_data(socket);
|
||||
}
|
||||
|
||||
std::string client_impl::exec(const std::string_view command)
|
||||
{
|
||||
tcp::socket socket(m_context);
|
||||
asio::connect(socket, m_endpoints);
|
||||
|
||||
switch_to_device(socket);
|
||||
|
||||
const auto request = std::string("exec:") + command.data();
|
||||
send_host_request(socket, request);
|
||||
|
||||
return protocol::host_data(socket);
|
||||
}
|
||||
|
||||
bool client_impl::push(const std::string_view src, const std::string_view dst, int perm)
|
||||
{
|
||||
tcp::socket socket(m_context);
|
||||
asio::connect(socket, m_endpoints);
|
||||
|
||||
switch_to_device(socket);
|
||||
|
||||
// Switch to sync mode
|
||||
const auto sync = "sync:";
|
||||
send_host_request(socket, sync);
|
||||
|
||||
// SEND request: destination, permissions
|
||||
const auto send_request = std::string(dst) + "," + std::to_string(perm);
|
||||
const auto request_size = static_cast<uint32_t>(send_request.size());
|
||||
send_sync_request(socket, "SEND", request_size, send_request.data());
|
||||
|
||||
// DATA request: file data trunk, trunk size
|
||||
std::ifstream file(src.data(), std::ios::binary);
|
||||
const auto buf_size = 64000;
|
||||
std::array<char, buf_size> buffer;
|
||||
while (!file.eof()) {
|
||||
file.read(buffer.data(), buf_size);
|
||||
const auto bytes_read = static_cast<uint32_t>(file.gcount());
|
||||
send_sync_request(socket, "DATA", bytes_read, buffer.data());
|
||||
}
|
||||
file.close();
|
||||
|
||||
// DONE request: timestamp
|
||||
const auto now = std::chrono::system_clock::now().time_since_epoch();
|
||||
const auto timestamp = std::chrono::duration_cast<std::chrono::seconds>(now).count();
|
||||
const auto done_request = protocol::sync_request("DONE", static_cast<uint32_t>(timestamp));
|
||||
socket.write_some(asio::buffer(done_request));
|
||||
|
||||
std::string result;
|
||||
uint32_t length;
|
||||
protocol::sync_response(socket, result, length);
|
||||
if (result != "OKAY") {
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
std::string client_impl::root()
|
||||
{
|
||||
tcp::socket socket(m_context);
|
||||
asio::connect(socket, m_endpoints);
|
||||
|
||||
switch_to_device(socket);
|
||||
|
||||
const auto request = "root:";
|
||||
send_host_request(socket, request);
|
||||
|
||||
return protocol::host_data(socket);
|
||||
}
|
||||
|
||||
std::string client_impl::unroot()
|
||||
{
|
||||
tcp::socket socket(m_context);
|
||||
asio::connect(socket, m_endpoints);
|
||||
|
||||
switch_to_device(socket);
|
||||
|
||||
const auto request = "unroot:";
|
||||
send_host_request(socket, request);
|
||||
|
||||
return protocol::host_data(socket);
|
||||
}
|
||||
|
||||
std::shared_ptr<io_handle> client_impl::interactive_shell(const std::string_view command)
|
||||
{
|
||||
auto context = std::make_unique<asio::io_context>();
|
||||
tcp::socket socket(*context);
|
||||
asio::connect(socket, m_endpoints);
|
||||
|
||||
switch_to_device(socket);
|
||||
|
||||
const auto request = std::string("shell:") + command.data();
|
||||
send_host_request(socket, request);
|
||||
|
||||
return std::make_shared<io_handle_impl>(std::move(context), std::move(socket));
|
||||
}
|
||||
|
||||
void client_impl::wait_for_device()
|
||||
{
|
||||
// If adbd restarts, we should wait the device to get offline first.
|
||||
std::this_thread::sleep_for(std::chrono::seconds(1));
|
||||
|
||||
const auto pattern = m_serial + "\tdevice";
|
||||
while (devices().find(pattern) == std::string::npos) {
|
||||
std::this_thread::sleep_for(std::chrono::microseconds(500));
|
||||
}
|
||||
}
|
||||
|
||||
return std::string(buffer.data(), bytes_read);
|
||||
}
|
||||
|
||||
void io_handle_impl::write(const std::string_view data) {
|
||||
m_socket.write_some(asio::buffer(data));
|
||||
}
|
||||
|
||||
class client_impl : public client {
|
||||
public:
|
||||
client_impl(const std::string_view serial);
|
||||
std::string connect() override;
|
||||
std::string disconnect() override;
|
||||
std::string version() override;
|
||||
std::string devices() override;
|
||||
std::string shell(const std::string_view command) override;
|
||||
std::string exec(const std::string_view command) override;
|
||||
bool push(const std::string_view src, const std::string_view dst,
|
||||
int perm) override;
|
||||
std::shared_ptr<io_handle>
|
||||
interactive_shell(const std::string_view command) override;
|
||||
std::string root() override;
|
||||
std::string unroot() override;
|
||||
void wait_for_device() override;
|
||||
|
||||
private:
|
||||
friend class client;
|
||||
|
||||
std::string m_serial;
|
||||
asio::io_context m_context;
|
||||
tcp_endpoints m_endpoints;
|
||||
|
||||
/// Switch the connection to the device.
|
||||
/**
|
||||
* @param socket Opened adb connection.
|
||||
* @note Should be used only by the client class.
|
||||
* @note Local services (e.g. shell, push) can be requested after this.
|
||||
*/
|
||||
void switch_to_device(asio::ip::tcp::socket& socket);
|
||||
};
|
||||
|
||||
std::shared_ptr<client> client::create(const std::string_view serial) {
|
||||
return std::make_shared<client_impl>(serial);
|
||||
}
|
||||
|
||||
client_impl::client_impl(const std::string_view serial) {
|
||||
m_serial = serial;
|
||||
|
||||
tcp::resolver resolver(m_context);
|
||||
m_endpoints = resolver.resolve("127.0.0.1", "5037");
|
||||
}
|
||||
|
||||
std::string client_impl::connect() {
|
||||
tcp::socket socket(m_context);
|
||||
asio::connect(socket, m_endpoints);
|
||||
|
||||
const auto request = "host:connect:" + m_serial;
|
||||
send_host_request(socket, request);
|
||||
|
||||
return protocol::host_message(socket);
|
||||
}
|
||||
|
||||
std::string client_impl::disconnect() {
|
||||
tcp::socket socket(m_context);
|
||||
asio::connect(socket, m_endpoints);
|
||||
|
||||
const auto request = "host:disconnect:" + m_serial;
|
||||
send_host_request(socket, request);
|
||||
|
||||
return protocol::host_message(socket);
|
||||
}
|
||||
|
||||
std::string client_impl::version() {
|
||||
return adb::version(m_context, m_endpoints);
|
||||
}
|
||||
|
||||
std::string client_impl::devices() {
|
||||
return adb::devices(m_context, m_endpoints);
|
||||
}
|
||||
|
||||
std::string client_impl::shell(const std::string_view command) {
|
||||
tcp::socket socket(m_context);
|
||||
asio::connect(socket, m_endpoints);
|
||||
|
||||
switch_to_device(socket);
|
||||
|
||||
const auto request = std::string("shell:") + command.data();
|
||||
send_host_request(socket, request);
|
||||
|
||||
return protocol::host_data(socket);
|
||||
}
|
||||
|
||||
std::string client_impl::exec(const std::string_view command) {
|
||||
tcp::socket socket(m_context);
|
||||
asio::connect(socket, m_endpoints);
|
||||
|
||||
switch_to_device(socket);
|
||||
|
||||
const auto request = std::string("exec:") + command.data();
|
||||
send_host_request(socket, request);
|
||||
|
||||
return protocol::host_data(socket);
|
||||
}
|
||||
|
||||
bool client_impl::push(const std::string_view src, const std::string_view dst,
|
||||
int perm) {
|
||||
tcp::socket socket(m_context);
|
||||
asio::connect(socket, m_endpoints);
|
||||
|
||||
switch_to_device(socket);
|
||||
|
||||
// Switch to sync mode
|
||||
const auto sync = "sync:";
|
||||
send_host_request(socket, sync);
|
||||
|
||||
// SEND request: destination, permissions
|
||||
const auto send_request = std::string(dst) + "," + std::to_string(perm);
|
||||
const auto request_size = static_cast<uint32_t>(send_request.size());
|
||||
send_sync_request(socket, "SEND", request_size, send_request.data());
|
||||
|
||||
// DATA request: file data trunk, trunk size
|
||||
std::ifstream file(src.data(), std::ios::binary);
|
||||
const auto buf_size = 64000;
|
||||
std::array<char, buf_size> buffer;
|
||||
while (!file.eof()) {
|
||||
file.read(buffer.data(), buf_size);
|
||||
const auto bytes_read = static_cast<uint32_t>(file.gcount());
|
||||
send_sync_request(socket, "DATA", bytes_read, buffer.data());
|
||||
void client_impl::switch_to_device(tcp::socket& socket)
|
||||
{
|
||||
const auto request = "host:transport:" + m_serial;
|
||||
send_host_request(socket, request);
|
||||
}
|
||||
file.close();
|
||||
|
||||
// DONE request: timestamp
|
||||
const auto now = std::chrono::system_clock::now().time_since_epoch();
|
||||
const auto timestamp =
|
||||
std::chrono::duration_cast<std::chrono::seconds>(now).count();
|
||||
const auto done_request =
|
||||
protocol::sync_request("DONE", static_cast<uint32_t>(timestamp));
|
||||
socket.write_some(asio::buffer(done_request));
|
||||
|
||||
std::string result;
|
||||
uint32_t length;
|
||||
protocol::sync_response(socket, result, length);
|
||||
if (result != "OKAY") {
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
std::string client_impl::root() {
|
||||
tcp::socket socket(m_context);
|
||||
asio::connect(socket, m_endpoints);
|
||||
|
||||
switch_to_device(socket);
|
||||
|
||||
const auto request = "root:";
|
||||
send_host_request(socket, request);
|
||||
|
||||
return protocol::host_data(socket);
|
||||
}
|
||||
|
||||
std::string client_impl::unroot() {
|
||||
tcp::socket socket(m_context);
|
||||
asio::connect(socket, m_endpoints);
|
||||
|
||||
switch_to_device(socket);
|
||||
|
||||
const auto request = "unroot:";
|
||||
send_host_request(socket, request);
|
||||
|
||||
return protocol::host_data(socket);
|
||||
}
|
||||
|
||||
std::shared_ptr<io_handle>
|
||||
client_impl::interactive_shell(const std::string_view command) {
|
||||
auto context = std::make_unique<asio::io_context>();
|
||||
tcp::socket socket(*context);
|
||||
asio::connect(socket, m_endpoints);
|
||||
|
||||
switch_to_device(socket);
|
||||
|
||||
const auto request = std::string("shell:") + command.data();
|
||||
send_host_request(socket, request);
|
||||
|
||||
return std::make_shared<io_handle_impl>(std::move(context),
|
||||
std::move(socket));
|
||||
}
|
||||
|
||||
void client_impl::wait_for_device() {
|
||||
// If adbd restarts, we should wait the device to get offline first.
|
||||
std::this_thread::sleep_for(std::chrono::seconds(1));
|
||||
|
||||
const auto pattern = m_serial + "\tdevice";
|
||||
while (devices().find(pattern) == std::string::npos) {
|
||||
std::this_thread::sleep_for(std::chrono::microseconds(500));
|
||||
}
|
||||
}
|
||||
|
||||
void client_impl::switch_to_device(tcp::socket& socket) {
|
||||
const auto request = "host:transport:" + m_serial;
|
||||
send_host_request(socket, request);
|
||||
}
|
||||
|
||||
} // namespace adb
|
||||
|
||||
@@ -4,178 +4,177 @@
|
||||
#include <string>
|
||||
#include <string_view>
|
||||
|
||||
namespace adb {
|
||||
|
||||
/// Retrieve the version of local adb server.
|
||||
/**
|
||||
* @return 4-byte string of the version number.
|
||||
* @throw std::system_error if the server is not available.
|
||||
*/
|
||||
std::string version();
|
||||
|
||||
/// Retrieve the available Android devices.
|
||||
/**
|
||||
* @return A string of the list of devices.
|
||||
* @throw std::system_error if the server is not available.
|
||||
* @note Equivalent to `adb devices`.
|
||||
*/
|
||||
std::string devices();
|
||||
|
||||
/// Kill the adb server if it is running.
|
||||
/**
|
||||
* @throw std::system_error if the server is not running.
|
||||
* @note Equivalent to `adb kill-server`.
|
||||
*/
|
||||
void kill_server();
|
||||
|
||||
class io_handle_impl;
|
||||
|
||||
/// Context for an interactive adb connection.
|
||||
/**
|
||||
* @note Should be used only by the client class, after a shell request.
|
||||
* @note The socket will be closed when the handle is destroyed.
|
||||
*/
|
||||
class io_handle {
|
||||
public:
|
||||
virtual ~io_handle() = default;
|
||||
|
||||
/// Write data to the adb connection.
|
||||
/**
|
||||
* @param data Data to write.
|
||||
* @throw std::runtime_error Thrown on socket failure.
|
||||
* @note Typically used to write stdin of a shell command.
|
||||
* @note The data should end with a newline.
|
||||
*/
|
||||
virtual void write(const std::string_view data) = 0;
|
||||
|
||||
/// Read data from the adb connection.
|
||||
/**
|
||||
* @param timeout Timeout in seconds. 0 means no timeout.
|
||||
* @return Data read. Empty if timeout or the connection is closed.
|
||||
* @throw std::runtime_error Thrown on socket failure.
|
||||
* @note Typically used to read stdout of a shell command.
|
||||
*/
|
||||
virtual std::string read(unsigned timeout = 0) = 0;
|
||||
|
||||
protected:
|
||||
io_handle() = default;
|
||||
};
|
||||
|
||||
class client_impl;
|
||||
|
||||
/// A client for the Android Debug Bridge.
|
||||
class client {
|
||||
public:
|
||||
/// Create a client for a specific device.
|
||||
/**
|
||||
* @param serial serial number of the device.
|
||||
* @note If the serial is empty, the unique device will be used. If there
|
||||
* are multiple devices, an exception will be thrown.
|
||||
*/
|
||||
static std::shared_ptr<client> create(const std::string_view serial);
|
||||
virtual ~client() = default;
|
||||
|
||||
/// Connect to the device.
|
||||
/**
|
||||
* @return A string of the connection status.
|
||||
* @throw std::system_error if the server is not available.
|
||||
* @note Equivalent to `adb connect <serial>`.
|
||||
*/
|
||||
virtual std::string connect() = 0;
|
||||
|
||||
/// Disconnect from the device.
|
||||
/**
|
||||
* @return A string of the disconnection status.
|
||||
* @throw std::system_error if the server is not available.
|
||||
* @note Equivalent to `adb disconnect <serial>`.
|
||||
*/
|
||||
virtual std::string disconnect() = 0;
|
||||
|
||||
namespace adb
|
||||
{
|
||||
/// Retrieve the version of local adb server.
|
||||
/**
|
||||
* @return 4-byte string of the version number.
|
||||
* @throw std::system_error if the server is not available.
|
||||
* @note This function reuses the class member io_context, which is
|
||||
* thread-safe for the client.
|
||||
*/
|
||||
virtual std::string version() = 0;
|
||||
std::string version();
|
||||
|
||||
/// Retrieve the available Android devices.
|
||||
/**
|
||||
* @return A string of the list of devices.
|
||||
* @throw std::system_error if the server is not available.
|
||||
* @note Equivalent to `adb devices`.
|
||||
* @note This function reuses the class member io_context, which is
|
||||
* thread-safe for the client.
|
||||
*/
|
||||
virtual std::string devices() = 0;
|
||||
std::string devices();
|
||||
|
||||
/// Send an one-shot shell command to the device.
|
||||
/// Kill the adb server if it is running.
|
||||
/**
|
||||
* @param command Command to execute.
|
||||
* @return A string of the command output.
|
||||
* @throw std::system_error if the server is not available.
|
||||
* @note Equivalent to `adb -s <serial> shell <command>` without stdin.
|
||||
* @throw std::system_error if the server is not running.
|
||||
* @note Equivalent to `adb kill-server`.
|
||||
*/
|
||||
virtual std::string shell(const std::string_view command) = 0;
|
||||
void kill_server();
|
||||
|
||||
/// Send an one-shot shell command to the device, using raw PTY.
|
||||
class io_handle_impl;
|
||||
|
||||
/// Context for an interactive adb connection.
|
||||
/**
|
||||
* @param command Command to execute.
|
||||
* @return A string of the command output, which is not mangled.
|
||||
* @throw std::system_error if the server is not available.
|
||||
* @note Equivalent to `adb -s <serial> exec-out <command>` without stdin.
|
||||
* @note Should be used only by the client class, after a shell request.
|
||||
* @note The socket will be closed when the handle is destroyed.
|
||||
*/
|
||||
virtual std::string exec(const std::string_view command) = 0;
|
||||
class io_handle
|
||||
{
|
||||
public:
|
||||
virtual ~io_handle() = default;
|
||||
|
||||
/// Send a file to the device.
|
||||
/**
|
||||
* @return true if the file is successfully sent.
|
||||
* @param src Path to the source file.
|
||||
* @param dst Path to the destination file.
|
||||
* @param perm Permission of the destination file.
|
||||
* @throw std::system_error if the server is not available.
|
||||
* @note Equivalent to `adb -s <serial> push <src> <dst>`.
|
||||
*/
|
||||
virtual bool push(const std::string_view src, const std::string_view dst,
|
||||
int perm) = 0;
|
||||
/// Write data to the adb connection.
|
||||
/**
|
||||
* @param data Data to write.
|
||||
* @throw std::runtime_error Thrown on socket failure.
|
||||
* @note Typically used to write stdin of a shell command.
|
||||
* @note The data should end with a newline.
|
||||
*/
|
||||
virtual void write(const std::string_view data) = 0;
|
||||
|
||||
/// Set the user of adbd to root on the device.
|
||||
/**
|
||||
* @throw std::system_error if the server is not available.
|
||||
* @note Equivalent to `adb -s <serial> root`.
|
||||
* @note The device might be offline after this command. Remember to wait
|
||||
* for the restart.
|
||||
*/
|
||||
virtual std::string root() = 0;
|
||||
/// Read data from the adb connection.
|
||||
/**
|
||||
* @param timeout Timeout in seconds. 0 means no timeout.
|
||||
* @return Data read. Empty if timeout or the connection is closed.
|
||||
* @throw std::runtime_error Thrown on socket failure.
|
||||
* @note Typically used to read stdout of a shell command.
|
||||
*/
|
||||
virtual std::string read(unsigned timeout = 0) = 0;
|
||||
|
||||
/// Set the user of adbd to non-root on the device.
|
||||
/**
|
||||
* @throw std::system_error if the server is not available.
|
||||
* @note Equivalent to `adb -s <serial> unroot`.
|
||||
* @note The device might be offline after this command. Remember to wait
|
||||
* for the restart.
|
||||
*/
|
||||
virtual std::string unroot() = 0;
|
||||
protected:
|
||||
io_handle() = default;
|
||||
};
|
||||
|
||||
/// Start an interactive shell session on the device.
|
||||
/**
|
||||
* @param command Command to execute.
|
||||
* @return An io_handle for the interactive session.
|
||||
* @throw std::system_error if the server is not available.
|
||||
* @note Equivalent to `adb -s <serial> shell <command>` with stdin.
|
||||
*/
|
||||
virtual std::shared_ptr<io_handle>
|
||||
interactive_shell(const std::string_view command) = 0;
|
||||
class client_impl;
|
||||
|
||||
/// Wait for the device to be available.
|
||||
/**
|
||||
* @throw std::system_error if the server is not available.
|
||||
*/
|
||||
virtual void wait_for_device() = 0;
|
||||
/// A client for the Android Debug Bridge.
|
||||
class client
|
||||
{
|
||||
public:
|
||||
/// Create a client for a specific device.
|
||||
/**
|
||||
* @param serial serial number of the device.
|
||||
* @note If the serial is empty, the unique device will be used. If there
|
||||
* are multiple devices, an exception will be thrown.
|
||||
*/
|
||||
static std::shared_ptr<client> create(const std::string_view serial);
|
||||
virtual ~client() = default;
|
||||
|
||||
protected:
|
||||
client() = default;
|
||||
};
|
||||
/// Connect to the device.
|
||||
/**
|
||||
* @return A string of the connection status.
|
||||
* @throw std::system_error if the server is not available.
|
||||
* @note Equivalent to `adb connect <serial>`.
|
||||
*/
|
||||
virtual std::string connect() = 0;
|
||||
|
||||
/// Disconnect from the device.
|
||||
/**
|
||||
* @return A string of the disconnection status.
|
||||
* @throw std::system_error if the server is not available.
|
||||
* @note Equivalent to `adb disconnect <serial>`.
|
||||
*/
|
||||
virtual std::string disconnect() = 0;
|
||||
|
||||
/// Retrieve the version of local adb server.
|
||||
/**
|
||||
* @return 4-byte string of the version number.
|
||||
* @throw std::system_error if the server is not available.
|
||||
* @note This function reuses the class member io_context, which is
|
||||
* thread-safe for the client.
|
||||
*/
|
||||
virtual std::string version() = 0;
|
||||
|
||||
/// Retrieve the available Android devices.
|
||||
/**
|
||||
* @return A string of the list of devices.
|
||||
* @throw std::system_error if the server is not available.
|
||||
* @note Equivalent to `adb devices`.
|
||||
* @note This function reuses the class member io_context, which is
|
||||
* thread-safe for the client.
|
||||
*/
|
||||
virtual std::string devices() = 0;
|
||||
|
||||
/// Send an one-shot shell command to the device.
|
||||
/**
|
||||
* @param command Command to execute.
|
||||
* @return A string of the command output.
|
||||
* @throw std::system_error if the server is not available.
|
||||
* @note Equivalent to `adb -s <serial> shell <command>` without stdin.
|
||||
*/
|
||||
virtual std::string shell(const std::string_view command) = 0;
|
||||
|
||||
/// Send an one-shot shell command to the device, using raw PTY.
|
||||
/**
|
||||
* @param command Command to execute.
|
||||
* @return A string of the command output, which is not mangled.
|
||||
* @throw std::system_error if the server is not available.
|
||||
* @note Equivalent to `adb -s <serial> exec-out <command>` without stdin.
|
||||
*/
|
||||
virtual std::string exec(const std::string_view command) = 0;
|
||||
|
||||
/// Send a file to the device.
|
||||
/**
|
||||
* @return true if the file is successfully sent.
|
||||
* @param src Path to the source file.
|
||||
* @param dst Path to the destination file.
|
||||
* @param perm Permission of the destination file.
|
||||
* @throw std::system_error if the server is not available.
|
||||
* @note Equivalent to `adb -s <serial> push <src> <dst>`.
|
||||
*/
|
||||
virtual bool push(const std::string_view src, const std::string_view dst, int perm) = 0;
|
||||
|
||||
/// Set the user of adbd to root on the device.
|
||||
/**
|
||||
* @throw std::system_error if the server is not available.
|
||||
* @note Equivalent to `adb -s <serial> root`.
|
||||
* @note The device might be offline after this command. Remember to wait
|
||||
* for the restart.
|
||||
*/
|
||||
virtual std::string root() = 0;
|
||||
|
||||
/// Set the user of adbd to non-root on the device.
|
||||
/**
|
||||
* @throw std::system_error if the server is not available.
|
||||
* @note Equivalent to `adb -s <serial> unroot`.
|
||||
* @note The device might be offline after this command. Remember to wait
|
||||
* for the restart.
|
||||
*/
|
||||
virtual std::string unroot() = 0;
|
||||
|
||||
/// Start an interactive shell session on the device.
|
||||
/**
|
||||
* @param command Command to execute.
|
||||
* @return An io_handle for the interactive session.
|
||||
* @throw std::system_error if the server is not available.
|
||||
* @note Equivalent to `adb -s <serial> shell <command>` with stdin.
|
||||
*/
|
||||
virtual std::shared_ptr<io_handle> interactive_shell(const std::string_view command) = 0;
|
||||
|
||||
/// Wait for the device to be available.
|
||||
/**
|
||||
* @throw std::system_error if the server is not available.
|
||||
*/
|
||||
virtual void wait_for_device() = 0;
|
||||
|
||||
protected:
|
||||
client() = default;
|
||||
};
|
||||
} // namespace adb
|
||||
|
||||
@@ -5,108 +5,113 @@
|
||||
|
||||
using asio::ip::tcp;
|
||||
|
||||
namespace adb::protocol {
|
||||
|
||||
/// Encoded the ADB host request.
|
||||
/**
|
||||
* @param body Body of the request.
|
||||
* @return Encoded request.
|
||||
*/
|
||||
static inline std::string host_request(const std::string_view body) {
|
||||
std::stringstream ss;
|
||||
ss << std::setfill('0') << std::setw(4) << std::hex << body.size() << body;
|
||||
return ss.str();
|
||||
}
|
||||
|
||||
/// Receive and check the response.
|
||||
/**
|
||||
* @param socket Opened adb connection.
|
||||
* @param failure Error message if the response is not OKAY.
|
||||
* @return `true` if the response is OKAY, `false` otherwise.
|
||||
* @throw std::runtime_error Thrown on socket failure
|
||||
*/
|
||||
static inline bool host_response(tcp::socket& socket, std::string& failure) {
|
||||
std::array<char, 4> header;
|
||||
socket.read_some(asio::buffer(header));
|
||||
const auto result = std::string_view(header.data(), 4);
|
||||
if (result == "OKAY") {
|
||||
return true;
|
||||
namespace adb::protocol
|
||||
{
|
||||
/// Encoded the ADB host request.
|
||||
/**
|
||||
* @param body Body of the request.
|
||||
* @return Encoded request.
|
||||
*/
|
||||
static inline std::string host_request(const std::string_view body)
|
||||
{
|
||||
std::stringstream ss;
|
||||
ss << std::setfill('0') << std::setw(4) << std::hex << body.size() << body;
|
||||
return ss.str();
|
||||
}
|
||||
|
||||
if (result != "FAIL") {
|
||||
failure = "unknown response";
|
||||
/// Receive and check the response.
|
||||
/**
|
||||
* @param socket Opened adb connection.
|
||||
* @param failure Error message if the response is not OKAY.
|
||||
* @return `true` if the response is OKAY, `false` otherwise.
|
||||
* @throw std::runtime_error Thrown on socket failure
|
||||
*/
|
||||
static inline bool host_response(tcp::socket& socket, std::string& failure)
|
||||
{
|
||||
std::array<char, 4> header;
|
||||
socket.read_some(asio::buffer(header));
|
||||
const auto result = std::string_view(header.data(), 4);
|
||||
if (result == "OKAY") {
|
||||
return true;
|
||||
}
|
||||
|
||||
if (result != "FAIL") {
|
||||
failure = "unknown response";
|
||||
return false;
|
||||
}
|
||||
|
||||
failure = host_message(socket);
|
||||
return false;
|
||||
}
|
||||
|
||||
failure = host_message(socket);
|
||||
return false;
|
||||
}
|
||||
std::string host_message(tcp::socket& socket)
|
||||
{
|
||||
std::array<char, 4> header;
|
||||
socket.read_some(asio::buffer(header));
|
||||
auto remain = std::stoull(std::string(header.data(), 4), nullptr, 16);
|
||||
|
||||
std::string host_message(tcp::socket& socket) {
|
||||
std::array<char, 4> header;
|
||||
socket.read_some(asio::buffer(header));
|
||||
auto remain = std::stoull(std::string(header.data(), 4), nullptr, 16);
|
||||
|
||||
std::string message;
|
||||
std::array<char, 1024> buffer;
|
||||
while (remain > 0) {
|
||||
const auto length = socket.read_some(asio::buffer(buffer));
|
||||
message.append(buffer.data(), length);
|
||||
remain -= length;
|
||||
}
|
||||
|
||||
return message;
|
||||
}
|
||||
|
||||
std::string host_data(tcp::socket& socket) {
|
||||
std::string data;
|
||||
std::array<char, 1024> buffer;
|
||||
asio::error_code ec;
|
||||
|
||||
while (!ec) {
|
||||
const auto length = socket.read_some(asio::buffer(buffer), ec);
|
||||
if (ec == asio::error::eof) {
|
||||
break;
|
||||
std::string message;
|
||||
std::array<char, 1024> buffer;
|
||||
while (remain > 0) {
|
||||
const auto length = socket.read_some(asio::buffer(buffer));
|
||||
message.append(buffer.data(), length);
|
||||
remain -= length;
|
||||
}
|
||||
data.append(buffer.data(), length);
|
||||
|
||||
return message;
|
||||
}
|
||||
|
||||
return data;
|
||||
}
|
||||
std::string host_data(tcp::socket& socket)
|
||||
{
|
||||
std::string data;
|
||||
std::array<char, 1024> buffer;
|
||||
asio::error_code ec;
|
||||
|
||||
std::string sync_request(const std::string_view id, const uint32_t length) {
|
||||
const auto len = {
|
||||
static_cast<char>(length & 0xff),
|
||||
static_cast<char>((length >> 8) & 0xff),
|
||||
static_cast<char>((length >> 16) & 0xff),
|
||||
static_cast<char>((length >> 24) & 0xff),
|
||||
};
|
||||
while (!ec) {
|
||||
const auto length = socket.read_some(asio::buffer(buffer), ec);
|
||||
if (ec == asio::error::eof) {
|
||||
break;
|
||||
}
|
||||
data.append(buffer.data(), length);
|
||||
}
|
||||
|
||||
return std::string(id) + std::string(len.begin(), len.end());
|
||||
}
|
||||
|
||||
void sync_response(tcp::socket& socket, std::string& id, uint32_t& length) {
|
||||
std::array<char, 8> response;
|
||||
socket.read_some(asio::buffer(response));
|
||||
|
||||
id = std::string(response.data(), 4);
|
||||
length = response[4] | (response[5] << 8) | (response[6] << 16) |
|
||||
(response[7] << 24);
|
||||
}
|
||||
|
||||
void send_host_request(tcp::socket& socket, const std::string_view request) {
|
||||
socket.write_some(asio::buffer(protocol::host_request(request)));
|
||||
std::string failure;
|
||||
if (!protocol::host_response(socket, failure)) {
|
||||
throw std::runtime_error(failure);
|
||||
return data;
|
||||
}
|
||||
}
|
||||
|
||||
void send_sync_request(tcp::socket& socket, const std::string_view id,
|
||||
uint32_t length, const char* body) {
|
||||
auto data_request = protocol::sync_request(id, length);
|
||||
socket.write_some(asio::buffer(data_request));
|
||||
socket.write_some(asio::buffer(body, length));
|
||||
}
|
||||
std::string sync_request(const std::string_view id, const uint32_t length)
|
||||
{
|
||||
const auto len = {
|
||||
static_cast<char>(length & 0xff),
|
||||
static_cast<char>((length >> 8) & 0xff),
|
||||
static_cast<char>((length >> 16) & 0xff),
|
||||
static_cast<char>((length >> 24) & 0xff),
|
||||
};
|
||||
|
||||
return std::string(id) + std::string(len.begin(), len.end());
|
||||
}
|
||||
|
||||
void sync_response(tcp::socket& socket, std::string& id, uint32_t& length)
|
||||
{
|
||||
std::array<char, 8> response;
|
||||
socket.read_some(asio::buffer(response));
|
||||
|
||||
id = std::string(response.data(), 4);
|
||||
length = response[4] | (response[5] << 8) | (response[6] << 16) | (response[7] << 24);
|
||||
}
|
||||
|
||||
void send_host_request(tcp::socket& socket, const std::string_view request)
|
||||
{
|
||||
socket.write_some(asio::buffer(protocol::host_request(request)));
|
||||
std::string failure;
|
||||
if (!protocol::host_response(socket, failure)) {
|
||||
throw std::runtime_error(failure);
|
||||
}
|
||||
}
|
||||
|
||||
void send_sync_request(tcp::socket& socket, const std::string_view id, uint32_t length, const char* body)
|
||||
{
|
||||
auto data_request = protocol::sync_request(id, length);
|
||||
socket.write_some(asio::buffer(data_request));
|
||||
socket.write_some(asio::buffer(body, length));
|
||||
}
|
||||
} // namespace adb::protocol
|
||||
|
||||
@@ -4,60 +4,57 @@
|
||||
|
||||
#include <asio/ip/tcp.hpp>
|
||||
|
||||
namespace adb::protocol {
|
||||
namespace adb::protocol
|
||||
{
|
||||
/// Receive encoded data from the host.
|
||||
/**
|
||||
* @param socket Opened adb connection.
|
||||
* @return Data from the host.
|
||||
* @throw std::runtime_error Thrown on socket failure.
|
||||
*/
|
||||
std::string host_message(asio::ip::tcp::socket& socket);
|
||||
|
||||
/// Receive encoded data from the host.
|
||||
/**
|
||||
* @param socket Opened adb connection.
|
||||
* @return Data from the host.
|
||||
* @throw std::runtime_error Thrown on socket failure.
|
||||
*/
|
||||
std::string host_message(asio::ip::tcp::socket& socket);
|
||||
/// Receive all data from the host.
|
||||
/**
|
||||
* @param socket Opened adb connection.
|
||||
* @return Data from the host.
|
||||
* @throw std::runtime_error Thrown on socket failure.
|
||||
* @note The function will keep reading until the connection is closed.
|
||||
*/
|
||||
std::string host_data(asio::ip::tcp::socket& socket);
|
||||
|
||||
/// Receive all data from the host.
|
||||
/**
|
||||
* @param socket Opened adb connection.
|
||||
* @return Data from the host.
|
||||
* @throw std::runtime_error Thrown on socket failure.
|
||||
* @note The function will keep reading until the connection is closed.
|
||||
*/
|
||||
std::string host_data(asio::ip::tcp::socket& socket);
|
||||
/// Encode the ADB sync request.
|
||||
/**
|
||||
* @param id 4-byte string of the request id.
|
||||
* @param length Length of the body.
|
||||
*/
|
||||
std::string sync_request(const std::string_view id, const uint32_t length);
|
||||
|
||||
/// Encode the ADB sync request.
|
||||
/**
|
||||
* @param id 4-byte string of the request id.
|
||||
* @param length Length of the body.
|
||||
*/
|
||||
std::string sync_request(const std::string_view id, const uint32_t length);
|
||||
/// Receive the sync response.
|
||||
/**
|
||||
* @param socket Opened adb connection.
|
||||
* @param id 4-byte string of the response id.
|
||||
* @param length Length of the body.
|
||||
* @throw std::runtime_error Thrown on socket failure.
|
||||
*/
|
||||
void sync_response(asio::ip::tcp::socket& socket, std::string& id, uint32_t& length);
|
||||
|
||||
/// Receive the sync response.
|
||||
/**
|
||||
* @param socket Opened adb connection.
|
||||
* @param id 4-byte string of the response id.
|
||||
* @param length Length of the body.
|
||||
* @throw std::runtime_error Thrown on socket failure.
|
||||
*/
|
||||
void sync_response(asio::ip::tcp::socket& socket, std::string& id,
|
||||
uint32_t& length);
|
||||
|
||||
/// Send an ADB host request and check its response.
|
||||
/**
|
||||
* @param socket Opened adb connection.
|
||||
* @param request Encoded request.
|
||||
* @throw std::runtime_error Thrown on socket failure or adb FAIL response.
|
||||
*/
|
||||
void send_host_request(asio::ip::tcp::socket& socket,
|
||||
const std::string_view request);
|
||||
|
||||
/// Send an ADB sync request.
|
||||
/**
|
||||
* @param socket Opened adb connection.
|
||||
* @param id 4-byte string of the request id.
|
||||
* @param length Length of the body.
|
||||
* @param body Body of the request.
|
||||
* @throw std::runtime_error Thrown on socket failure.
|
||||
*/
|
||||
void send_sync_request(asio::ip::tcp::socket& socket, const std::string_view id,
|
||||
const uint32_t length, const char* body);
|
||||
/// Send an ADB host request and check its response.
|
||||
/**
|
||||
* @param socket Opened adb connection.
|
||||
* @param request Encoded request.
|
||||
* @throw std::runtime_error Thrown on socket failure or adb FAIL response.
|
||||
*/
|
||||
void send_host_request(asio::ip::tcp::socket& socket, const std::string_view request);
|
||||
|
||||
/// Send an ADB sync request.
|
||||
/**
|
||||
* @param socket Opened adb connection.
|
||||
* @param id 4-byte string of the request id.
|
||||
* @param length Length of the body.
|
||||
* @param body Body of the request.
|
||||
* @throw std::runtime_error Thrown on socket failure.
|
||||
*/
|
||||
void send_sync_request(asio::ip::tcp::socket& socket, const std::string_view id, const uint32_t length,
|
||||
const char* body);
|
||||
} // namespace adb::protocol
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
#include "DrGrandetTaskPlugin.h"
|
||||
|
||||
#include "Controller/Controller.h"
|
||||
#include "Config/TaskData.h"
|
||||
#include "Controller/Controller.h"
|
||||
#include "Utils/Logger.hpp"
|
||||
#include "Vision/OcrImageAnalyzer.h"
|
||||
|
||||
@@ -74,4 +74,4 @@ int asst::DrGrandetTaskPlugin::analyze_time_left()
|
||||
|
||||
Log.info("Time left ms:", millisec);
|
||||
return millisec;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -5,8 +5,8 @@
|
||||
#include <utility>
|
||||
|
||||
#include "Common/AsstMsg.h"
|
||||
#include "Controller/Controller.h"
|
||||
#include "Config/TaskData.h"
|
||||
#include "Controller/Controller.h"
|
||||
#include "Task/ProcessTask.h"
|
||||
#include "Utils/Logger.hpp"
|
||||
#include "Utils/Ranges.hpp"
|
||||
|
||||
@@ -2,8 +2,8 @@
|
||||
|
||||
#include "Utils/Ranges.hpp"
|
||||
|
||||
#include "Controller/Controller.h"
|
||||
#include "Config/TaskData.h"
|
||||
#include "Controller/Controller.h"
|
||||
#include "Task/ProcessTask.h"
|
||||
#include "Utils/Logger.hpp"
|
||||
#include "Vision/Infrast/InfrastClueImageAnalyzer.h"
|
||||
|
||||
@@ -3,8 +3,8 @@
|
||||
#include <algorithm>
|
||||
#include <vector>
|
||||
|
||||
#include "Controller/Controller.h"
|
||||
#include "Config/TaskData.h"
|
||||
#include "Controller/Controller.h"
|
||||
#include "Task/ProcessTask.h"
|
||||
#include "Utils/Logger.hpp"
|
||||
#include "Vision/MatchImageAnalyzer.h"
|
||||
|
||||
@@ -4,9 +4,9 @@
|
||||
|
||||
#include <meojson/json.hpp>
|
||||
|
||||
#include "Controller/Controller.h"
|
||||
#include "Config/GeneralConfig.h"
|
||||
#include "Config/TaskData.h"
|
||||
#include "Controller/Controller.h"
|
||||
#include "Task/ProcessTask.h"
|
||||
#include "Utils/Logger.hpp"
|
||||
#include "Vision/Miscellaneous/DepotImageAnalyzer.h"
|
||||
|
||||
@@ -2,8 +2,8 @@
|
||||
|
||||
#include <regex>
|
||||
|
||||
#include "Controller/Controller.h"
|
||||
#include "Config/TaskData.h"
|
||||
#include "Controller/Controller.h"
|
||||
#include "Status.h"
|
||||
#include "Task/ProcessTask.h"
|
||||
#include "Utils/Logger.hpp"
|
||||
|
||||
@@ -48,7 +48,6 @@ bool asst::ReclamationControlTask::run_giveup_upon_fight_procedure()
|
||||
RunCheckSuccess(wait_between_day);
|
||||
skip_announce_report();
|
||||
while (!need_exit() && !check_emergency()) {
|
||||
|
||||
RunCheckSuccess(reset_scope);
|
||||
RunCheckSuccess(click_center_base);
|
||||
RunCheckSuccess(click_any_zone);
|
||||
@@ -80,7 +79,6 @@ bool asst::ReclamationControlTask::run_smelt_gold_procedure()
|
||||
|
||||
bool buy_result = false;
|
||||
while (!need_exit() && !buy_result) {
|
||||
|
||||
RunCheckSuccess(reset_scope);
|
||||
RunCheckSuccess(click_corner_black_market);
|
||||
RunCheckSuccess(click_black_market);
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
#include "RoguelikeCustomStartTaskPlugin.h"
|
||||
|
||||
#include "Controller/Controller.h"
|
||||
#include "Config/Miscellaneous/BattleDataConfig.h"
|
||||
#include "Config/TaskData.h"
|
||||
#include "Controller/Controller.h"
|
||||
#include "Status.h"
|
||||
#include "Task/ProcessTask.h"
|
||||
#include "Utils/Logger.hpp"
|
||||
|
||||
@@ -2,8 +2,8 @@
|
||||
|
||||
#include "Utils/Ranges.hpp"
|
||||
|
||||
#include "Controller/Controller.h"
|
||||
#include "Config/TaskData.h"
|
||||
#include "Controller/Controller.h"
|
||||
#include "Status.h"
|
||||
#include "Task/ProcessTask.h"
|
||||
#include "Utils/Logger.hpp"
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
#include "RoguelikeShoppingTaskPlugin.h"
|
||||
|
||||
#include "Controller/Controller.h"
|
||||
#include "Config/Miscellaneous/BattleDataConfig.h"
|
||||
#include "Config/Roguelike/RoguelikeShoppingConfig.h"
|
||||
#include "Controller/Controller.h"
|
||||
#include "Status.h"
|
||||
#include "Task/ProcessTask.h"
|
||||
#include "Utils/Logger.hpp"
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
#include "RoguelikeSkillSelectionTaskPlugin.h"
|
||||
|
||||
#include "Controller/Controller.h"
|
||||
#include "Config/Roguelike/RoguelikeRecruitConfig.h"
|
||||
#include "Config/TaskData.h"
|
||||
#include "Controller/Controller.h"
|
||||
#include "Status.h"
|
||||
#include "Vision/Roguelike/RoguelikeSkillSelectionImageAnalyzer.h"
|
||||
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
#pragma once
|
||||
|
||||
#include <filesystem>
|
||||
#include <Utils/Ranges.hpp>
|
||||
#include <filesystem>
|
||||
|
||||
namespace asst::utils
|
||||
{
|
||||
@@ -9,18 +9,21 @@ namespace asst::utils
|
||||
concept ByteValueType = std::is_integral_v<ValueType> && sizeof(ValueType) == 1;
|
||||
|
||||
template <typename ContainerType>
|
||||
concept AppendableBytesContainer = requires(ContainerType a)
|
||||
{
|
||||
requires ranges::contiguous_range<ContainerType>;
|
||||
requires ByteValueType<typename ContainerType::value_type>;
|
||||
requires std::is_constructible_v<ContainerType>;
|
||||
requires std::is_constructible_v<ContainerType, size_t, typename ContainerType::value_type>; // std::string(count, ch), std::vector(count, value)
|
||||
a.insert(a.end(), a.begin(), a.begin() + (size_t)1);
|
||||
a.resize(a.size());
|
||||
};
|
||||
concept AppendableBytesContainer =
|
||||
requires(ContainerType a) {
|
||||
requires ranges::contiguous_range<ContainerType>;
|
||||
requires ByteValueType<typename ContainerType::value_type>;
|
||||
requires std::is_constructible_v<ContainerType>;
|
||||
requires std::is_constructible_v<ContainerType, size_t,
|
||||
typename ContainerType::value_type>; // std::string(count, ch),
|
||||
// std::vector(count, value)
|
||||
a.insert(a.end(), a.begin(), a.begin() + (size_t)1);
|
||||
a.resize(a.size());
|
||||
};
|
||||
|
||||
template<AppendableBytesContainer ContainerType>
|
||||
ContainerType read_file(const std::filesystem::path& path) {
|
||||
template <AppendableBytesContainer ContainerType>
|
||||
ContainerType read_file(const std::filesystem::path& path)
|
||||
{
|
||||
ContainerType result;
|
||||
std::ifstream file(path, std::ios::binary | std::ios::ate);
|
||||
auto fileSize = file.tellg();
|
||||
|
||||
@@ -51,4 +51,4 @@ namespace asst
|
||||
{
|
||||
return imwrite(asst::utils::path(utf8_path), img, params);
|
||||
}
|
||||
} // namespace asst
|
||||
} // namespace asst
|
||||
|
||||
@@ -3,8 +3,8 @@
|
||||
#include <regex>
|
||||
#include <unordered_map>
|
||||
|
||||
#include "Config/Miscellaneous/OcrPack.h"
|
||||
#include "Config/Miscellaneous/OcrConfig.h"
|
||||
#include "Config/Miscellaneous/OcrPack.h"
|
||||
#include "Config/TaskData.h"
|
||||
#include "Utils/Logger.hpp"
|
||||
|
||||
@@ -112,11 +112,13 @@ void asst::OcrImageAnalyzer::set_use_cache(bool is_use) noexcept
|
||||
|
||||
void asst::OcrImageAnalyzer::set_required(std::vector<std::string> required) noexcept
|
||||
{
|
||||
ranges::for_each(required, [](std::string& str) { str = OcrConfig::get_instance().process_equivalence_class(str); });
|
||||
ranges::for_each(required,
|
||||
[](std::string& str) { str = OcrConfig::get_instance().process_equivalence_class(str); });
|
||||
m_required = std::move(required);
|
||||
}
|
||||
|
||||
void asst::OcrImageAnalyzer::set_replace(const std::unordered_map<std::string, std::string>& replace, bool replace_full) noexcept
|
||||
void asst::OcrImageAnalyzer::set_replace(const std::unordered_map<std::string, std::string>& replace,
|
||||
bool replace_full) noexcept
|
||||
{
|
||||
m_replace = {};
|
||||
for (auto&& [key, val] : replace) {
|
||||
|
||||
@@ -25,7 +25,8 @@ namespace asst
|
||||
virtual void sort_result_by_required(); // 按传入的需求数组排序,传入的在前面结果接在前面
|
||||
|
||||
void set_required(std::vector<std::string> required) noexcept;
|
||||
void set_replace(const std::unordered_map<std::string, std::string>& replace, bool replace_full = false) noexcept;
|
||||
void set_replace(const std::unordered_map<std::string, std::string>& replace,
|
||||
bool replace_full = false) noexcept;
|
||||
|
||||
virtual void set_task_info(std::shared_ptr<TaskInfo> task_ptr);
|
||||
virtual void set_task_info(const std::string& task_name);
|
||||
|
||||
Reference in New Issue
Block a user