2024-04-13 09:53:41 +08:00
|
|
|
|
// https://github.com/jamiebuilds/tinykeys/pull/193/commits/2598ecb3db6b3948c7acbf0e7bd8b0674961ad61
|
|
|
|
|
import {
|
|
|
|
|
SwipeAction,
|
|
|
|
|
TouchAction,
|
|
|
|
|
swipe,
|
|
|
|
|
touch,
|
|
|
|
|
} from "./frontcommand/scrcpyMaskCmd";
|
|
|
|
|
|
2024-04-16 17:07:25 +08:00
|
|
|
|
|
|
|
|
|
// TODO 根据当前蒙版的尺寸换算屏幕尺寸
|
2024-04-13 09:53:41 +08:00
|
|
|
|
function clientxToPosx(clientx: number) {
|
2024-04-14 17:19:45 +08:00
|
|
|
|
return clientx < 70 ? 0 : Math.floor(clientx - 70);
|
2024-04-13 09:53:41 +08:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
function clientyToPosy(clienty: number) {
|
2024-04-14 17:19:45 +08:00
|
|
|
|
return clienty < 30 ? 0 : Math.floor(clienty - 30);
|
2024-04-13 09:53:41 +08:00
|
|
|
|
}
|
|
|
|
|
|
2024-04-14 17:19:45 +08:00
|
|
|
|
function clientxToPosOffsetx(clientx: number, posx: number, scale: number) {
|
|
|
|
|
let offsetX = clientxToPosx(clientx) - posx;
|
|
|
|
|
return Math.round(offsetX * scale);
|
2024-04-13 09:53:41 +08:00
|
|
|
|
}
|
|
|
|
|
|
2024-04-14 17:19:45 +08:00
|
|
|
|
function clientyToPosOffsety(clienty: number, posy: number, scale: number) {
|
|
|
|
|
let offsetY = clientyToPosy(clienty) - posy;
|
|
|
|
|
return Math.round(offsetY * scale);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
function clientxToCenterOffsetx(clientx: number, range: number, scale = 0.5) {
|
|
|
|
|
return Math.max(
|
|
|
|
|
-range,
|
|
|
|
|
Math.min(range, clientxToPosOffsetx(clientx, screenSizeW / 2, scale))
|
|
|
|
|
);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
function clientyToCenterOffsety(clienty: number, range: number, scale = 0.5) {
|
|
|
|
|
return Math.max(
|
|
|
|
|
-range,
|
2024-04-14 21:29:28 +08:00
|
|
|
|
Math.min(range, clientyToPosOffsety(clienty, screenSizeH * 0.55, scale))
|
2024-04-14 17:19:45 +08:00
|
|
|
|
);
|
2024-04-13 09:53:41 +08:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
async function sleep(ms: number) {
|
|
|
|
|
return new Promise((resolve) => setTimeout(resolve, ms));
|
|
|
|
|
}
|
|
|
|
|
|
2024-04-14 17:19:45 +08:00
|
|
|
|
function calculateMacroPosX(pos: [string, number] | number): number {
|
|
|
|
|
if (typeof pos === "number") {
|
|
|
|
|
return pos;
|
|
|
|
|
}
|
|
|
|
|
if (typeof pos === "string") {
|
|
|
|
|
return clientxToPosx(mouseX);
|
|
|
|
|
} else {
|
|
|
|
|
if (pos[0] === "mouse") {
|
|
|
|
|
return clientxToPosx(mouseX) + pos[1];
|
|
|
|
|
} else {
|
|
|
|
|
throw new Error("Invalid pos");
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
function calculateMacroPosY(pos: [string, number] | number): number {
|
|
|
|
|
if (typeof pos === "number") {
|
|
|
|
|
return pos;
|
|
|
|
|
}
|
|
|
|
|
if (typeof pos === "string") {
|
|
|
|
|
return clientyToPosy(mouseY);
|
|
|
|
|
} else {
|
|
|
|
|
if (pos[0] === "mouse") {
|
|
|
|
|
return clientyToPosy(mouseY) + pos[1];
|
|
|
|
|
} else {
|
|
|
|
|
throw new Error("Invalid pos");
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
function calculateMacroPosList(
|
|
|
|
|
posList: [[string, number] | number, [string, number] | number][]
|
|
|
|
|
): { x: number; y: number }[] {
|
|
|
|
|
return posList.map((posPair) => {
|
|
|
|
|
return {
|
|
|
|
|
x: calculateMacroPosX(posPair[0]),
|
|
|
|
|
y: calculateMacroPosY(posPair[1]),
|
|
|
|
|
};
|
|
|
|
|
});
|
|
|
|
|
}
|
|
|
|
|
|
2024-04-14 21:29:28 +08:00
|
|
|
|
// TODO 技能界面实际上是有投影变换的,需要一定的算法,不能仅仅相对坐标 (640,400)
|
2024-04-14 17:19:45 +08:00
|
|
|
|
|
|
|
|
|
// add shortcuts for observation
|
|
|
|
|
function addObservationShortcuts(
|
|
|
|
|
key: string,
|
|
|
|
|
posX: number,
|
|
|
|
|
posY: number,
|
|
|
|
|
scale: number,
|
|
|
|
|
pointerId: number
|
|
|
|
|
) {
|
|
|
|
|
let observationMouseX = 0;
|
|
|
|
|
let observationMouseY = 0;
|
|
|
|
|
addShortcut(
|
|
|
|
|
key,
|
|
|
|
|
async () => {
|
|
|
|
|
observationMouseX = clientxToPosx(mouseX);
|
|
|
|
|
observationMouseY = clientyToPosy(mouseY);
|
|
|
|
|
await touch({
|
|
|
|
|
action: TouchAction.Down,
|
|
|
|
|
pointerId,
|
|
|
|
|
screen: {
|
|
|
|
|
w: screenSizeW,
|
|
|
|
|
h: screenSizeH,
|
|
|
|
|
},
|
|
|
|
|
pos: {
|
|
|
|
|
x: posX,
|
|
|
|
|
y: posY,
|
|
|
|
|
},
|
|
|
|
|
});
|
|
|
|
|
},
|
|
|
|
|
async () => {
|
|
|
|
|
await touch({
|
|
|
|
|
action: TouchAction.Move,
|
|
|
|
|
pointerId,
|
|
|
|
|
screen: {
|
|
|
|
|
w: screenSizeW,
|
|
|
|
|
h: screenSizeH,
|
|
|
|
|
},
|
|
|
|
|
pos: {
|
|
|
|
|
x: posX + clientxToPosOffsetx(mouseX, observationMouseX, scale),
|
|
|
|
|
y: posY + clientyToPosOffsety(mouseY, observationMouseY, scale),
|
|
|
|
|
},
|
|
|
|
|
});
|
|
|
|
|
},
|
|
|
|
|
async () => {
|
|
|
|
|
await touch({
|
|
|
|
|
action: TouchAction.Up,
|
|
|
|
|
pointerId,
|
|
|
|
|
screen: {
|
|
|
|
|
w: screenSizeW,
|
|
|
|
|
h: screenSizeH,
|
|
|
|
|
},
|
|
|
|
|
pos: {
|
|
|
|
|
x: posX + clientxToPosOffsetx(mouseX, observationMouseY, scale),
|
|
|
|
|
y: posY + clientyToPosOffsety(mouseY, observationMouseY, scale),
|
|
|
|
|
},
|
|
|
|
|
});
|
|
|
|
|
}
|
|
|
|
|
);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// add shortcuts for simple tap (touch for 100 ms when pressed)
|
|
|
|
|
function addTapShortcuts(
|
|
|
|
|
key: string,
|
|
|
|
|
posX: number,
|
|
|
|
|
posY: number,
|
|
|
|
|
pointerId: number
|
|
|
|
|
) {
|
|
|
|
|
addShortcut(
|
|
|
|
|
key,
|
|
|
|
|
async () => {
|
|
|
|
|
await touch({
|
|
|
|
|
action: TouchAction.Default,
|
|
|
|
|
pointerId,
|
|
|
|
|
screen: {
|
|
|
|
|
w: screenSizeW,
|
|
|
|
|
h: screenSizeH,
|
|
|
|
|
},
|
|
|
|
|
pos: {
|
|
|
|
|
x: posX,
|
|
|
|
|
y: posY,
|
|
|
|
|
},
|
|
|
|
|
});
|
|
|
|
|
},
|
|
|
|
|
undefined,
|
|
|
|
|
undefined
|
|
|
|
|
);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// add shortcuts for cancel skill
|
|
|
|
|
function addCancelSkillShortcuts(
|
|
|
|
|
key: string,
|
|
|
|
|
posX: number,
|
|
|
|
|
posY: number,
|
|
|
|
|
pointerId: number
|
|
|
|
|
) {
|
|
|
|
|
addShortcut(
|
|
|
|
|
key,
|
|
|
|
|
async () => {
|
|
|
|
|
// delete the callback
|
|
|
|
|
for (const cancelAbleKey of cancelAbleKeyList) {
|
|
|
|
|
loopDownKeyCBMap.delete(cancelAbleKey);
|
|
|
|
|
upKeyCBMap.delete(cancelAbleKey);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
let distance = 0;
|
|
|
|
|
while (distance <= 20) {
|
|
|
|
|
await touch({
|
|
|
|
|
action: TouchAction.Move,
|
|
|
|
|
pointerId,
|
|
|
|
|
screen: {
|
|
|
|
|
w: screenSizeW,
|
|
|
|
|
h: screenSizeH,
|
|
|
|
|
},
|
|
|
|
|
pos: {
|
|
|
|
|
x: posX + distance,
|
|
|
|
|
y: posY,
|
|
|
|
|
},
|
|
|
|
|
});
|
|
|
|
|
await sleep(5);
|
|
|
|
|
distance += 1;
|
|
|
|
|
}
|
|
|
|
|
await touch({
|
|
|
|
|
action: TouchAction.Up,
|
|
|
|
|
pointerId,
|
|
|
|
|
screen: {
|
|
|
|
|
w: screenSizeW,
|
|
|
|
|
h: screenSizeH,
|
|
|
|
|
},
|
|
|
|
|
pos: {
|
|
|
|
|
x: posX,
|
|
|
|
|
y: posY,
|
|
|
|
|
},
|
|
|
|
|
});
|
|
|
|
|
},
|
|
|
|
|
undefined,
|
|
|
|
|
undefined
|
|
|
|
|
);
|
|
|
|
|
}
|
2024-04-13 09:53:41 +08:00
|
|
|
|
|
|
|
|
|
// add shortcuts for trigger when pressed skill
|
|
|
|
|
function addTriggerWhenPressedSkillShortcuts(
|
|
|
|
|
key: string,
|
|
|
|
|
// pos relative to the device
|
|
|
|
|
posX: number,
|
|
|
|
|
posY: number,
|
|
|
|
|
directional: boolean,
|
|
|
|
|
// range is needed when directional is true
|
|
|
|
|
range: number,
|
|
|
|
|
pointerId: number
|
|
|
|
|
) {
|
|
|
|
|
if (directional) {
|
|
|
|
|
addShortcut(
|
|
|
|
|
key,
|
|
|
|
|
// down
|
|
|
|
|
async () => {
|
|
|
|
|
await swipe({
|
|
|
|
|
action: SwipeAction.Default,
|
|
|
|
|
pointerId,
|
|
|
|
|
screen: {
|
|
|
|
|
w: screenSizeW,
|
|
|
|
|
h: screenSizeH,
|
|
|
|
|
},
|
|
|
|
|
pos: [
|
|
|
|
|
{ x: posX, y: posY },
|
|
|
|
|
{
|
2024-04-14 17:19:45 +08:00
|
|
|
|
x: posX + clientxToCenterOffsetx(mouseX, range),
|
|
|
|
|
y: posY + clientyToCenterOffsety(mouseY, range),
|
2024-04-13 09:53:41 +08:00
|
|
|
|
},
|
|
|
|
|
],
|
|
|
|
|
intervalBetweenPos: 0,
|
|
|
|
|
});
|
|
|
|
|
},
|
|
|
|
|
undefined,
|
|
|
|
|
undefined
|
|
|
|
|
);
|
|
|
|
|
} else {
|
2024-04-14 17:19:45 +08:00
|
|
|
|
addTapShortcuts(key, posX, posY, pointerId);
|
2024-04-13 09:53:41 +08:00
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2024-04-14 17:19:45 +08:00
|
|
|
|
// add shortcuts for directionless skill (cancelable)
|
2024-04-13 09:53:41 +08:00
|
|
|
|
function addDirectionlessSkillShortcuts(
|
|
|
|
|
key: string,
|
|
|
|
|
// pos relative to the device
|
|
|
|
|
posX: number,
|
|
|
|
|
posY: number,
|
|
|
|
|
pointerId: number
|
|
|
|
|
) {
|
|
|
|
|
addShortcut(
|
|
|
|
|
key,
|
|
|
|
|
// down
|
|
|
|
|
async () => {
|
|
|
|
|
await touch({
|
|
|
|
|
action: TouchAction.Down,
|
|
|
|
|
pointerId,
|
|
|
|
|
screen: {
|
|
|
|
|
w: screenSizeW,
|
|
|
|
|
h: screenSizeH,
|
|
|
|
|
},
|
|
|
|
|
pos: {
|
|
|
|
|
x: posX,
|
|
|
|
|
y: posY,
|
|
|
|
|
},
|
|
|
|
|
});
|
|
|
|
|
},
|
|
|
|
|
// loop
|
|
|
|
|
undefined,
|
|
|
|
|
// up
|
|
|
|
|
async () => {
|
|
|
|
|
await touch({
|
|
|
|
|
action: TouchAction.Up,
|
|
|
|
|
pointerId,
|
|
|
|
|
screen: {
|
|
|
|
|
w: screenSizeW,
|
|
|
|
|
h: screenSizeH,
|
|
|
|
|
},
|
|
|
|
|
pos: {
|
|
|
|
|
x: posX,
|
|
|
|
|
y: posY,
|
|
|
|
|
},
|
|
|
|
|
});
|
2024-04-14 17:19:45 +08:00
|
|
|
|
},
|
|
|
|
|
true
|
2024-04-13 09:53:41 +08:00
|
|
|
|
);
|
|
|
|
|
}
|
|
|
|
|
|
2024-04-14 17:19:45 +08:00
|
|
|
|
// add shortcuts for directional skill (cancelable)
|
2024-04-13 09:53:41 +08:00
|
|
|
|
function addDirectionalSkillShortcuts(
|
|
|
|
|
key: string,
|
|
|
|
|
// pos relative to the device
|
|
|
|
|
posX: number,
|
|
|
|
|
posY: number,
|
|
|
|
|
range: number,
|
|
|
|
|
pointerId: number
|
|
|
|
|
) {
|
|
|
|
|
addShortcut(
|
|
|
|
|
key,
|
|
|
|
|
// down
|
|
|
|
|
async () => {
|
|
|
|
|
await swipe({
|
|
|
|
|
action: SwipeAction.NoUp,
|
|
|
|
|
pointerId,
|
|
|
|
|
screen: {
|
|
|
|
|
w: screenSizeW,
|
|
|
|
|
h: screenSizeH,
|
|
|
|
|
},
|
|
|
|
|
pos: [
|
|
|
|
|
{ x: posX, y: posY },
|
|
|
|
|
{
|
2024-04-14 17:19:45 +08:00
|
|
|
|
x: posX + clientxToCenterOffsetx(mouseX, range),
|
|
|
|
|
y: posY + clientyToCenterOffsety(mouseY, range),
|
2024-04-13 09:53:41 +08:00
|
|
|
|
},
|
|
|
|
|
],
|
|
|
|
|
intervalBetweenPos: 0,
|
|
|
|
|
});
|
|
|
|
|
},
|
|
|
|
|
// loop
|
|
|
|
|
async () => {
|
|
|
|
|
await touch({
|
|
|
|
|
action: TouchAction.Move,
|
|
|
|
|
pointerId,
|
|
|
|
|
screen: {
|
|
|
|
|
w: screenSizeW,
|
|
|
|
|
h: screenSizeH,
|
|
|
|
|
},
|
|
|
|
|
pos: {
|
2024-04-14 17:19:45 +08:00
|
|
|
|
x: posX + clientxToCenterOffsetx(mouseX, range),
|
|
|
|
|
y: posY + clientyToCenterOffsety(mouseY, range),
|
2024-04-13 09:53:41 +08:00
|
|
|
|
},
|
|
|
|
|
});
|
|
|
|
|
},
|
|
|
|
|
// up
|
|
|
|
|
async () => {
|
|
|
|
|
await touch({
|
|
|
|
|
action: TouchAction.Up,
|
|
|
|
|
pointerId,
|
|
|
|
|
screen: {
|
|
|
|
|
w: screenSizeW,
|
|
|
|
|
h: screenSizeH,
|
|
|
|
|
},
|
|
|
|
|
pos: {
|
2024-04-14 17:19:45 +08:00
|
|
|
|
x: posX + clientxToCenterOffsetx(mouseX, range),
|
|
|
|
|
y: posY + clientyToCenterOffsety(mouseY, range),
|
2024-04-13 09:53:41 +08:00
|
|
|
|
},
|
|
|
|
|
});
|
2024-04-14 17:19:45 +08:00
|
|
|
|
},
|
|
|
|
|
true
|
2024-04-13 09:53:41 +08:00
|
|
|
|
);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// add shortcuts for steering wheel
|
|
|
|
|
function addSteeringWheelKeyboardShortcuts(
|
|
|
|
|
key: wheelKey,
|
|
|
|
|
// pos relative to the device
|
|
|
|
|
posX: number,
|
|
|
|
|
posY: number,
|
|
|
|
|
offset: number,
|
|
|
|
|
pointerId: number
|
|
|
|
|
) {
|
2024-04-14 21:29:28 +08:00
|
|
|
|
let loopFlag = false;
|
|
|
|
|
let curPosX = 0;
|
|
|
|
|
let curPosY = 0;
|
2024-04-13 09:53:41 +08:00
|
|
|
|
|
|
|
|
|
// calculate the end coordinates of the eight directions of the direction wheel
|
|
|
|
|
let offsetHalf = Math.round(offset / 1.414);
|
2024-04-14 21:29:28 +08:00
|
|
|
|
const calculatedPosList = [
|
2024-04-13 09:53:41 +08:00
|
|
|
|
{ x: posX - offset, y: posY }, // left
|
|
|
|
|
{ x: posX + offset, y: posY }, // right
|
|
|
|
|
{ x: posX, y: posY - offset }, // up
|
|
|
|
|
{ x: posX, y: posY + offset }, // down
|
|
|
|
|
{ x: posX - offsetHalf, y: posY - offsetHalf }, // left up
|
|
|
|
|
{ x: posX + offsetHalf, y: posY - offsetHalf }, // right up
|
|
|
|
|
{ x: posX - offsetHalf, y: posY + offsetHalf }, // left down
|
|
|
|
|
{ x: posX + offsetHalf, y: posY + offsetHalf }, // right down
|
|
|
|
|
];
|
|
|
|
|
|
2024-04-14 21:29:28 +08:00
|
|
|
|
// united loop callback for all directions
|
|
|
|
|
const unitedloopCB = async () => {
|
|
|
|
|
let newPosIndex;
|
|
|
|
|
if (downKeyMap.get(key.left)) {
|
|
|
|
|
newPosIndex = downKeyMap.get(key.up)
|
|
|
|
|
? 4
|
|
|
|
|
: downKeyMap.get(key.down)
|
|
|
|
|
? 6
|
|
|
|
|
: 0;
|
|
|
|
|
} else if (downKeyMap.get(key.right)) {
|
|
|
|
|
newPosIndex = downKeyMap.get(key.up)
|
|
|
|
|
? 5
|
|
|
|
|
: downKeyMap.get(key.down)
|
|
|
|
|
? 7
|
|
|
|
|
: 1;
|
|
|
|
|
} else if (downKeyMap.get(key.up)) {
|
|
|
|
|
newPosIndex = 2;
|
|
|
|
|
} else if (downKeyMap.get(key.down)) {
|
|
|
|
|
newPosIndex = 3;
|
2024-04-13 09:53:41 +08:00
|
|
|
|
} else {
|
2024-04-14 21:29:28 +08:00
|
|
|
|
// all keys released
|
|
|
|
|
await unitedUpCB();
|
|
|
|
|
return;
|
2024-04-13 09:53:41 +08:00
|
|
|
|
}
|
2024-04-14 21:29:28 +08:00
|
|
|
|
// if newPos is the same as curPos, return
|
|
|
|
|
let newPos = calculatedPosList[newPosIndex];
|
|
|
|
|
if (newPos.x === curPosX && newPos.y === curPosY) return;
|
|
|
|
|
|
|
|
|
|
curPosX = newPos.x;
|
|
|
|
|
curPosY = newPos.y;
|
|
|
|
|
// move to the direction
|
2024-04-13 09:53:41 +08:00
|
|
|
|
await touch({
|
|
|
|
|
action: TouchAction.Move,
|
2024-04-14 21:29:28 +08:00
|
|
|
|
pointerId,
|
2024-04-13 09:53:41 +08:00
|
|
|
|
screen: {
|
|
|
|
|
w: screenSizeW,
|
|
|
|
|
h: screenSizeH,
|
|
|
|
|
},
|
2024-04-14 21:29:28 +08:00
|
|
|
|
pos: newPos,
|
2024-04-13 09:53:41 +08:00
|
|
|
|
});
|
2024-04-14 21:29:28 +08:00
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
const unitedUpCB = async () => {
|
|
|
|
|
if (
|
|
|
|
|
downKeyMap.get(key.left) === false &&
|
|
|
|
|
downKeyMap.get(key.right) === false &&
|
|
|
|
|
downKeyMap.get(key.up) === false &&
|
|
|
|
|
downKeyMap.get(key.down) === false
|
|
|
|
|
) {
|
|
|
|
|
// all wheel keys has been released
|
|
|
|
|
for (const k of ["left", "right", "up", "down"]) {
|
|
|
|
|
// only delete the valid key
|
|
|
|
|
loopDownKeyCBMap.delete(key[k]);
|
|
|
|
|
upKeyCBMap.delete(key[k]);
|
|
|
|
|
}
|
|
|
|
|
// touch up
|
|
|
|
|
await touch({
|
|
|
|
|
action: TouchAction.Up,
|
|
|
|
|
pointerId,
|
|
|
|
|
screen: {
|
|
|
|
|
w: screenSizeW,
|
|
|
|
|
h: screenSizeH,
|
|
|
|
|
},
|
|
|
|
|
pos: {
|
|
|
|
|
x: curPosX,
|
|
|
|
|
y: curPosY,
|
|
|
|
|
},
|
|
|
|
|
});
|
|
|
|
|
// recover the status
|
|
|
|
|
curPosX = 0;
|
|
|
|
|
curPosY = 0;
|
|
|
|
|
loopFlag = false;
|
|
|
|
|
}
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
for (const k of ["left", "right", "up", "down"]) {
|
|
|
|
|
addShortcut(
|
|
|
|
|
key[k],
|
|
|
|
|
async () => {
|
|
|
|
|
if (loopFlag) return;
|
|
|
|
|
loopFlag = true;
|
|
|
|
|
// add upCB
|
|
|
|
|
upKeyCBMap.set(key[k], unitedUpCB);
|
|
|
|
|
|
|
|
|
|
// touch down on the center position
|
|
|
|
|
await touch({
|
|
|
|
|
action: TouchAction.Down,
|
|
|
|
|
pointerId,
|
|
|
|
|
screen: {
|
|
|
|
|
w: screenSizeW,
|
|
|
|
|
h: screenSizeH,
|
|
|
|
|
},
|
|
|
|
|
pos: {
|
|
|
|
|
x: posX,
|
|
|
|
|
y: posY,
|
|
|
|
|
},
|
|
|
|
|
});
|
|
|
|
|
// add loopCB
|
|
|
|
|
loopDownKeyCBMap.set(key[k], unitedloopCB);
|
|
|
|
|
},
|
|
|
|
|
undefined,
|
|
|
|
|
undefined
|
|
|
|
|
);
|
2024-04-13 09:53:41 +08:00
|
|
|
|
}
|
|
|
|
|
}
|
2024-04-14 21:29:28 +08:00
|
|
|
|
|
2024-04-13 09:53:41 +08:00
|
|
|
|
interface wheelKey {
|
|
|
|
|
left: string;
|
|
|
|
|
right: string;
|
|
|
|
|
up: string;
|
|
|
|
|
down: string;
|
|
|
|
|
[key: string]: string;
|
|
|
|
|
}
|
|
|
|
|
|
2024-04-14 17:19:45 +08:00
|
|
|
|
// add baisc click shortcuts
|
|
|
|
|
function addClickShortcuts(key: string, pointerId: number) {
|
2024-04-13 09:53:41 +08:00
|
|
|
|
addShortcut(
|
2024-04-14 17:19:45 +08:00
|
|
|
|
key,
|
2024-04-13 09:53:41 +08:00
|
|
|
|
async () => {
|
|
|
|
|
await touch({
|
|
|
|
|
action: TouchAction.Down,
|
|
|
|
|
pointerId,
|
|
|
|
|
screen: {
|
|
|
|
|
w: screenSizeW,
|
|
|
|
|
h: screenSizeH,
|
|
|
|
|
},
|
|
|
|
|
pos: {
|
|
|
|
|
x: clientxToPosx(mouseX),
|
|
|
|
|
y: clientyToPosy(mouseY),
|
|
|
|
|
},
|
|
|
|
|
});
|
|
|
|
|
},
|
|
|
|
|
async () => {
|
|
|
|
|
await touch({
|
|
|
|
|
action: TouchAction.Move,
|
|
|
|
|
pointerId,
|
|
|
|
|
screen: {
|
|
|
|
|
w: screenSizeW,
|
|
|
|
|
h: screenSizeH,
|
|
|
|
|
},
|
|
|
|
|
pos: {
|
|
|
|
|
x: clientxToPosx(mouseX),
|
|
|
|
|
y: clientyToPosy(mouseY),
|
|
|
|
|
},
|
|
|
|
|
});
|
|
|
|
|
},
|
|
|
|
|
async () => {
|
|
|
|
|
await touch({
|
|
|
|
|
action: TouchAction.Up,
|
|
|
|
|
pointerId,
|
|
|
|
|
screen: {
|
|
|
|
|
w: screenSizeW,
|
|
|
|
|
h: screenSizeH,
|
|
|
|
|
},
|
|
|
|
|
pos: {
|
|
|
|
|
x: clientxToPosx(mouseX),
|
|
|
|
|
y: clientyToPosy(mouseY),
|
|
|
|
|
},
|
|
|
|
|
});
|
|
|
|
|
}
|
|
|
|
|
);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
let screenSizeW: number;
|
|
|
|
|
let screenSizeH: number;
|
|
|
|
|
let mouseX = 0;
|
|
|
|
|
let mouseY = 0;
|
|
|
|
|
|
|
|
|
|
const downKeyMap: Map<string, boolean> = new Map();
|
|
|
|
|
const downKeyCBMap: Map<string, () => Promise<void>> = new Map();
|
|
|
|
|
const loopDownKeyCBMap: Map<string, () => Promise<void>> = new Map();
|
|
|
|
|
const upKeyCBMap: Map<string, () => Promise<void>> = new Map();
|
2024-04-14 17:19:45 +08:00
|
|
|
|
const cancelAbleKeyList: string[] = [];
|
2024-04-13 09:53:41 +08:00
|
|
|
|
|
|
|
|
|
function keydownHandler(event: KeyboardEvent) {
|
|
|
|
|
if (event.repeat) return;
|
2024-04-14 17:19:45 +08:00
|
|
|
|
event.preventDefault();
|
|
|
|
|
if (downKeyMap.has(event.code)) {
|
2024-04-14 21:29:28 +08:00
|
|
|
|
downKeyMap.set(event.code, true);
|
2024-04-13 09:53:41 +08:00
|
|
|
|
// execute the down callback (if there is) asyncily
|
2024-04-14 17:19:45 +08:00
|
|
|
|
let cb = downKeyCBMap.get(event.code);
|
2024-04-13 09:53:41 +08:00
|
|
|
|
if (cb) cb();
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
function keyupHandler(event: KeyboardEvent) {
|
2024-04-14 17:19:45 +08:00
|
|
|
|
event.preventDefault();
|
|
|
|
|
if (downKeyMap.has(event.code)) {
|
2024-04-14 21:29:28 +08:00
|
|
|
|
downKeyMap.set(event.code, false);
|
2024-04-13 09:53:41 +08:00
|
|
|
|
// execute the up callback (if there is) asyncily
|
2024-04-14 17:19:45 +08:00
|
|
|
|
let cb = upKeyCBMap.get(event.code);
|
2024-04-13 09:53:41 +08:00
|
|
|
|
if (cb) cb();
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
function handleMouseDown(event: MouseEvent) {
|
2024-04-14 17:19:45 +08:00
|
|
|
|
mouseX = event.clientX;
|
|
|
|
|
mouseY = event.clientY;
|
|
|
|
|
event.preventDefault();
|
2024-04-13 09:53:41 +08:00
|
|
|
|
let key = "M" + event.button.toString();
|
|
|
|
|
if (downKeyMap.has(key)) {
|
2024-04-14 21:29:28 +08:00
|
|
|
|
downKeyMap.set(key, true);
|
2024-04-13 09:53:41 +08:00
|
|
|
|
// execute the down callback asyncily
|
|
|
|
|
let cb = downKeyCBMap.get(key);
|
|
|
|
|
if (cb) cb();
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
function handleMouseUp(event: MouseEvent) {
|
2024-04-14 17:19:45 +08:00
|
|
|
|
mouseX = event.clientX;
|
|
|
|
|
mouseY = event.clientY;
|
|
|
|
|
event.preventDefault();
|
2024-04-13 09:53:41 +08:00
|
|
|
|
let key = "M" + event.button.toString();
|
|
|
|
|
if (downKeyMap.has(key)) {
|
2024-04-14 21:29:28 +08:00
|
|
|
|
downKeyMap.set(key, false);
|
2024-04-13 09:53:41 +08:00
|
|
|
|
// execute the up callback asyncily
|
|
|
|
|
let cb = upKeyCBMap.get(key);
|
|
|
|
|
if (cb) cb();
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
function handleMouseMove(event: MouseEvent) {
|
|
|
|
|
mouseX = event.clientX;
|
|
|
|
|
mouseY = event.clientY;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
function addShortcut(
|
|
|
|
|
key: string,
|
|
|
|
|
downCB: () => Promise<void>,
|
|
|
|
|
loopCB?: () => Promise<void>,
|
2024-04-14 17:19:45 +08:00
|
|
|
|
upCB?: () => Promise<void>,
|
|
|
|
|
cancelAble = false // only work with downCB && upCB
|
2024-04-13 09:53:41 +08:00
|
|
|
|
) {
|
|
|
|
|
downKeyMap.set(key, false);
|
|
|
|
|
|
2024-04-14 17:19:45 +08:00
|
|
|
|
if (cancelAble && downCB && upCB) {
|
|
|
|
|
cancelAbleKeyList.push(key);
|
|
|
|
|
const cancelAbleUpCB = async () => {
|
|
|
|
|
loopDownKeyCBMap.delete(key);
|
|
|
|
|
upKeyCBMap.delete(key);
|
|
|
|
|
await upCB();
|
|
|
|
|
};
|
2024-04-13 09:53:41 +08:00
|
|
|
|
if (loopCB)
|
2024-04-14 17:19:45 +08:00
|
|
|
|
downKeyCBMap.set(key, async () => {
|
|
|
|
|
loopDownKeyCBMap.set(key, loopCB);
|
|
|
|
|
upKeyCBMap.set(key, cancelAbleUpCB);
|
|
|
|
|
await downCB();
|
|
|
|
|
});
|
|
|
|
|
else {
|
|
|
|
|
// no loopCB
|
|
|
|
|
downKeyCBMap.set(key, async () => {
|
|
|
|
|
upKeyCBMap.set(key, cancelAbleUpCB);
|
|
|
|
|
await downCB();
|
|
|
|
|
});
|
|
|
|
|
}
|
|
|
|
|
} else {
|
|
|
|
|
if (downCB && loopCB)
|
|
|
|
|
downKeyCBMap.set(key, async () => {
|
|
|
|
|
downCB();
|
|
|
|
|
loopDownKeyCBMap.set(key, loopCB);
|
|
|
|
|
});
|
|
|
|
|
else if (downCB) {
|
|
|
|
|
// no loopCB
|
|
|
|
|
downKeyCBMap.set(key, downCB);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (upCB) {
|
2024-04-13 09:53:41 +08:00
|
|
|
|
upKeyCBMap.set(key, async () => {
|
|
|
|
|
loopDownKeyCBMap.delete(key);
|
|
|
|
|
upCB();
|
|
|
|
|
});
|
2024-04-14 17:19:45 +08:00
|
|
|
|
}
|
2024-04-13 09:53:41 +08:00
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2024-04-14 17:19:45 +08:00
|
|
|
|
/**
|
|
|
|
|
* execute the json object macro
|
|
|
|
|
* @param macro
|
|
|
|
|
* @example
|
|
|
|
|
* await execMacro([
|
|
|
|
|
* {
|
|
|
|
|
* type: "touch",
|
|
|
|
|
* // op, pointerId, posX, posY
|
|
|
|
|
* args: ["down", 5, ["mouse", -10], 600],
|
|
|
|
|
* },
|
|
|
|
|
* {
|
|
|
|
|
* type: "sleep",
|
|
|
|
|
* // time(ms)
|
|
|
|
|
* args: [1000],
|
|
|
|
|
* },
|
|
|
|
|
* {
|
|
|
|
|
* type: "touch",
|
|
|
|
|
* args: ["up", 5, ["mouse", 10], 600],
|
|
|
|
|
* },
|
|
|
|
|
* {
|
|
|
|
|
* type: "swipe",
|
|
|
|
|
* // op, pointerId, posList, intervalBetweenPos
|
|
|
|
|
* args: [
|
|
|
|
|
* "default", 5,
|
|
|
|
|
* [
|
|
|
|
|
* [
|
|
|
|
|
* ["mouse", 100],
|
|
|
|
|
* ["mouse", -100],
|
|
|
|
|
* ],
|
|
|
|
|
* ["mouse", "mouse"],
|
|
|
|
|
* ],
|
|
|
|
|
* 1000,
|
|
|
|
|
* ],
|
|
|
|
|
* },
|
|
|
|
|
* ]);
|
|
|
|
|
*/
|
|
|
|
|
async function execMacro(macro: any[]) {
|
|
|
|
|
for (const cmd of macro) {
|
|
|
|
|
if (!cmd.hasOwnProperty("type") || !cmd.hasOwnProperty("args")) {
|
|
|
|
|
console.error("Invalid command: ", cmd);
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
try {
|
|
|
|
|
switch (cmd.type) {
|
|
|
|
|
case "sleep":
|
|
|
|
|
await sleep(cmd.args[0]);
|
|
|
|
|
break;
|
|
|
|
|
case "touch":
|
|
|
|
|
let touchAction;
|
|
|
|
|
switch (cmd.args[0]) {
|
|
|
|
|
case "default":
|
|
|
|
|
touchAction = TouchAction.Default;
|
|
|
|
|
break;
|
|
|
|
|
case "down":
|
|
|
|
|
touchAction = TouchAction.Down;
|
|
|
|
|
break;
|
|
|
|
|
case "up":
|
|
|
|
|
touchAction = TouchAction.Up;
|
|
|
|
|
break;
|
|
|
|
|
case "move":
|
|
|
|
|
touchAction = TouchAction.Move;
|
|
|
|
|
break;
|
|
|
|
|
default:
|
|
|
|
|
console.error("Invalid touch action: ", cmd.args[0]);
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
await touch({
|
|
|
|
|
action: touchAction,
|
|
|
|
|
pointerId: cmd.args[1],
|
|
|
|
|
screen: {
|
|
|
|
|
w: screenSizeW,
|
|
|
|
|
h: screenSizeH,
|
|
|
|
|
},
|
|
|
|
|
pos: {
|
|
|
|
|
x: calculateMacroPosX(cmd.args[2]),
|
|
|
|
|
y: calculateMacroPosY(cmd.args[3]),
|
|
|
|
|
},
|
|
|
|
|
});
|
|
|
|
|
break;
|
|
|
|
|
case "swipe":
|
|
|
|
|
let swipeAction;
|
|
|
|
|
switch (cmd.args[0]) {
|
|
|
|
|
case "default":
|
|
|
|
|
swipeAction = SwipeAction.Default;
|
|
|
|
|
break;
|
|
|
|
|
case "noUp":
|
|
|
|
|
swipeAction = SwipeAction.NoUp;
|
|
|
|
|
break;
|
|
|
|
|
case "noDown":
|
|
|
|
|
swipeAction = SwipeAction.NoDown;
|
|
|
|
|
break;
|
|
|
|
|
default:
|
|
|
|
|
console.error("Invalid swipe action: ", cmd.args[0]);
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
await swipe({
|
|
|
|
|
action: swipeAction,
|
|
|
|
|
pointerId: cmd.args[1],
|
|
|
|
|
screen: {
|
|
|
|
|
w: screenSizeW,
|
|
|
|
|
h: screenSizeH,
|
|
|
|
|
},
|
|
|
|
|
pos: calculateMacroPosList(cmd.args[2]),
|
|
|
|
|
intervalBetweenPos: cmd.args[3],
|
|
|
|
|
});
|
|
|
|
|
break;
|
|
|
|
|
default:
|
|
|
|
|
console.error("Invalid command: ", cmd);
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
} catch (e) {
|
|
|
|
|
console.error("Invalid command: ", cmd, e);
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2024-04-15 11:52:28 +08:00
|
|
|
|
let loopFlag = false;
|
|
|
|
|
function execLoopCB() {
|
|
|
|
|
loopDownKeyCBMap.forEach((cb) => {
|
|
|
|
|
cb();
|
|
|
|
|
});
|
|
|
|
|
if (loopFlag) requestAnimationFrame(execLoopCB);
|
|
|
|
|
}
|
|
|
|
|
|
2024-04-14 17:19:45 +08:00
|
|
|
|
export function listenToKeyEvent() {
|
|
|
|
|
document.addEventListener("keydown", keydownHandler);
|
|
|
|
|
document.addEventListener("keyup", keyupHandler);
|
2024-04-15 11:52:28 +08:00
|
|
|
|
loopFlag = true;
|
|
|
|
|
execLoopCB();
|
2024-04-15 08:27:16 +08:00
|
|
|
|
// setInterval(()=>console.log(loopDownKeyCBMap), 3000);
|
2024-04-14 17:19:45 +08:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
export function unlistenToKeyEvent() {
|
|
|
|
|
document.removeEventListener("keydown", keydownHandler);
|
|
|
|
|
document.removeEventListener("keyup", keyupHandler);
|
2024-04-15 11:52:28 +08:00
|
|
|
|
loopFlag = false;
|
2024-04-14 17:19:45 +08:00
|
|
|
|
}
|
|
|
|
|
|
2024-04-13 09:53:41 +08:00
|
|
|
|
export function initShortcuts(
|
2024-04-14 17:19:45 +08:00
|
|
|
|
screenSize: [number, number],
|
|
|
|
|
element: HTMLElement
|
2024-04-13 09:53:41 +08:00
|
|
|
|
) {
|
|
|
|
|
screenSizeW = screenSize[0];
|
|
|
|
|
screenSizeH = screenSize[1];
|
2024-04-14 17:19:45 +08:00
|
|
|
|
|
2024-04-13 09:53:41 +08:00
|
|
|
|
element.addEventListener("mousedown", handleMouseDown);
|
|
|
|
|
element.addEventListener("mousemove", handleMouseMove);
|
|
|
|
|
element.addEventListener("mouseup", handleMouseUp);
|
2024-04-14 17:19:45 +08:00
|
|
|
|
element.addEventListener("mouseout", handleMouseUp); // mouse out of the element as mouse up
|
2024-04-13 09:53:41 +08:00
|
|
|
|
|
2024-04-14 17:19:45 +08:00
|
|
|
|
addClickShortcuts("M0", 0);
|
2024-04-13 09:53:41 +08:00
|
|
|
|
addSteeringWheelKeyboardShortcuts(
|
|
|
|
|
{
|
2024-04-14 17:19:45 +08:00
|
|
|
|
left: "KeyA",
|
|
|
|
|
right: "KeyD",
|
|
|
|
|
up: "KeyW",
|
|
|
|
|
down: "KeyS",
|
2024-04-13 09:53:41 +08:00
|
|
|
|
},
|
|
|
|
|
180,
|
|
|
|
|
560,
|
|
|
|
|
100,
|
|
|
|
|
1
|
|
|
|
|
);
|
2024-04-15 08:27:16 +08:00
|
|
|
|
addDirectionalSkillShortcuts("KeyQ", 950, 610, 200, 2); // skill 1
|
|
|
|
|
addDirectionalSkillShortcuts("AltLeft", 1025, 500, 200, 2); // skill 2
|
|
|
|
|
addDirectionalSkillShortcuts("KeyE", 1160, 420, 200, 2); // skill 3
|
2024-04-14 17:19:45 +08:00
|
|
|
|
addTriggerWhenPressedSkillShortcuts("M4", 1160, 420, false, 0, 2); // skill 3 (no direction and trigger when pressed)
|
|
|
|
|
addDirectionlessSkillShortcuts("M1", 1150, 280, 2); // equipment skill (middle mouse click)
|
|
|
|
|
addCancelSkillShortcuts("Space", 1160, 140, 2); // cancel skill
|
|
|
|
|
|
|
|
|
|
addTapShortcuts("KeyB", 650, 650, 3); // home
|
|
|
|
|
addTapShortcuts("KeyC", 740, 650, 3); // recover
|
2024-04-15 08:27:16 +08:00
|
|
|
|
addDirectionalSkillShortcuts("KeyF", 840, 650, 200, 2); // summoner skills
|
2024-04-14 17:19:45 +08:00
|
|
|
|
addTriggerWhenPressedSkillShortcuts("ControlLeft", 840, 650, false, 0, 3); // summoner skills (no direction and trigger when pressed)
|
|
|
|
|
addTapShortcuts("M2", 1165, 620, 3); // attack (right click)
|
2024-04-15 08:27:16 +08:00
|
|
|
|
addTapShortcuts("Digit1", 880, 560, 3); // skill 1 upgrade
|
|
|
|
|
addTapShortcuts("Digit2", 960, 430, 3); // skill 2 upgrade
|
|
|
|
|
addTapShortcuts("Digit3", 1090, 350, 3); // skill 3 upgrade
|
2024-04-15 14:22:11 +08:00
|
|
|
|
addTapShortcuts("Digit5", 130, 300, 3); // quick buy 1
|
|
|
|
|
addTapShortcuts("Digit6", 130, 370, 3); // quick buy 2
|
2024-04-14 17:19:45 +08:00
|
|
|
|
|
|
|
|
|
addObservationShortcuts("M3", 1000, 200, 0.5, 4); // observation
|
|
|
|
|
|
|
|
|
|
// panel
|
|
|
|
|
addShortcut(
|
|
|
|
|
"Tab",
|
|
|
|
|
async () => {
|
|
|
|
|
await execMacro([
|
|
|
|
|
{
|
|
|
|
|
type: "touch",
|
|
|
|
|
args: ["default", 5, 1185, 40],
|
|
|
|
|
},
|
|
|
|
|
]);
|
|
|
|
|
},
|
|
|
|
|
undefined,
|
|
|
|
|
async () => {
|
|
|
|
|
await execMacro([
|
|
|
|
|
{
|
|
|
|
|
type: "touch",
|
|
|
|
|
args: ["default", 5, 1220, 100],
|
|
|
|
|
},
|
|
|
|
|
]);
|
|
|
|
|
}
|
|
|
|
|
);
|
|
|
|
|
|
|
|
|
|
// shop
|
|
|
|
|
addShortcut(
|
|
|
|
|
"ShiftLeft",
|
|
|
|
|
async () => {
|
|
|
|
|
await execMacro([
|
|
|
|
|
{
|
|
|
|
|
type: "touch",
|
|
|
|
|
args: ["default", 5, 40, 300],
|
|
|
|
|
},
|
|
|
|
|
]);
|
|
|
|
|
},
|
|
|
|
|
undefined,
|
|
|
|
|
async () => {
|
|
|
|
|
await execMacro([
|
|
|
|
|
{
|
|
|
|
|
type: "touch",
|
|
|
|
|
args: ["default", 5, 1200, 60],
|
|
|
|
|
},
|
|
|
|
|
]);
|
|
|
|
|
}
|
|
|
|
|
);
|
2024-04-15 08:27:16 +08:00
|
|
|
|
|
|
|
|
|
// map
|
|
|
|
|
addShortcut(
|
|
|
|
|
"KeyZ",
|
|
|
|
|
async () => {
|
|
|
|
|
await execMacro([
|
|
|
|
|
{
|
|
|
|
|
type: "touch",
|
|
|
|
|
args: ["default", 5, 250, 230],
|
|
|
|
|
},
|
|
|
|
|
]);
|
|
|
|
|
},
|
|
|
|
|
undefined,
|
|
|
|
|
async () => {
|
|
|
|
|
await execMacro([
|
|
|
|
|
{
|
|
|
|
|
type: "touch",
|
|
|
|
|
args: ["default", 5, 640, 150],
|
|
|
|
|
},
|
|
|
|
|
]);
|
|
|
|
|
}
|
|
|
|
|
);
|
2024-04-13 09:53:41 +08:00
|
|
|
|
}
|