forked from kiccer/logitech-macro-frame
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathlmf.lua
545 lines (439 loc) · 13.1 KB
/
lmf.lua
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
----------------------------------------------------------------------------------------------------
-- 使用者配置设置 --
-- User config settings --
----------------------------------------------------------------------------------------------------
userConfig = {
}
--||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||--
-- --
-- >> Logitech Macro Frame << --
-- --
-- Welcome to this script. If you have any questions, please visit: --
-- https://github.com/kiccer/logitech-macro-frame --
-- Please click [★ Star] to support my project, thank you. --
-- --
--||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||--
----------------------------------------------------------------------------------------------------
-- Framework built-in code --
----------------------------------------------------------------------------------------------------
-- console
console = {
clear = ClearLog
}
function console.log (...)
local arr = {...}
for i = 1, #arr do logMsg(table.print(arr[i]) .. "\n") end
end
lmf = {
debug = true,
monitor = {}, -- 监听器列表
_timers = {}, -- 定时器函数列表
_for_protect_time = 20000, -- lmf.for 方法的循环保护,超过此毫秒数时间将强制结束循环,防止死循环卡死。
}
function lmf.isPressed (n)
if type(n) == "number" then
return IsMouseButtonPressed(n)
elseif type(n) == "string" then
return IsModifierPressed(n)
else
if lmf.debug then error("[lmf.isPressed] Wrong parameter data type: " .. tostring(n) .. " is not a \"number\" or \"string\".") end
end
end
function lmf.setDpi (n, i)
if type(n) == "table" then
SetMouseDPITable(n, i)
elseif type(n) == "number" then
SetMouseDPITableIndex(n)
else
if lmf.debug then error("[lmf.setDpi] Wrong parameter data type: " .. tostring(n) .. " is not a \"table\" or \"number\".") end
end
end
function lmf.addSpeed (n)
if type(n) ~= "number" then
if lmf.debug then error("[lmf.addSpeed] Wrong parameter data type: " .. tostring(n) .. " is not a \"number\".") end
elseif n > 0 then
IncrementMouseSpeed(n)
elseif n < 0 then
DecrementMouseSpeed(-n)
end
end
-- 重命名 API,整合个别 API 功能
getM = GetMKeyState
setM = SetMKeyState
sleep = Sleep
logMsg = OutputLogMessage
lcdMsg = OutputLCDMessage
debugMsg = OutputDebugMessage
getTime = GetRunningTime
getDate = GetDate
keyDown = PressKey
keyUp = ReleaseKey
keyTap = PressAndReleaseKey
mouseDown = PressMouseButton
mouseUp = ReleaseMouseButton
mouseTap = PressAndReleaseMouseButton
move = MoveMouseRelative
moveTo = MoveMouseTo
moveToThis = MoveMouseToVirtual
wheel = MoveMouseWheel
getMouse = GetMousePosition
playMacro = PlayMacro
abortMacro = AbortMacro
setColor = SetBacklightColor
setSpeed = SetMouseSpeed
getSpeed = GetMouseSpeed
addSpeed = lmf.addSpeed
isLock = IsKeyLockOn
isPressed = lmf.isPressed
setDpi = lmf.setDpi
-- 重命名 OnEvent 的 event 参数
lmf.events = {
-- load event
{ "PROFILE_ACTIVATED", "load" },
{ "PROFILE_DEACTIVATED", "unload" },
-- mouse event
{ "MOUSE_BUTTON_PRESSED", "mousedown" },
{ "MOUSE_BUTTON_RELEASED", "mouseup" },
-- G key event
{ "G_PRESSED", "gkeydown" },
{ "G_RELEASED", "gkeyup" },
-- M key event
{ "M_PRESSED", "mkeydown" },
{ "M_RELEASED", "mkeyup" },
}
-- 监听动作
function lmf.on (k, f)
local index = nil
local list = table.map(lmf.events, function (n, i)
return n[2]
end)
if table.some(list, function (n, i)
return n == k
end) then
if lmf.monitor[k] and #lmf.monitor[k] > 0 then
index = #lmf.monitor[k] + 1
lmf.monitor[k][index] = f
else
index = 1
lmf.monitor[k] = { f }
end
end
return index and {
event = k,
id = index
} or nil
end
-- 取消监听
function lmf.off (n)
lmf.monitor[n.event][n.id] = false
end
-- 触发监听事件
function lmf.emit (k, d)
if lmf.monitor[k] and #lmf.monitor[k] then
table.forEach(lmf.monitor[k], function (n, i)
if n then n(d) end
end)
end
end
-- lmf 提供的 loop 循环方法
function lmf.loop (func, timestamp)
local startTime = getTime()
local lastTime = getTime()
repeat
if getTime() - lastTime >= timestamp then
lastTime = lastTime + timestamp
if not func() then break end
end
sleep(1)
until getTime() - startTime >= lmf._for_protect_time
end
--[[ tools ]]
-- split function
function string.split (str, s)
if string.find(str, s) == nil then return { str } end
local res = {}
local reg = "(.-)" .. s .. "()"
local index = 0
local last_i
for n, i in string.gfind(str, reg) do
index = index + 1
res[index] = n
last_i = i
end
res[index + 1] = string.sub(str, last_i)
return res
end
-- table find
function table.find (t, f)
local res = nil
for i = 1, #t do
local n = t[i]
if f(n, i) then
res = n
break
end
end
return res
end
-- table filter
function table.filter (t, f)
local res = {}
table.forEach(t, function (n, i)
if f(n, i) then table.push(res, n) end
end)
return res
end
-- join function
function string.join (t, s)
return table.reduce(t, function(n, m)
return n .. s .. m
end)
end
-- table push
function table.push (t, v)
t[#t + 1] = v
end
-- table indexOf
function table.indexOf (t, v)
local res = -1
for i = 1, #t do
if t[i] == v then
res = i
break
end
end
return res
end
-- table merge
function table.merge (...)
local res = {}
local tabs = {...}
for i = 1, #tabs do
local n = tabs[i]
assert(type(n) == "table", "[table.merge] Wrong parameter data type: " .. tostring(n) .. " is not a \"table\".")
for k, v in pairs(n) do
table._merge(res, k, v)
end
end
return res
end
function table._merge (tab, key, val)
if type(val) == "table" then
tab[key] = tab[key] ~= nil and tab[key] or {}
for k, v in pairs(val) do
table._merge(tab[key], k, v)
end
else
tab[key] = val
end
end
-- table cloneDeep
function table.cloneDeep (t)
return type(t) == "table" and table.merge(t) or t
end
-- Javascript Array.prototype.some
function table.some (t, c)
local res = false
for i = 1, #t do
if c(t[i], i) then
res = true
break
end
end
return res
end
-- Javascript Array.prototype.every
function table.every (t, c)
local res = true
for i = 1, #t do
if not c(t[i], i) then
res = false
break
end
end
return res
end
-- Javascript Array.prototype.reduce
function table.reduce (t, c)
local res = c(t[1], t[2])
for i = 3, #t do res = c(res, t[i]) end
return res
end
-- Javascript Array.prototype.map
function table.map (t, c)
local res = {}
for i = 1, #t do res[i] = c(t[i], i) end
return res
end
-- Javascript Array.prototype.forEach
function table.forEach (t, c)
for i = 1, #t do c(t[i], i) end
end
function table.createFill (n, v)
local res = {}
for i = 1, n do res[i] = v end
return res
end
--[[
* 打印 table
* @param {any} val 传入值
* @return {str} 格式化后的文本
]]
function table.print (val)
local function loop (val, keyType, _indent)
_indent = _indent or 1
keyType = keyType or "string"
local res = ""
local indentStr = " " -- 缩进空格
local indent = string.rep(indentStr, _indent)
local end_indent = string.rep(indentStr, _indent - 1)
local putline = function (...)
local arr = { res, ... }
for i = 1, #arr do
if type(arr[i]) ~= "string" then arr[i] = tostring(arr[i]) end
end
res = table.concat(arr)
end
if type(val) == "table" then
putline("{ ")
if #val > 0 then
local index = 0
local block = false
for i = 1, #val do
local n = val[i]
if type(n) == "table" or type(n) == "function" then
block = true
break
end
end
if block then
for i = 1, #val do
local n = val[i]
index = index + 1
if index == 1 then putline("\n") end
putline(indent, loop(n, type(i), _indent + 1), "\n")
if index == #val then putline(end_indent) end
end
else
for i = 1, #val do
local n = val[i]
index = index + 1
putline(loop(n, type(i), _indent + 1))
end
end
else
putline("\n")
for k, v in pairs(val) do
putline(indent, k, " = ", loop(v, type(k), _indent + 1), "\n")
end
putline(end_indent)
end
putline("}, ")
elseif type(val) == "string" then
val = string.gsub(val, "\a", "\\a") -- 响铃(BEL)
val = string.gsub(val, "\b", "\\b") -- 退格(BS),将当前位置移到前一列
val = string.gsub(val, "\f", "\\f") -- 换页(FF),将当前位置移到下页开头
val = string.gsub(val, "\n", "\\n") -- 换行(LF),将当前位置移到下一行开头
val = string.gsub(val, "\r", "\\r") -- 回车(CR),将当前位置移到本行开头
val = string.gsub(val, "\t", "\\t") -- 水平指标(HT),(调用下一个TAB位置)
val = string.gsub(val, "\v", "\\v") -- 垂直指标(VT)
putline("\"", val, "\", ")
elseif type(val) == "boolean" then
putline(val and "true, " or "false, ")
elseif type(val) == "function" then
putline(tostring(val), ", ")
elseif type(val) == "nil" then
putline("nil, ")
else
putline(val, ", ")
end
return res
end
local res = loop(val)
res = string.gsub(res, ",(%s*})", "%1")
res = string.gsub(res, ",(%s*)$", "%1")
res = string.gsub(res, "{%s+}", "{}")
return res
end
----------------------------------------------------------------------------------------------------
-- Default event --
----------------------------------------------------------------------------------------------------
lmf.on('unload', function ()
EnablePrimaryMouseButtonEvents(false)
end)
----------------------------------------------------------------------------------------------------
-- Entry function --
----------------------------------------------------------------------------------------------------
function OnEvent (event, arg, family)
-- console.log("event = " .. event .. ", arg = " .. arg .. ", family = " .. family)
table.forEach(lmf.events, function (n, i)
if event == n[1] then
lmf._emit(n[2], arg, family)
end
end)
end
function lmf._emit (ename, arg, family)
if arg == 2 then arg = 3 elseif arg == 3 then arg = 2 end
local list = { "lalt", "lctrl", "lshift", "ralt", "rctrl", "rshift" }
local res = {
event = ename, -- 触发的事件
g = arg, -- 触发事件的 G 键,包括鼠标、键盘、耳机等
family = family ~= "" and family or "other", -- 触发事件的设备 (鼠标或其他)
pressed = {}, -- 哪些 G 键是按住的状态 (仅支持判断 g1、g2、g3、g4、g5 五个鼠标 G 键)
modifier = {}, -- 哪些修饰键是按住的状态 (lalt、lctrl、lshift、ralt、rctrl、rshift)
capslock = isLock("capslock"), -- 大写锁定键是否开启
numlock = isLock("numlock"), -- 小键盘锁定是否开启
scrolllock = isLock("scrolllock"), -- 滚动锁定是否开启
}
for i = 1, 5 do
if isPressed(i) then
res.pressed[#res.pressed + 1] = "g" .. i
end
end
for i = 1, #list do
if isPressed(list[i]) then
res.modifier[#res.modifier + 1] = list[i]
end
end
lmf.emit(ename, res)
end
--||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||--
-- --
-- 从这里开始写你的代码 --
-- Start writing your code here. --
-- --
--||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||--
EnablePrimaryMouseButtonEvents(true)
-- Execute when the script is loaded
lmf.on("load", function ()
console.log("hello world")
end)
lmf.on('unload', function ()
console.clear()
end)
-- 按住左键连点效果实现范例 (开启大写生效)
-- local G1 = false
--
-- lmf.on("mousedown", function (e)
-- -- console.log(e)
-- if e.g == 1 and e.capslock then
-- G1 = true
-- setM(1)
-- end
-- end)
--
-- lmf.on("mkeydown", function (e)
-- if G1 and e.capslock then
-- setM(1)
-- mouseTap(1)
-- end
-- end)
--
-- lmf.on("mouseup", function (e)
-- if e.g == 1 then
-- G1 = false
-- end
-- end)
-- console.log(lmf)
---------------------------------------------- Code End --------------------------------------------
----------------------------------------------------------------------------------------------------