diff --git a/QtScrcpy/device/controller/inputconvert/inputconvertgame.cpp b/QtScrcpy/device/controller/inputconvert/inputconvertgame.cpp index 4fd252c..78a59bc 100644 --- a/QtScrcpy/device/controller/inputconvert/inputconvertgame.cpp +++ b/QtScrcpy/device/controller/inputconvert/inputconvertgame.cpp @@ -8,8 +8,8 @@ InputConvertGame::InputConvertGame(Controller* controller) : InputConvertNormal(controller) -{ - m_keyMap.loadKeyMapNode(); +{ + m_keyMap.loadKeyMap(""); if (m_keyMap.enableMouseMoveMap()) { m_mouseMoveLastConverPos = m_keyMap.getMouseMoveMap().startPos; } diff --git a/QtScrcpy/device/controller/inputconvert/keymap/keymap.cpp b/QtScrcpy/device/controller/inputconvert/keymap/keymap.cpp index b69a549..678cb96 100644 --- a/QtScrcpy/device/controller/inputconvert/keymap/keymap.cpp +++ b/QtScrcpy/device/controller/inputconvert/keymap/keymap.cpp @@ -1,170 +1,269 @@ +#include +#include +#include +#include +#include +#include +#include +#include + #include "keymap.h" -KeyMap::KeyMap() +QString KeyMap::s_keyMapPath = ""; + +KeyMap::KeyMap(QObject *parent) + : QObject(parent) +{ + loadKeyMap(""); +} + +KeyMap::~KeyMap() { } -void KeyMap::loadKeyMapNode() +const QString& KeyMap::getKeyMapPath() { - KeyMapNode node; - node.type = KMT_CLICK; - node.click.keyNode.key = Qt::Key_Space; // 跳 - node.click.keyNode.pos = QPointF(0.96f, 0.7f); - node.click.switchMap = false; - m_keyMapNodes.push_back(node); + if (s_keyMapPath.isEmpty()) { + s_keyMapPath = QString::fromLocal8Bit(qgetenv("QTSCRCPY_KEYMAP_PATH")); + QFileInfo fileInfo(s_keyMapPath); + if (s_keyMapPath.isEmpty() || !fileInfo.isDir()) { + s_keyMapPath = QCoreApplication::applicationDirPath() + "/keymap"; + } + } + return s_keyMapPath; +} - node.type = KMT_CLICK; - node.click.keyNode.key = Qt::Key_M; // 地图 - node.click.keyNode.pos = QPointF(0.98f, 0.03f); - node.click.switchMap = true; - m_keyMapNodes.push_back(node); +void KeyMap::loadKeyMap(const QString &json) +{ + QString errorString; + QByteArray allData; + QJsonParseError jsonError; + QJsonDocument jsonDoc; + QJsonObject rootObj; - node.type = KMT_CLICK; - node.click.keyNode.key = Qt::Key_Tab; // 背包 - node.click.keyNode.pos = QPointF(0.06f, 0.9f); - node.click.switchMap = true; - m_keyMapNodes.push_back(node); + QMetaEnum metaEnumKey = QMetaEnum::fromType(); + QMetaEnum metaEnumMouseButtons = QMetaEnum::fromType(); + QMetaEnum metaEnumKeyMapType = QMetaEnum::fromType(); - node.type = KMT_CLICK; - node.click.keyNode.key = Qt::Key_Z; // 趴 - node.click.keyNode.pos = QPointF(0.95f, 0.9f); - node.click.switchMap = false; - m_keyMapNodes.push_back(node); + QFile loadFile(getKeyMapPath() + "/gameforpeace.json"); + if(!loadFile.open(QIODevice::ReadOnly)) + { + errorString = "json error: open file failed"; + goto parseError; + } - node.type = KMT_CLICK; - node.click.keyNode.key = Qt::Key_C; // 蹲 - node.click.keyNode.pos = QPointF(0.86f, 0.92f); - node.click.switchMap = false; - m_keyMapNodes.push_back(node); + allData = loadFile.readAll(); + loadFile.close(); - node.type = KMT_CLICK; - node.click.keyNode.key = Qt::Key_R; // 换弹 - node.click.keyNode.pos = QPointF(0.795f, 0.93f); - node.click.switchMap = false; - m_keyMapNodes.push_back(node); - node.type = KMT_CLICK; - node.click.keyNode.key = Qt::Key_Alt; // 小眼睛 - node.click.keyNode.pos = QPointF(0.8f, 0.31f); - node.click.switchMap = false; - m_keyMapNodes.push_back(node); + jsonDoc = QJsonDocument::fromJson(allData, &jsonError); - node.type = KMT_CLICK; - node.click.keyNode.key = Qt::Key_F; // 捡东西1 - node.click.keyNode.pos = QPointF(0.7f, 0.34f); - node.click.switchMap = false; - m_keyMapNodes.push_back(node); + if(jsonError.error != QJsonParseError::NoError) + { + errorString = QString("json error: %1").arg(jsonError.errorString()); + goto parseError; + } - node.type = KMT_CLICK; - node.click.keyNode.key = Qt::Key_G; // 捡东西2 - node.click.keyNode.pos = QPointF(0.7f, 0.44f); - node.click.switchMap = false; - m_keyMapNodes.push_back(node); + // switchKey + rootObj = jsonDoc.object(); + if (rootObj.contains("switchKey") && rootObj.value("switchKey").isString()) { + Qt::Key key = (Qt::Key)metaEnumKey.keyToValue(rootObj.value("switchKey").toString().toStdString().c_str()); + if (-1 == key) { + errorString = QString("json error: switchKey invalid"); + goto parseError; + } + m_switchKey = key; + } else { + errorString = QString("json error: no find switchKey"); + goto parseError; + } - node.type = KMT_CLICK; - node.click.keyNode.key = Qt::Key_H; // 捡东西3 - node.click.keyNode.pos = QPointF(0.7f, 0.54f); - node.click.switchMap = false; - m_keyMapNodes.push_back(node); + // mouseMoveMap + if (rootObj.contains("mouseMoveMap") && rootObj.value("mouseMoveMap").isObject()) { + QJsonObject mouseMoveMap = rootObj.value("mouseMoveMap").toObject(); + if (mouseMoveMap.contains("speedRatio") && mouseMoveMap.value("speedRatio").isDouble()) { + m_mouseMoveMap.speedRatio = mouseMoveMap.value("speedRatio").toInt(); + } else { + errorString = QString("json error: mouseMoveMap on find speedRatio"); + goto parseError; + } + if (mouseMoveMap.contains("startPos") && mouseMoveMap.value("startPos").isObject()) { + QJsonObject startPos = mouseMoveMap.value("startPos").toObject(); + if (startPos.contains("x") && startPos.value("x").isDouble()) { + m_mouseMoveMap.startPos.setX(startPos.value("x").toDouble()); + } + if (startPos.contains("y") && startPos.value("y").isDouble()) { + m_mouseMoveMap.startPos.setY(startPos.value("y").toDouble()); + } + } else { + errorString = QString("json error: mouseMoveMap on find startPos"); + goto parseError; + } + } - node.type = KMT_CLICK; - node.click.keyNode.key = Qt::Key_1; // 换枪1 - node.click.keyNode.pos = QPointF(0.45f, 0.9f); - node.click.switchMap = false; - m_keyMapNodes.push_back(node); + // keyMapNodes + if (rootObj.contains("keyMapNodes") && rootObj.value("keyMapNodes").isArray()) { + QJsonArray keyMapNodes = rootObj.value("keyMapNodes").toArray(); + QJsonObject node; + int size = keyMapNodes.size(); + for (int i = 0; i < size; i++) { + if (!keyMapNodes.at(i).isObject()) { + errorString = QString("json error: keyMapNodes node must be json object"); + goto parseError; + } + node = keyMapNodes.at(i).toObject(); + if (!node.contains("type") || !node.value("type").isString()) { + errorString = QString("json error: keyMapNodes no find node type"); + goto parseError; + } - node.type = KMT_CLICK; - node.click.keyNode.key = Qt::Key_2; // 换枪2 - node.click.keyNode.pos = QPointF(0.55f, 0.9f); - node.click.switchMap = false; - m_keyMapNodes.push_back(node); + KeyMap::KeyMapType type = (KeyMap::KeyMapType)metaEnumKeyMapType.keyToValue(node.value("type").toString().toStdString().c_str()); + switch (type) { + case KeyMap::KMT_CLICK: + { + // safe check + if (!node.contains("key") || !node.value("key").isString() + || !node.contains("pos") || !node.value("pos").isObject() + || !node.value("pos").toObject().contains("x") || !node.value("pos").toObject().value("x").isDouble() + || !node.value("pos").toObject().contains("y") || !node.value("pos").toObject().value("y").isDouble() + || !node.contains("switchMap") || !node.value("switchMap").isBool() + ) { + qWarning() << "json error: keyMapNodes node format error"; + break; + } - node.type = KMT_CLICK; - node.click.keyNode.key = Qt::Key_3; // 手雷 - node.click.keyNode.pos = QPointF(0.67f, 0.92f); - node.click.switchMap = false; - m_keyMapNodes.push_back(node); + Qt::Key key = (Qt::Key)metaEnumKey.keyToValue(node.value("key").toString().toStdString().c_str()); + Qt::MouseButtons btn = (Qt::MouseButtons)metaEnumMouseButtons.keyToValue(node.value("key").toString().toStdString().c_str()); + if (-1 == key && -1 == btn) { + qWarning() << "json error: keyMapNodes node invalid key: " << node.value("key").toString(); + break; + } - node.type = KMT_CLICK; - node.click.keyNode.key = Qt::Key_4; // 快速打药 - node.click.keyNode.pos = QPointF(0.33f, 0.95f); - node.click.switchMap = false; - m_keyMapNodes.push_back(node); + KeyMapNode keyMapNode; + keyMapNode.type = type; + if (key != -1) { + keyMapNode.click.keyNode.key = key; + } else { + keyMapNode.click.keyNode.key = btn; + } + keyMapNode.click.keyNode.pos = QPointF(node.value("pos").toObject().value("x").toDouble(), + node.value("pos").toObject().value("y").toDouble()); + keyMapNode.click.switchMap = node.value("switchMap").toBool(); + m_keyMapNodes.push_back(keyMapNode); + } + break; + case KeyMap::KMT_CLICK_TWICE: + { + // safe check + if (!node.contains("key") || !node.value("key").isString() + || !node.contains("pos") || !node.value("pos").isObject() + || !node.value("pos").toObject().contains("x") || !node.value("pos").toObject().value("x").isDouble() + || !node.value("pos").toObject().contains("y") || !node.value("pos").toObject().value("y").isDouble() + ) { + qWarning() << "json error: keyMapNodes node format error"; + break; + } - node.type = KMT_CLICK; - node.click.keyNode.key = Qt::Key_5; // 下车 - node.click.keyNode.pos = QPointF(0.92f, 0.4f); - node.click.switchMap = false; - m_keyMapNodes.push_back(node); + Qt::Key key = (Qt::Key)metaEnumKey.keyToValue(node.value("key").toString().toStdString().c_str()); + Qt::MouseButtons btn = (Qt::MouseButtons)metaEnumMouseButtons.keyToValue(node.value("key").toString().toStdString().c_str()); + if (-1 == key && -1 == btn) { + qWarning() << "json error: keyMapNodes node invalid key: " << node.value("key").toString(); + break; + } - node.type = KMT_CLICK; - node.click.keyNode.key = Qt::Key_6; // 救人 - node.click.keyNode.pos = QPointF(0.49f, 0.63f); - node.click.switchMap = false; - m_keyMapNodes.push_back(node); + KeyMapNode keyMapNode; + keyMapNode.type = type; + if (key != -1) { + keyMapNode.clickTwice.keyNode.key = key; + } else { + keyMapNode.clickTwice.keyNode.key = btn; + } + keyMapNode.clickTwice.keyNode.pos = QPointF(node.value("pos").toObject().value("x").toDouble(), + node.value("pos").toObject().value("y").toDouble()); + m_keyMapNodes.push_back(keyMapNode); + } + break; + case KeyMap::KMT_STEER_WHEEL: + { + // safe check + if (!node.contains("leftKey") || !node.value("leftKey").isString() + || !node.contains("rightKey") || !node.value("rightKey").isString() + || !node.contains("upKey") || !node.value("upKey").isString() + || !node.contains("downKey") || !node.value("downKey").isString() + || !node.contains("leftOffset") || !node.value("leftOffset").isDouble() + || !node.contains("rightOffset") || !node.value("rightOffset").isDouble() + || !node.contains("upOffset") || !node.value("upOffset").isDouble() + || !node.contains("downOffset") || !node.value("downOffset").isDouble() + || !node.contains("centerPos") || !node.value("centerPos").isObject() + || !node.value("centerPos").toObject().contains("x") || !node.value("centerPos").toObject().value("x").isDouble() + || !node.value("centerPos").toObject().contains("y") || !node.value("centerPos").toObject().value("y").isDouble() + ) { + qWarning() << "json error: keyMapNodes node format error"; + break; + } - node.type = KMT_CLICK; - node.click.keyNode.key = Qt::Key_Shift; // 车加速 - node.click.keyNode.pos = QPointF(0.82f, 0.8f); - node.click.switchMap = false; - m_keyMapNodes.push_back(node); + Qt::Key leftKey = (Qt::Key)metaEnumKey.keyToValue(node.value("leftKey").toString().toStdString().c_str()); + Qt::MouseButtons leftBtn = (Qt::MouseButtons)metaEnumMouseButtons.keyToValue(node.value("leftKey").toString().toStdString().c_str()); + Qt::Key rightKey = (Qt::Key)metaEnumKey.keyToValue(node.value("rightKey").toString().toStdString().c_str()); + Qt::MouseButtons rightBtn = (Qt::MouseButtons)metaEnumMouseButtons.keyToValue(node.value("rightKey").toString().toStdString().c_str()); + Qt::Key upKey = (Qt::Key)metaEnumKey.keyToValue(node.value("upKey").toString().toStdString().c_str()); + Qt::MouseButtons upBtn = (Qt::MouseButtons)metaEnumMouseButtons.keyToValue(node.value("upKey").toString().toStdString().c_str()); + Qt::Key downKey = (Qt::Key)metaEnumKey.keyToValue(node.value("downKey").toString().toStdString().c_str()); + Qt::MouseButtons downBtn = (Qt::MouseButtons)metaEnumMouseButtons.keyToValue(node.value("downKey").toString().toStdString().c_str()); - node.type = KMT_CLICK; - node.click.keyNode.key = Qt::Key_X; // 开关门 - node.click.keyNode.pos = QPointF(0.7f, 0.7f); - node.click.switchMap = false; - m_keyMapNodes.push_back(node); + if ((-1 == leftKey && -1 == leftBtn) + || (-1 == rightKey && -1 == rightBtn) + || (-1 == upKey && -1 == upBtn) + || (-1 == downKey && -1 == downBtn) + ) { + qWarning() << "json error: keyMapNodes node invalid key: " << node.value("key").toString(); + break; + } - node.type = KMT_CLICK; - node.click.keyNode.key = Qt::Key_T; // 舔包 - node.click.keyNode.pos = QPointF(0.72f, 0.26f); - node.click.switchMap = false; - m_keyMapNodes.push_back(node); + KeyMapNode keyMapNode; + keyMapNode.type = type; + if (leftKey != -1) { + keyMapNode.steerWheel.leftKey = leftKey; + } else { + keyMapNode.steerWheel.leftKey = leftBtn; + } + if (rightKey != -1) { + keyMapNode.steerWheel.rightKey = rightKey; + } else { + keyMapNode.steerWheel.rightKey = rightBtn; + } + if (upKey != -1) { + keyMapNode.steerWheel.upKey = upKey; + } else { + keyMapNode.steerWheel.upKey = upBtn; + } + if (downKey != -1) { + keyMapNode.steerWheel.downKey = downKey; + } else { + keyMapNode.steerWheel.downKey = downBtn; + } + keyMapNode.steerWheel.leftOffset = node.value("leftOffset").toDouble(); + keyMapNode.steerWheel.rightOffset = node.value("rightOffset").toDouble(); + keyMapNode.steerWheel.upOffset = node.value("upOffset").toDouble(); + keyMapNode.steerWheel.downOffset = node.value("downOffset").toDouble(); + keyMapNode.steerWheel.centerPos = QPointF(node.value("centerPos").toObject().value("x").toDouble(), + node.value("centerPos").toObject().value("y").toDouble()); + m_keyMapNodes.push_back(keyMapNode); + } + break; + default: + qWarning() << "json error: keyMapNodes invalid node type:" << node.value("type").toString(); + break; + } + } + } - node.type = KMT_CLICK; - node.click.keyNode.key = Qt::LeftButton; // 开枪 - node.click.keyNode.pos = QPointF(0.86f, 0.72f); - node.click.switchMap = false; - m_keyMapNodes.push_back(node); - - node.type = KMT_CLICK; - node.click.keyNode.key = Qt::RightButton; // 开镜 - node.click.keyNode.pos = QPointF(0.96f, 0.52f); - node.click.switchMap = false; - m_keyMapNodes.push_back(node); - - KeyMapNode node2; - node2.type = KMT_CLICK_TWICE; - node2.clickTwice.keyNode.key = Qt::Key_Q; // 左探头 - node2.clickTwice.keyNode.pos = QPointF(0.12f, 0.35f); - m_keyMapNodes.push_back(node2); - - node2.type = KMT_CLICK_TWICE; - node2.clickTwice.keyNode.key = Qt::Key_E; // 右探头 - node2.clickTwice.keyNode.pos = QPointF(0.2, 0.35f); - m_keyMapNodes.push_back(node2); - - // 方向盘 - KeyMapNode node3; - node3.type = KMT_STEER_WHEEL; - node3.steerWheel.centerPos = {0.16f, 0.75f}; - node3.steerWheel.leftOffset = 0.1f; - node3.steerWheel.rightOffset = 0.1f; - node3.steerWheel.upOffset = 0.27f; - node3.steerWheel.downOffset = 0.2f; - - node3.steerWheel.leftKey = Qt::Key_A; - node3.steerWheel.rightKey = Qt::Key_D; - node3.steerWheel.upKey = Qt::Key_W; - node3.steerWheel.downKey = Qt::Key_S; - - m_keyMapNodes.push_back(node3); - - m_mouseMoveMap.startPos = QPointF(0.57f, 0.26f); - m_mouseMoveMap.speedRatio = 10; - - m_switchKey = Qt::Key_QuoteLeft; +parseError: + if (!errorString.isEmpty()) { + qWarning() << errorString; + } + return; } KeyMap::KeyMapNode KeyMap::getKeyMapNode(int key) diff --git a/QtScrcpy/device/controller/inputconvert/keymap/keymap.h b/QtScrcpy/device/controller/inputconvert/keymap/keymap.h index dcb403d..fdc7181 100644 --- a/QtScrcpy/device/controller/inputconvert/keymap/keymap.h +++ b/QtScrcpy/device/controller/inputconvert/keymap/keymap.h @@ -1,19 +1,22 @@ #ifndef KEYMAP_H #define KEYMAP_H +#include #include #include #include -class KeyMap -{ +class KeyMap : public QObject +{ + Q_OBJECT public: enum KeyMapType { KMT_INVALID = -1, KMT_CLICK = 0, KMT_CLICK_TWICE, KMT_STEER_WHEEL, - }; + }; + Q_ENUM(KeyMapType) struct KeyNode { int key = Qt::Key_unknown; @@ -67,19 +70,23 @@ public: int speedRatio = 1; }; - KeyMap(); + KeyMap(QObject *parent = Q_NULLPTR); + virtual ~KeyMap(); - void loadKeyMapNode(); + void loadKeyMap(const QString &json); KeyMap::KeyMapNode getKeyMapNode(int key); int getSwitchKey(); MouseMoveMap getMouseMoveMap(); bool enableMouseMoveMap(); +protected: + const QString& getKeyMapPath(); + private: QVector m_keyMapNodes; int m_switchKey = Qt::Key_QuoteLeft; MouseMoveMap m_mouseMoveMap; - + static QString s_keyMapPath; }; #endif // KEYMAP_H diff --git a/QtScrcpy/main.cpp b/QtScrcpy/main.cpp index f040278..2642721 100644 --- a/QtScrcpy/main.cpp +++ b/QtScrcpy/main.cpp @@ -33,6 +33,7 @@ int main(int argc, char *argv[]) #ifdef Q_OS_WIN32 qputenv("QTSCRCPY_ADB_PATH", "../../../third_party/adb/win/adb.exe"); qputenv("QTSCRCPY_SERVER_PATH", "../../../third_party/scrcpy-server.jar"); + qputenv("QTSCRCPY_KEYMAP_PATH", "../../../keymap"); #endif #ifdef Q_OS_LINUX diff --git a/keymap/gameforpeace.json b/keymap/gameforpeace.json new file mode 100644 index 0000000..63de51b --- /dev/null +++ b/keymap/gameforpeace.json @@ -0,0 +1,255 @@ +{ + "switchKey": "Key_QuoteLeft", + "mouseMoveMap": { + "startPos": { + "x": 0.57, + "y": 0.26 + }, + "speedRatio": 10 + }, + "keyMapNodes": [{ + "comment": "方向盘", + "type": "KMT_STEER_WHEEL", + "centerPos": { + "x": 0.16, + "y": 0.75 + }, + "leftOffset": 0.1, + "rightOffset": 0.1, + "upOffset": 0.27, + "downOffset": 0.2, + "leftKey": "Key_A", + "rightKey": "Key_D", + "upKey": "Key_W", + "downKey": "Key_S" + }, + { + "comment": "左探头", + "type": "KMT_CLICK_TWICE", + "key": "Key_Q", + "pos": { + "x": 0.12, + "y": 0.35 + } + }, + { + "comment": "右探头", + "type": "KMT_CLICK_TWICE", + "key": "Key_E", + "pos": { + "x": 0.2, + "y": 0.35 + } + }, + { + "comment": "跳", + "type": "KMT_CLICK", + "key": "Key_Space", + "pos": { + "x": 0.96, + "y": 0.7 + }, + "switchMap": false + }, + { + "comment": "地图", + "type": "KMT_CLICK", + "key": "Key_M", + "pos": { + "x": 0.98, + "y": 0.03 + }, + "switchMap": true + }, + { + "comment": "背包", + "type": "KMT_CLICK", + "key": "Key_Tab", + "pos": { + "x": 0.06, + "y": 0.9 + }, + "switchMap": true + }, + { + "comment": "趴", + "type": "KMT_CLICK", + "key": "Key_Z", + "pos": { + "x": 0.95, + "y": 0.9 + }, + "switchMap": false + }, + { + "comment": "蹲", + "type": "KMT_CLICK", + "key": "Key_C", + "pos": { + "x": 0.86, + "y": 0.92 + }, + "switchMap": false + }, + { + "comment": "换弹", + "type": "KMT_CLICK", + "key": "Key_R", + "pos": { + "x": 0.795, + "y": 0.93 + }, + "switchMap": false + }, + { + "comment": "小眼睛", + "type": "KMT_CLICK", + "key": "Key_Alt", + "pos": { + "x": 0.8, + "y": 0.31 + }, + "switchMap": false + }, + { + "comment": "捡东西1", + "type": "KMT_CLICK", + "key": "Key_F", + "pos": { + "x": 0.7, + "y": 0.34 + }, + "switchMap": false + }, + { + "comment": "捡东西2", + "type": "KMT_CLICK", + "key": "Key_G", + "pos": { + "x": 0.7, + "y": 0.44 + }, + "switchMap": false + }, + { + "comment": "捡东西3", + "type": "KMT_CLICK", + "key": "Key_H", + "pos": { + "x": 0.7, + "y": 0.54 + }, + "switchMap": false + }, + { + "comment": "换枪1", + "type": "KMT_CLICK", + "key": "Key_1", + "pos": { + "x": 0.45, + "y": 0.9 + }, + "switchMap": false + }, + { + "comment": "换枪2", + "type": "KMT_CLICK", + "key": "Key_2", + "pos": { + "x": 0.55, + "y": 0.9 + }, + "switchMap": false + }, + { + "comment": "手雷", + "type": "KMT_CLICK", + "key": "Key_3", + "pos": { + "x": 0.67, + "y": 0.92 + }, + "switchMap": false + }, + { + "comment": "快速打药", + "type": "KMT_CLICK", + "key": "Key_4", + "pos": { + "x": 0.33, + "y": 0.95 + }, + "switchMap": false + }, + { + "comment": "下车", + "type": "KMT_CLICK", + "key": "Key_S", + "pos": { + "x": 0.92, + "y": 0.4 + }, + "switchMap": false + }, + { + "comment": "救人", + "type": "KMT_CLICK", + "key": "Key_6", + "pos": { + "x": 0.49, + "y": 0.63 + }, + "switchMap": false + }, + { + "comment": "车加速", + "type": "KMT_CLICK", + "key": "Key_Shift", + "pos": { + "x": 0.82, + "y": 0.8 + }, + "switchMap": false + }, + { + "comment": "开关门", + "type": "KMT_CLICK", + "key": "Key_X", + "pos": { + "x": 0.7, + "y": 0.7 + }, + "switchMap": false + }, + { + "comment": "舔包", + "type": "KMT_CLICK", + "key": "Key_T", + "pos": { + "x": 0.72, + "y": 0.26 + }, + "switchMap": false + }, + { + "comment": "开枪", + "type": "KMT_CLICK", + "key": "LeftButton", + "pos": { + "x": 0.86, + "y": 0.72 + }, + "switchMap": false + }, + { + "comment": "开镜", + "type": "KMT_CLICK", + "key": "RightButton", + "pos": { + "x": 0.96, + "y": 0.52 + }, + "switchMap": false + } + ] +} \ No newline at end of file