WiFiMouseServer手机等作为远程输入

发布于:2025-07-21 ⋅ 阅读:(22) ⋅ 点赞:(0)

将代码保存为myWifiMouse.cpp, 在MSYS终端编译运行这个服务端,

$ cd   /source_dir_path/

 $ g++ -std=c++14 -o myWifiMouse myWifiMouse.cpp -lws2_32 && ./myWifiMouse.exe

/*
--------------------通信协议--------------------

鼠标数据帧格式:
mos+'  '+len+func+' '+data
mos:为固定标识,注意:mos后是两个空格
len:func加data的字节长度,len与func之间是没有空格的
func:有3个分别为R(按键),m(移动),w(滚轮),c(左键点击)
data:有3种,
	按键:l左键、r右键、m中键,按下为d,释放为u,
		按键数据举例为:"l d"、"l u"、"m d"、"m u";
	移动:分别为xy坐标,
		移动数据举例为:"1 5"、"0 -8"、"-1 0"、"-5 -5";
	滚轮:只不滚动值,要么正,要么负;
	

下面是鼠标数据帧举例: 
	左键点击一次:"mos  1c"
	左键按下:"mos  5R l d"
	左键释放:"mos  5R l u"
	右键按下:"mos  5R r d"
	右键释放:"mos  5R r u"
	中键按下:"mos  5R m d"
	中键释放:"mos  5R m u"
	移动:"mos  5m 0 3"
	滚轮:"mos  3w 0"
	滚轮:"mos  3w 1"
	
键盘数据帧格式:
key+'  '+len+data
key:为固定标识,注意:key后是2个空格
len:data的字节长度,len与data之间是没有空格的
data:为键盘操作输入数据
下面是键盘数据帧举例:
	回车键:"key  3RTN"
	退格键:"key  3BAS"
	
输入法数据帧格式:
utf8+' '+data
utf8:为固定标识,注意:utf8后是1个空格
data:为字符文字数据
下面是键盘数据帧举例:
	"utf8 abdsd":接收到字符串"abdsd"
	"utf8 好的,好东西":接收到字符串"好的,好东西"

--------------------通信协议--------------------

*/
#include <iostream>
#include <thread>
#include <mutex>
#include <unordered_map>
#include <string>
#include <winsock2.h>
#include <windows.h>
#include <ctime>
#include <list>
#pragma comment(lib, "ws2_32.lib")

// 配置日志(包含帧计数信息)
// 定义日志宏,用于输出不同级别的日志信息
// LOG_INFO 用于输出信息级别的日志
#define LOG_INFO(msg) std::cout << getCurrentTime()<<" "<< __LINE__ << " - INFO - " << msg << std::endl
// LOG_ERROR 用于输出错误级别的日志
#define LOG_ERROR(msg) std::cerr << getCurrentTime()<<" "<< __LINE__ << " - ERROR - " << msg << std::endl
// LOG_WARNING 用于输出警告级别的日志
#define LOG_WARNING(msg) std::cout << getCurrentTime()<<" "<< __LINE__ << " - WARNING - " << msg << std::endl
// LOG_DEBUG 用于输出调试级别的日志
#define LOG_DEBUG(msg) std::cout << getCurrentTime()<<" "<< __LINE__ << " - DEBUG - " << msg << std::endl

// 获取当前时间的函数,返回一个字符串表示当前时间
std::string getCurrentTime() {
    time_t now = time(0);
    char* dt = ctime(&now);
    std::string timeStr(dt);
    timeStr.pop_back();  // 去掉换行符
    return timeStr;
}

// WiFiMouseServer 类,用于实现一个WiFi鼠标服务器
class WiFiMouseServer {
public:
    // 构造函数,初始化服务器的主机地址和端口号
    WiFiMouseServer(const std::string& host = "0.0.0.0", int port = 1978)
        : host(host), port(port), running(false), frame_count(0) {
        // 初始化Winsock库
        WSADATA wsaData;
        if (WSAStartup(MAKEWORD(2, 2), &wsaData) != 0) {
            LOG_ERROR("WSAStartup failed");
            return;
        }

        // 创建服务器套接字
        server_socket = socket(AF_INET, SOCK_STREAM, 0);
        if (server_socket == INVALID_SOCKET) {
            LOG_ERROR("Failed to create socket");
            WSACleanup();
            return;
        }

        // 配置服务器地址信息
        sockaddr_in server_addr;
        server_addr.sin_family = AF_INET;
        server_addr.sin_addr.s_addr = inet_addr(host.c_str());
        server_addr.sin_port = htons(port);

        // 将套接字绑定到指定的地址和端口
        if (bind(server_socket, (sockaddr*)&server_addr, sizeof(server_addr)) == SOCKET_ERROR) {
            LOG_ERROR("Failed to bind socket");
            closesocket(server_socket);
            WSACleanup();
            return;
        }

        // 开始监听客户端连接
        if (listen(server_socket, 5) == SOCKET_ERROR) {
            LOG_ERROR("Failed to listen on socket");
            closesocket(server_socket);
            WSACleanup();
            return;
        }
    }

    // 析构函数,停止服务器并清理Winsock库
    ~WiFiMouseServer() {
        stop();
        WSACleanup();
    }

    // 启动服务器,开启一个新线程来接受客户端连接
    void start() {
        running = true;
        LOG_INFO("Server started, listening on " + host + ":" + std::to_string(port) + " | Waiting for client connections...");
        std::thread(&WiFiMouseServer::_accept_connections, this).detach();
    }

    // 停止服务器,关闭套接字并输出处理的总帧数
    void stop() {
        running = false;
        if (server_socket != INVALID_SOCKET) {
            closesocket(server_socket);
            server_socket = INVALID_SOCKET;
        }
        LOG_INFO("Server stopped | Total frames processed: " + std::to_string(frame_count));
    }

    // 从列表中获取指定索引的元素,如果索引越界则抛出异常
    static std::string getElement(const std::list<std::string>& myList, int index)
    {
        if (index < 0 || index >= myList.size()) {
            throw std::out_of_range("Index out of range");
        }
        auto it = myList.begin();
        std::advance(it, index); // 移动迭代器到目标位置
        return *it; // 解引用获取元素
    }

    // 将字符串按指定分隔符分割成多个子字符串,并存储在列表中返回
    static std::list<std::string> split(const std::string& _buffer, const std::string& _split )
    {
        int pos = 0;
        int len;
        std::list<std::string> temp;
        for (size_t i = 0; i < _buffer.length(); )
        {
            pos = _buffer.find( _split, i );
            if( pos < 0 )
            {
                temp.push_back( _buffer.substr( i ) );
                break;
            }
            len = pos - i;
            temp.push_back( _buffer.substr( i, len ) );
            i += len+1;
        }
        return temp;
    }

private:
    std::string host;  // 服务器主机地址
    int port;  // 服务器端口号
    SOCKET server_socket;  // 服务器套接字
    bool running;  // 服务器运行状态
    std::unordered_map<SOCKET, std::string> client_buffers;  // 客户端缓冲区,存储每个客户端接收到的数据
    int frame_count;  // 处理的总帧数

    // 接受客户端连接的线程函数,不断循环接受新的客户端连接
    void _accept_connections() {
        while (running) {
            sockaddr_in client_addr;
            int client_addr_len = sizeof(client_addr);
            SOCKET client_socket = accept(server_socket, (sockaddr*)&client_addr, &client_addr_len);
            if (client_socket == INVALID_SOCKET) {
                if (running) {
                    LOG_ERROR("Failed to accept connection");
                }
                continue;
            }

            client_buffers[client_socket] = "";
            LOG_INFO("New client connected: " + std::string(inet_ntoa(client_addr.sin_addr)) + ":" + std::to_string(ntohs(client_addr.sin_port)) + " | Current connections: " + std::to_string(client_buffers.size()));
            std::thread(&WiFiMouseServer::_handle_client, this, client_socket).detach();
        }
    }

    // 处理客户端连接的线程函数,不断接收客户端发送的数据并处理
    void _handle_client(SOCKET client_socket) {
        // try {
        while (true) {
            char buffer[1024];
            int bytes_received = recv(client_socket, buffer, sizeof(buffer), 0);
            if (bytes_received <= 0) {
                LOG_INFO("Client disconnected | Total frames processed: " + std::to_string(frame_count));
                break;
            }

            client_buffers[client_socket] += std::string(buffer, bytes_received);
            LOG_DEBUG("Received data, current buffer length: " + std::to_string(client_buffers[client_socket].length()) + " characters");

            _split_and_process_frames(client_socket);
        }
        // } catch (const std::exception& e) {
        //     LOG_ERROR("Error handling client: " + std::string(e.what()));
        // }

        if (client_buffers.find(client_socket) != client_buffers.end()) {
            client_buffers.erase(client_socket);
        }
        closesocket(client_socket);
    }

    // 解析帧头信息,返回一个包含长度、功能和帧头长度的元组指针
    std::unique_ptr<std::tuple<std::string, std::string, int>> _parse_frame_header(const std::string& buffer)
    {
        std::list<std::string> ds = split( buffer, " " );

        if ( ds.size() < 2 )
        {
            return nullptr;
        }

        std::string mark;
        std::string len_func_part ;
        std::string func;
        std::string len_str;

        int i=0;
        if ( ds.size()>i ) mark = getElement(ds,i);
        i++;
        if ( ds.size()>i ) ;//rev = getElement(ds,i);
        i++;
        if ( ds.size()>i ) len_func_part = getElement(ds,i);
        i++;

        if (len_func_part.find("1c") != std::string::npos) {
            func = "c";
            len_str = "1";
        } else {
            func = len_func_part.substr(len_func_part.length() - 1);
            len_str = len_func_part.substr(0, len_func_part.length() - 1);
        }

        if (func != "R" && func != "m" && func != "w" && func != "c") {
            LOG_WARNING("Invalid func field: " + func);
            return nullptr;
        }

        int frame_header_len = mark.size() + len_str.size() + 2;
        return std::make_unique<std::tuple<std::string, std::string, int>>(len_str, func, frame_header_len);
    }

    // 处理鼠标帧数据,解析并处理鼠标相关的操作
    void _process_mouse_frame(SOCKET client_socket, std::string& buffer)
    {
        size_t mos_pos = buffer.find("mos  ");
        if (mos_pos == std::string::npos) {
            return;
        }

        size_t _pos = mos_pos;
        buffer = buffer.substr(_pos);

        auto frame_parts = _parse_frame_header(buffer);
        if (!frame_parts) {
            return;
        }

        std::string len_str = std::get<0>(*frame_parts);
        std::string func = std::get<1>(*frame_parts);
        int frame_header_len = std::get<2>(*frame_parts);

        int expected_func_data_len;
        try {
            expected_func_data_len = std::stoi(len_str);
        } catch (const std::invalid_argument& e) {
            LOG_WARNING("Invalid len field: " + len_str + " | Discarding current incomplete frame");
            buffer = buffer.substr(1);
            return;
        }

        int min_frame_len = frame_header_len + expected_func_data_len ;
        if (buffer.length() < min_frame_len) {
            buffer = buffer.substr(1);
            return;
        }

        std::string func_data_str = buffer.substr(frame_header_len);
        int actual_func_data_len = func_data_str.length();

        if (actual_func_data_len < expected_func_data_len) {
            return;
        }

        func_data_str = func_data_str.substr(0, expected_func_data_len);
        int full_frame_len = frame_header_len + func_data_str.length();
        if (full_frame_len > buffer.length()) {
            return;
        }

        std::string full_frame = buffer.substr(0, full_frame_len);
        _process_single_frame(full_frame);

        buffer = buffer.substr(full_frame_len);
        frame_count++;
        LOG_DEBUG("Successfully processed 1 frame | Total frames: " + std::to_string(frame_count) + " | Remaining buffer length: " + std::to_string(buffer.length()));

    }

    // 处理键盘帧数据,解析并处理键盘相关的操作
    void _process_keyboard_frame(SOCKET client_socket, std::string& buffer)
    {
        size_t key_pos = buffer.find("key  ");
        if (key_pos == std::string::npos) {
            return;
        }
        buffer = buffer.substr(key_pos);
        size_t space_pos = buffer.find("  ");
        if (space_pos == std::string::npos) {
            return;
        }

        std::string len_str = buffer.substr(space_pos + 2);
        size_t data_start = len_str.find_first_not_of("0123456789");
        if (data_start == std::string::npos) {
            return;
        }

        std::string len_part = len_str.substr(0, data_start);
        std::string data = len_str.substr(data_start);

        int expected_len = std::stoi(len_part);
        int actual_len = data.length();
        if (actual_len < expected_len) {
            LOG_WARNING("Length verification failed for key frame: expected " + std::to_string(expected_len) + " bytes, actual " + std::to_string(actual_len) + " bytes");
            buffer = buffer.substr(1);
            return;
        }

        std::string full_frame = buffer.substr(0, space_pos + 2 + len_part.length() + expected_len );
        _process_single_frame(full_frame);

        buffer = buffer.substr(full_frame.length());
        frame_count++;
        LOG_DEBUG("Successfully processed 1 key frame | Total frames: " + std::to_string(frame_count) + " | Remaining buffer length: " + std::to_string(buffer.length()));

    }

    // 处理输入法帧数据,解析并处理输入法相关的操作
    void _process_input_method_frame(SOCKET client_socket, std::string& buffer) {
        size_t utf8_pos = buffer.find("utf8 ");
        if (utf8_pos == std::string::npos) {
            return;
        }

        buffer = buffer.substr(utf8_pos);
        size_t space_pos = buffer.find(' ');
        if (space_pos == std::string::npos) {
            return;
        }

        std::string func = "utf8";
        std::string data = buffer.substr(space_pos + 1);
        std::string full_frame = buffer.substr(0, space_pos + 0 + data.length());
        _process_single_frame(full_frame);

        buffer = buffer.substr(full_frame.length());
        frame_count++;
        LOG_DEBUG("Successfully processed 1 frame | Total frames: " + std::to_string(frame_count) + " | Remaining buffer length: " + std::to_string(buffer.length()));

    }

    // 分割并处理接收到的数据帧,根据帧的类型调用相应的处理函数
    void _split_and_process_frames(SOCKET client_socket) {
        std::string& buffer = client_buffers[client_socket];

        while (true)
        {
            size_t mos_pos = buffer.find("mos  ");
            size_t utf8_pos = buffer.find("utf8 ");
            size_t key_pos = buffer.find("key  ");

            // LOG_DEBUG("---> buffer: " + (buffer) );

            if (mos_pos == std::string::npos && utf8_pos == std::string::npos && key_pos == std::string::npos) {
                return;
            }

            if (mos_pos != std::string::npos && (utf8_pos == std::string::npos || mos_pos < utf8_pos) && (key_pos == std::string::npos || mos_pos < key_pos))
            {
                _process_mouse_frame( client_socket, buffer) ;
            }
            else if (utf8_pos != std::string::npos && (key_pos == std::string::npos || utf8_pos < key_pos))
            {
                _process_input_method_frame( client_socket, buffer) ;
            }
            else
            {
                _process_keyboard_frame( client_socket, buffer);
            }
        }
    }

    // 处理单个数据帧,根据帧的功能调用相应的处理函数
    void _process_single_frame(const std::string& frame) {
        try {
            // std::string func;
            std::string data;

            std::string mark;
            std::string len_func_part ;
            std::string func;
            std::string len_str;

            std::list<std::string> ds = split( frame, " ");

            if ( ds.size() < 2 )
            {
                return  ;
            }

            int i=0;
            if ( ds.size()>i ) mark = getElement(ds,i);
            i++;
            if ( ds.size()>i ) ;//rev = getElement(ds,i);
            i++;
            if ( ds.size()>i ) len_func_part = getElement(ds,i);
            i++;

            if ( mark == "utf8") {
                func = mark;
                data = frame.substr(5);
            }
            else if ( mark == "key")
            {
                func = mark;
                size_t space_pos = frame.find(' ');
                std::string len_str = frame.substr(space_pos + 2);
                size_t data_start = len_str.find_first_not_of("0123456789");
                data = len_str.substr(data_start);
            }
            else
            {

                if (len_func_part.find("1c") != std::string::npos) {
                    func = "c";
                    len_str = "1";
                } else {
                    func = len_func_part.substr(len_func_part.length() - 1);
                    len_str = len_func_part.substr(0, len_func_part.length() - 1);
                }

                int _d_pos = frame.find( len_func_part );
                if( _d_pos + len_func_part.size() + 1 < frame.size() )
                    data = frame.substr( _d_pos + len_func_part.size() + 1 );

                int expected_len = std::stoi(len_str);
                int actual_len = (func + " " + data).length();
                if ( !data.empty() && actual_len != expected_len)
                {
                    return ;//throw std::invalid_argument("Length verification failed: expected " + std::to_string(expected_len) + " bytes, actual " + std::to_string(actual_len) + " bytes");
                }
            }

            if (func == "R") {
                handle_mouse_key(data);
            } else if (func == "m") {
                handle_mouse_move(data);
            } else if (func == "w") {
                handle_mouse_scroll(data);
            } else if (func == "c") {
                handle_mouse_click(data);
            } else if (func == "utf8") {
                handle_keyboard(data);
            } else if (func == "key") {
                handle_keyboard_key(data);
            } else {
                return ;//throw std::invalid_argument("Unsupported func: " + func);
            }
        } catch (const std::exception& e) {
            LOG_WARNING("Failed to process frame: " + std::string(e.what()) + " | Frame content: " + frame);
        }
    }
#if 1
    // 处理鼠标按键事件,模拟鼠标按键的按下和释放操作
    void handle_mouse_key(const std::string& data) {
        size_t pos = data.find(' ');
        if (pos == std::string::npos) {
            throw std::invalid_argument("Invalid key data format: " + data);
        }

        std::string key_type = data.substr(0, pos);
        std::string action = data.substr(pos + 1);

        if ((key_type != "l" && key_type != "r" && key_type != "m") || (action != "d" && action != "u")) {
            throw std::invalid_argument("Invalid key parameters: " + data);
        }

        INPUT input = {0};
        input.type = INPUT_MOUSE;

        // 设置按键类型
        if (key_type == "l") {
            input.mi.dwFlags = (action == "d") ? MOUSEEVENTF_LEFTDOWN : MOUSEEVENTF_LEFTUP;
        } else if (key_type == "r") {
            input.mi.dwFlags = (action == "d") ? MOUSEEVENTF_RIGHTDOWN : MOUSEEVENTF_RIGHTUP;
        } else { // m
            input.mi.dwFlags = (action == "d") ? MOUSEEVENTF_MIDDLEDOWN : MOUSEEVENTF_MIDDLEUP;
        }

        // 发送输入事件
        SendInput(1, &input, sizeof(INPUT));
    }

    // 处理鼠标移动事件,模拟鼠标的移动操作
    void handle_mouse_move(const std::string& data) {
        size_t pos = data.find(' ');
        if (pos == std::string::npos) {
            throw std::invalid_argument("Invalid move data format: " + data);
        }

        int x = std::stoi(data.substr(0, pos));
        int y = std::stoi(data.substr(pos + 1));

        INPUT input = {0};
        input.type = INPUT_MOUSE;
        input.mi.dwFlags = MOUSEEVENTF_MOVE;
        input.mi.dx = x;
        input.mi.dy = y;

        SendInput(1, &input, sizeof(INPUT));
    }

    // 处理鼠标滚动事件,模拟鼠标的滚动操作
    void handle_mouse_scroll(const std::string& data) {
        try {
            int value = std::stoi(data);
            if (value == 0) return; // 无滚动,直接返回

            INPUT input = {0};
            input.type = INPUT_MOUSE;
            input.mi.dwFlags = MOUSEEVENTF_WHEEL;
            input.mi.mouseData = (value > 0) ? WHEEL_DELTA : -WHEEL_DELTA;

            SendInput(1, &input, sizeof(INPUT));
        } catch (const std::invalid_argument& e) {
            throw std::invalid_argument("Invalid scroll value: " + data);
        }
    }

    // 处理鼠标点击事件,模拟鼠标左键的点击操作
    void handle_mouse_click(const std::string& data) {
        INPUT inputs[2] = {0};

        // 左键按下
        inputs[0].type = INPUT_MOUSE;
        inputs[0].mi.dwFlags = MOUSEEVENTF_LEFTDOWN;

        // 左键释放
        inputs[1].type = INPUT_MOUSE;
        inputs[1].mi.dwFlags = MOUSEEVENTF_LEFTUP;

        // 发送两个输入事件
        SendInput(2, inputs, sizeof(INPUT));
    }
#else
    // 另一种处理鼠标按键事件的实现,使用mouse_event函数
    void handle_mouse_key(const std::string& data) {
        size_t pos = data.find(' ');
        if (pos == std::string::npos) {
            throw std::invalid_argument("Invalid key data format: " + data);
        }

        std::string key_type = data.substr(0, pos);
        std::string action = data.substr(pos + 1);

        if ((key_type != "l" && key_type != "r" && key_type != "m") || (action != "d" && action != "u")) {
            throw std::invalid_argument("Invalid key parameters: " + data);
        }

        DWORD button;



        if (action == "d") {
            if (key_type == "l") {
                button = MOUSEEVENTF_LEFTDOWN;
            } else if (key_type == "r") {
                button = MOUSEEVENTF_RIGHTDOWN;
            } else {
                button = MOUSEEVENTF_MIDDLEDOWN;
            }
            mouse_event( button, 0, 0, 0, 0);
        }
        else
        {
            if (key_type == "l") {
                button = MOUSEEVENTF_LEFTUP;
            } else if (key_type == "r") {
                button = MOUSEEVENTF_RIGHTUP;
            } else {
                button = MOUSEEVENTF_MIDDLEUP;
            }
            mouse_event( button, 0, 0, 0, 0);
        }
    }

    // 另一种处理鼠标移动事件的实现,使用mouse_event函数
    void handle_mouse_move(const std::string& data) {
        size_t pos = data.find(' ');
        if (pos == std::string::npos) {
            throw std::invalid_argument("Invalid move data format: " + data);
        }

        int x = std::stoi(data.substr(0, pos));
        int y = std::stoi(data.substr(pos + 1));

        mouse_event(MOUSEEVENTF_MOVE, x, y, 0, 0);
    }

    // 另一种处理鼠标滚动事件的实现,使用mouse_event函数
    void handle_mouse_scroll(const std::string& data) {
        try {
            int value = std::stoi(data);
            if (value > 0) {
                mouse_event(MOUSEEVENTF_WHEEL, 0, 0, WHEEL_DELTA, 0);
            } else if (value < 0) {
                mouse_event(MOUSEEVENTF_WHEEL, 0, 0, -WHEEL_DELTA, 0);
            }

        } catch (const std::invalid_argument& e) {
            throw std::invalid_argument("Invalid scroll value: " + data);
        }
    }

    // 另一种处理鼠标点击事件的实现,使用mouse_event函数
    void handle_mouse_click(const std::string& data) {
        mouse_event(MOUSEEVENTF_LEFTDOWN, 0, 0, 0, 0);
        mouse_event(MOUSEEVENTF_LEFTUP, 0, 0, 0, 0);
    }
#endif
    // 辅助函数:将UTF-8字符串转换为宽字符字符串
    wchar_t* utf8_to_wchar(const char* utf8_str) {
        if (!utf8_str) return nullptr;
        // 计算宽字符所需长度
        int wlen = MultiByteToWideChar(CP_UTF8, 0, utf8_str, -1, nullptr, 0);
        if (wlen == 0) {
            LOG_WARNING("UTF-8 to wide char conversion failed (length 0)");
            return nullptr;
        }
        // 分配内存并转换
        wchar_t* wstr = new wchar_t[wlen];
        if (!wstr) {
            LOG_ERROR("Memory allocation failed for wide char");
            return nullptr;
        }
        if (MultiByteToWideChar(CP_UTF8, 0, utf8_str, -1, wstr, wlen) == 0) {
            LOG_WARNING("UTF-8 to wide char conversion failed (MultiByteToWideChar)");
            delete[] wstr;
            return nullptr;
        }
        return wstr;
    }

    // 辅助函数:模拟单个宽字符的输入
    void simulate_unicode_input(wchar_t c) {
        INPUT input[2] = {0}; // 存储按键按下和释放两个事件

        // 按键按下事件
        input[0].type = INPUT_KEYBOARD;
        input[0].ki.wVk = 0; // 不使用虚拟键码(通过Unicode扫描码输入)
        input[0].ki.wScan = c; // 宽字符扫描码(直接对应Unicode字符)
        input[0].ki.dwFlags = KEYEVENTF_UNICODE; // 标记为Unicode输入

        // 按键释放事件
        input[1].type = INPUT_KEYBOARD;
        input[1].ki.wVk = 0;
        input[1].ki.wScan = c;
        input[1].ki.dwFlags = KEYEVENTF_UNICODE | KEYEVENTF_KEYUP; // 释放标记

        // 发送输入事件(返回值为成功发送的事件数,此处简化处理)
        SendInput(2, input, sizeof(INPUT));
    }

    // 处理键盘输入,将UTF-8字符串转换为宽字符并逐个字符模拟输入
    void handle_keyboard(const std::string& data) {
        if (data.empty()) {
            LOG_DEBUG("No keyboard data to input");
            return;
        }

        // 1. 将UTF-8字符串转换为宽字符(支持中文等)
        wchar_t* wstr = utf8_to_wchar(data.c_str());
        if (!wstr) {
            LOG_WARNING("Failed to process keyboard data (invalid UTF-8)");
            return;
        }

        // 2. 逐个字符模拟输入(间隔短时间避免输入混乱)
        for (int i = 0; wstr[i] != L'\0'; ++i) {
            simulate_unicode_input(wstr[i]);
            Sleep(10); // 轻微延迟,确保系统能正确接收
        }

        // 释放内存
        delete[] wstr;
        LOG_DEBUG("Keyboard input completed: " + data);
    }

    // 处理键盘按键事件,模拟回车键和退格键的按下和释放操作
    void handle_keyboard_key(const std::string& data) {
        if (data == "RTN") {
            // 处理回车键
            keybd_event(VK_RETURN, 0, 0, 0);
            keybd_event(VK_RETURN, 0, KEYEVENTF_KEYUP, 0);
        } else if (data == "BAS") {
            // 处理退格键
            keybd_event(VK_BACK, 0, 0, 0);
            keybd_event(VK_BACK, 0, KEYEVENTF_KEYUP, 0);
        } else {
            LOG_WARNING("Unsupported keyboard key: " + data);
        }
    }

};

int main() {

    WiFiMouseServer server;

    server.start();

    try {
        std::cout << "Server is running, press Ctrl+C to stop..." << std::endl;
        while (true) {
            std::this_thread::sleep_for(std::chrono::seconds(1));
        }
    } catch (const std::exception& e) {
        server.stop();
    }

    return 0;
}


网站公告

今日签到

点亮在社区的每一天
去签到