thinclient 0.0.4

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,17 @@
1
+ *.gem
2
+ *.rbc
3
+ .bundle
4
+ .config
5
+ .yardoc
6
+ Gemfile.lock
7
+ InstalledFiles
8
+ _yardoc
9
+ coverage
10
+ doc/
11
+ lib/bundler/man
12
+ pkg
13
+ rdoc
14
+ spec/reports
15
+ test/tmp
16
+ test/version_tmp
17
+ tmp
data/Gemfile ADDED
@@ -0,0 +1,4 @@
1
+ source 'https://rubygems.org'
2
+
3
+ # Specify your gem's dependencies in thinclient.gemspec
4
+ gemspec
@@ -0,0 +1,22 @@
1
+ Copyright (c) 2014 wangbaomi
2
+
3
+ MIT License
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining
6
+ a copy of this software and associated documentation files (the
7
+ "Software"), to deal in the Software without restriction, including
8
+ without limitation the rights to use, copy, modify, merge, publish,
9
+ distribute, sublicense, and/or sell copies of the Software, and to
10
+ permit persons to whom the Software is furnished to do so, subject to
11
+ the following conditions:
12
+
13
+ The above copyright notice and this permission notice shall be
14
+ included in all copies or substantial portions of the Software.
15
+
16
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
17
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
18
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
19
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
20
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
21
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
22
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
@@ -0,0 +1,29 @@
1
+ # Thinclient
2
+
3
+ TODO: Write a gem description
4
+
5
+ ## Installation
6
+
7
+ Add this line to your application's Gemfile:
8
+
9
+ gem 'thinclient'
10
+
11
+ And then execute:
12
+
13
+ $ bundle
14
+
15
+ Or install it yourself as:
16
+
17
+ $ gem install thinclient
18
+
19
+ ## Usage
20
+
21
+ TODO: Write usage instructions here
22
+
23
+ ## Contributing
24
+
25
+ 1. Fork it
26
+ 2. Create your feature branch (`git checkout -b my-new-feature`)
27
+ 3. Commit your changes (`git commit -am 'Add some feature'`)
28
+ 4. Push to the branch (`git push origin my-new-feature`)
29
+ 5. Create new Pull Request
@@ -0,0 +1 @@
1
+ require "bundler/gem_tasks"
Binary file
Binary file
Binary file
Binary file
@@ -0,0 +1,9 @@
1
+ require "rubygems"
2
+ require "logger"
3
+ require "thinclient/image"
4
+ require "thinclient/input"
5
+ require "thinclient/keyboard"
6
+ require "thinclient/keycode"
7
+ require "thinclient/mouse"
8
+ require "thinclient/mylogger"
9
+ require "thinclient/error"
@@ -0,0 +1,8 @@
1
+ module ThinClient
2
+ class Error
3
+ SUCCESS = 0
4
+ NO_IMAGEMATCH = 1
5
+
6
+
7
+ end
8
+ end
@@ -0,0 +1,101 @@
1
+ module ThinClient
2
+ class Image
3
+ # 图片匹配程序ImageMatch.exe.如果没有找到则返回NO_IMAGEMATCH
4
+ def self.setImageMatch(path = "ImageMatch.exe")
5
+ @ImageMatch = path.nil? ? "ImageMatch.exe" : path
6
+ if not File.exist?(@ImageMatch)
7
+ print("ImageMatch.exe Not Found\n")
8
+ return ThinClient::Error::NO_IMAGEMATCH
9
+ end
10
+ return ThinClient::Error::SUCCESS
11
+ end
12
+
13
+ # 查找图片坐标.任何错误导致的查找失败都返回坐标(0,0),查找成功返回具体坐标和查找时匹配的图片名称
14
+ def self.getPosition(img1, img2, similar = 0.8)
15
+ position = {:X => 0, :Y => 0, :resultImg => ""}
16
+ if (ThinClient::Error::SUCCESS != setImageMatch())
17
+ return position
18
+ end
19
+ if not File.exist?(img1)
20
+ print("Image #{img1} Not Found\n")
21
+ return position
22
+ end
23
+ if not File.exist?(img2)
24
+ print("Image #{img2} Not Found\n")
25
+ return position
26
+ end
27
+
28
+ info = `#{@ImageMatch} #{img1} #{img2} #{similar}`
29
+ if 0 === info.split(/,/)[0]
30
+ print("#{img1} and #{img2} Not Match\n")
31
+ return position
32
+ end
33
+
34
+ position[:X] = info.split(/,/)[0].to_i
35
+ position[:Y] = info.split(/,/)[1].to_i
36
+ position[:resultImg] = info.split(/,/)[2].to_s
37
+ return position
38
+ end
39
+
40
+ # 在当前屏幕中查找指定图片的坐标
41
+ def self.getPositionOnScreen(img, similar = 0.8)
42
+ if false == screenCap("tmp.png")
43
+ return false
44
+ end
45
+ return getPosition("tmp.png", img, similar)
46
+ end
47
+
48
+ # 查找图片是否存在
49
+ def self.include?(img1, img2, similar = 0.8)
50
+ position = getPosition(img1, img2, similar)
51
+ if (position[:X] != 0 && position[:Y] != 0)
52
+ return true
53
+ end
54
+ return false
55
+ end
56
+
57
+ # 在当前屏幕中是否存在指定图片
58
+ def self.includeOnScreen?(img, similar = 0.8)
59
+ if false == screenCap("tmp.png")
60
+ return false
61
+ end
62
+ return include?("tmp.png", img, similar)
63
+
64
+ end
65
+
66
+ # 截图保存
67
+ def self.screenCap(name = "tmp.png")
68
+ tempFile = "/sdcard/screen.png"
69
+ system("adb shell screencap -p #{tempFile}")
70
+ system("adb pull #{tempFile} #{name}")
71
+ unless File.exist?(name)
72
+ print "Screencap Fail"
73
+ return false
74
+ end
75
+ return true
76
+
77
+ end
78
+
79
+ # 通过鼠标点击图片(无论是瘦客户机的还是虚拟桌面的都可以点击到)
80
+ def self.mouseClick(img, similar = 0.8)
81
+ position = getPositionOnScreen(img, similar)
82
+ if (position[:X] === 0 || position[:Y] === 0)
83
+ return false
84
+ end
85
+ #print ("position:#{position}\n")
86
+ Mouse.moveTo(position[:X], position[:Y])
87
+ Mouse.click()
88
+ return true
89
+ end
90
+
91
+ # 触摸图片(这个操作无法触摸到虚拟桌面内的图片)
92
+ def self.tap(img, similar = 0.8)
93
+ position = getPositionOnScreen(img, similar)
94
+ if (position[:X] === 0 || position[:Y] === 0)
95
+ return false
96
+ end
97
+ #print ("position:#{position}\n")
98
+ system("adb shell input tap #{position[:X]} #{position[:Y]}")
99
+ end
100
+ end
101
+ end
@@ -0,0 +1,60 @@
1
+ module ThinClient
2
+ class Input
3
+ # input text
4
+ def self.text(str)
5
+ begin
6
+ str =str.to_s
7
+ strings = str.split(/ /)
8
+ strings.each{ |string|
9
+ system("adb shell input text #{string}")
10
+ Keyboard.sendKeys("space")
11
+ }
12
+ rescue => ex
13
+ Log.error("#{ex}")
14
+ print("#{ex}")
15
+ end
16
+
17
+ end
18
+
19
+ # input tap
20
+ def self.tap(x = 0, y = 0)
21
+ begin
22
+ if (x == nil || y == nil)
23
+ Log.error("Usage: dragDropImage(img, x, y)")
24
+ print("Usage: dragDropImage(img, x, y)")
25
+ return
26
+ end
27
+ x = x.to_i
28
+ y = y.to_i
29
+ rescue => ex
30
+ Log.error("#{ex}")
31
+ print("#{ex}")
32
+ end
33
+ system("adb shell input tap #{x}, #{y}")
34
+ end
35
+
36
+ # input keyevent
37
+ def self.keyevent(keycode)
38
+ system("adb shell input keyevent #{keycode}")
39
+ end
40
+
41
+ # input swipe
42
+ def self.swipe(x1 = 0, y1 = 0, x2 = 0, y2 = 0)
43
+ begin
44
+ if (x1 == nil || y1 == nil || x2 == nil || y2 == nil)
45
+ Log.error("Usage: dragDropImage(img, x, y)")
46
+ print("Usage: dragDropImage(img, x, y)")
47
+ return
48
+ end
49
+ x1 = x1.to_i
50
+ y1 = y1.to_i
51
+ x2 = x2.to_i
52
+ y2 = y2.to_i
53
+ rescue => ex
54
+ Log.error("#{ex}")
55
+ print("#{ex}")
56
+ end
57
+ system("adb shell input swipe #{x1} #{y1} #{x2} #{y2}")
58
+ end
59
+ end
60
+ end
@@ -0,0 +1,102 @@
1
+
2
+ module ThinClient
3
+
4
+ class Keyboard
5
+
6
+ @keyboardEvent = ""
7
+ @SYN_EVENT = ""
8
+
9
+ def initialize()
10
+ getKeyboardEvent()
11
+ end
12
+
13
+ # 获取键盘设备
14
+ def self.getKeyboardEvent()
15
+ # getevent获取到的键盘的名字不是统一的,观察到的名字中都包含" USB"字样
16
+ str = `adb shell getevent -p`
17
+
18
+ begin
19
+ events = str.scan(/\/dev\/input\/event.\r\n.* USB.*/)
20
+ Log.debug("Events:#{events}")
21
+ if (events.size != 2)
22
+ Log.error("Keyboard Not Found. It Cannot Work Without a Keyboard Connected to The ThinClient")
23
+ return false
24
+ end
25
+ @keyboardEvent = events[1].split(/\r/)[0]
26
+ @SYN_EVENT = "adb shell sendevent #{@keyboardEvent} 0 0 0"
27
+ #print @keyboardEvent
28
+ return true
29
+ rescue => ex
30
+ Log.error("#{ex}")
31
+ print ex
32
+ return false
33
+ end
34
+ end
35
+
36
+ # 按下键盘按键
37
+ def self.keyDown(keycode)
38
+ begin
39
+ keycode = keycode.to_s
40
+ rescue => ex
41
+ Log.error("#{ex}")
42
+ print("#{ex}")
43
+ end
44
+ system("adb shell sendevent #{@keyboardEvent} 1 #{keycode} 1")
45
+ system("#{@SYN_EVENT}")
46
+ end
47
+
48
+ # 抬起键盘按键
49
+ def self.keyUp(keycode)
50
+ begin
51
+ keycode = keycode.to_s
52
+ rescue => ex
53
+ Log.error("#{ex}")
54
+ print("#{ex}")
55
+ end
56
+ system("adb shell sendevent #{@keyboardEvent} 1 #{keycode} 0")
57
+ system("#{@SYN_EVENT}")
58
+ end
59
+
60
+ # 发送键盘按键,多个按键用"+"隔开(按键名称见KeyCode.Key)
61
+ def self.sendKeys(keys)
62
+ if false === getKeyboardEvent()
63
+ return
64
+ end
65
+ args = dealArg(keys)
66
+ args.each { |key|
67
+ keyDown(key)
68
+ }
69
+ args.each { |key|
70
+ keyUp(key)
71
+ }
72
+ end
73
+
74
+ # 处理输入的参数
75
+ def self.dealArg(keys)
76
+ begin
77
+ keys = keys.to_s
78
+ rescue => ex
79
+ Log.error("#{ex}")
80
+ print("#{ex}")
81
+ end
82
+ args = []
83
+ tmp = keys.split(/\+/)
84
+ Log.debug("Keys:#{tmp}")
85
+ tmp.each { |key|
86
+ key = "KEY_" + key.upcase
87
+ index = KeyCode.key2code(key)
88
+ if (index == 0xffff)
89
+ return args
90
+ end
91
+ args.push(index)
92
+ }
93
+ return args
94
+ end
95
+
96
+
97
+
98
+
99
+ end
100
+
101
+ end
102
+
@@ -0,0 +1,119 @@
1
+ module ThinClient
2
+ class KeyCode
3
+
4
+ Code = [
5
+ 0x0001, 0x0002, 0x0003, 0x0004,
6
+ 0x0005, 0x0006, 0x0007, 0x0008,
7
+ 0x0009, 0x000a, 0x000b, 0x000c,
8
+ 0x000d, 0x000e, 0x000f, 0x0010,
9
+ 0x0011, 0x0012, 0x0013, 0x0014,
10
+ 0x0015, 0x0016, 0x0017, 0x0018,
11
+ 0x0019, 0x001a, 0x001b, 0x001c,
12
+ 0x001d, 0x001e, 0x001f, 0x0020,
13
+ 0x0021, 0x0022, 0x0023, 0x0024,
14
+ 0x0025, 0x0026, 0x0027, 0x0028,
15
+ 0x0029, 0x002a, 0x002b, 0x002c,
16
+ 0x002d, 0x002e, 0x002f, 0x0030,
17
+ 0x0031, 0x0032, 0x0033, 0x0034,
18
+ 0x0035, 0x0036, 0x0037, 0x0038,
19
+ 0x0039, 0x003a, 0x003b, 0x003c,
20
+ 0x003d, 0x003e, 0x003f, 0x0040,
21
+ 0x0041, 0x0042, 0x0043, 0x0044,
22
+ 0x0045, 0x0046, 0x0047, 0x0048,
23
+ 0x0049, 0x004a, 0x004b, 0x004c,
24
+ 0x004d, 0x004e, 0x004f, 0x0050,
25
+ 0x0051, 0x0052, 0x0053, 0x0056,
26
+ 0x0057, 0x0058, 0x0059, 0x005c,
27
+ 0x005d, 0x005e, 0x005f, 0x0060,
28
+ 0x0061, 0x0062, 0x0063, 0x0064,
29
+ 0x0066, 0x0067, 0x0068, 0x0069,
30
+ 0x006a, 0x006b, 0x006c, 0x006d,
31
+ 0x006e, 0x006f, 0x0071, 0x0072,
32
+ 0x0073, 0x0074, 0x0075, 0x0077,
33
+ 0x0079, 0x007a, 0x007b, 0x007c,
34
+ 0x007d, 0x007e, 0x007f, 0x0080,
35
+ 0x0081, 0x0082, 0x0083, 0x0084,
36
+ 0x0085, 0x0086, 0x0087, 0x0088,
37
+ 0x0089, 0x008a, 0x00b7, 0x00b8,
38
+ 0x00b9, 0x00ba, 0x00bb, 0x00bc,
39
+ 0x00bd, 0x00be, 0x00bf, 0x00c0,
40
+ 0x00c1, 0x00c2, 0x00f0,
41
+ #add
42
+ 0x007d, 0x0038, 0x001d, 0x002a,
43
+ 0x0029, 0x000c, 0x000d, 0x001a,
44
+ 0x001b, 0X0027, 0X0028, 0X002B,
45
+ 0X0033, 0X0034, 0X0035
46
+
47
+ ]
48
+
49
+ Key = [
50
+ "KEY_ESC", "KEY_1", "KEY_2", "KEY_3",
51
+ "KEY_4", "KEY_5", "KEY_6", "KEY_7",
52
+ "KEY_8", "KEY_9", "KEY_0", "KEY_MINUS",
53
+ "KEY_EQUAL", "KEY_BACKSPACE", "KEY_TAB", "KEY_Q",
54
+ "KEY_W", "KEY_E", "KEY_R", "KEY_T",
55
+ "KEY_Y", "KEY_U", "KEY_I", "KEY_O",
56
+ "KEY_P", "KEY_LEFTBRACE", "KEY_RIGHTBRACE",
57
+ "KEY_ENTER", "KEY_LEFTCTRL", "KEY_A","KEY_S",
58
+ "KEY_D", "KEY_F", "KEY_G", "KEY_H",
59
+ "KEY_J", "KEY_K", "KEY_L", "KEY_SEMICOLON",
60
+ "KEY_APOSTROPHE", "KEY_GRAVE","KEY_LEFTSHIFT","KEY_BACKSLASH",
61
+ "KEY_Z", "KEY_X", "KEY_C", "KEY_V",
62
+ "KEY_B", "KEY_N", "KEY_M", "KEY_COMMA",
63
+ "KEY_DOT", "KEY_SLASH","KEY_RIGHTSHIFT","KEY_KPASTERISK",
64
+ "KEY_LEFTALT", "KEY_SPACE","KEY_CAPSLOCK","KEY_F1",
65
+ "KEY_F2", "KEY_F3", "KEY_F4", "KEY_F5",
66
+ "KEY_F6", "KEY_F7", "KEY_F8", "KEY_F9",
67
+ "KEY_F10", "KEY_NUMLOCK","KEY_SCROLLLOCK","KEY_KP7",
68
+ "KEY_KP8", "KEY_KP9", "KEY_KPMINUS","KEY_KP4",
69
+ "KEY_KP5", "KEY_KP6", "KEY_KPPLUS","KEY_KP1",
70
+ "KEY_KP2", "KEY_KP3", "KEY_KP0", "KEY_KPDOT",
71
+ "KEY_102ND", "KEY_F11", "KEY_F12", "KEY_RO",
72
+ "KEY_HENKAN", "KEY_KATAKANAHIRAGANA","KEY_MUHENKAN","KEY_KPJPCOMMA",
73
+ "KEY_KPENTER", "KEY_RIGHTCTRL","KEY_KPSLASH","KEY_SYSRQ",
74
+ "KEY_RIGHTALT", "KEY_HOME","KEY_UP","KEY_PAGEUP",
75
+ "KEY_LEFT", "KEY_RIGHT","KEY_END","KEY_DOWN",
76
+ "KEY_PAGEDOWN", "KEY_INSERT","KEY_DELETE","KEY_MUTE",
77
+ "KEY_VOLUMEDOWN", "KEY_VOLUMEUP","KEY_POWER","KEY_KPEQUAL",
78
+ "KEY_PAUSE", "KEY_KPCOMMA","KEY_HANGEUL","KEY_HANJA",
79
+ "KEY_YEN", "KEY_LEFTMETA","KEY_RIGHTMETA","KEY_COMPOSE",
80
+ "KEY_STOP", "KEY_AGAIN","KEY_PROPS","KEY_UNDO",
81
+ "KEY_FRONT", "KEY_COPY","KEY_OPEN","KEY_PASTE",
82
+ "KEY_FIND", "KEY_CUT","KEY_HELP","KEY_F13",
83
+ "KEY_F14", "KEY_F15","KEY_F16","KEY_F17",
84
+ "KEY_F18", "KEY_F19","KEY_F20","KEY_F21","KEY_F22",
85
+ "KEY_F23", "KEY_F24", "KEY_UNKNOWN",
86
+ #add
87
+ "KEY_WIN", "KEY_ALT", "KEY_CTRL", "KEY_SHIFT",
88
+ "KEY_`", "KEY_-", "KEY_=", "KEY_[",
89
+ "KEY_]", "KEY_;", "KEY_'", "KEY_\\",
90
+ "KEY_,", "KEY_.", "KEY_/"
91
+ ]
92
+
93
+ def self.key2code(key)
94
+ begin
95
+ key = key.to_s
96
+ rescue => ex
97
+ Log.error("#{ex}")
98
+ print("#{ex}")
99
+ end
100
+ index = Key.index(key)
101
+ if (index != nil)
102
+ return Code[index]
103
+ end
104
+ print "No such key:#{key}\n"
105
+ Log.error("No such key:#{key}")
106
+ return 0xffff
107
+ end
108
+
109
+ def self.code2key(code)
110
+ index = Code.index(code)
111
+ if (index != nil)
112
+ return Key[index]
113
+ end
114
+ return "NULL"
115
+ end
116
+
117
+
118
+ end
119
+ end
@@ -0,0 +1,318 @@
1
+ module ThinClient
2
+ class Mouse
3
+ @mouseEvent = ""
4
+ @SYN_EVENT = ""
5
+ @realX = 1920.0
6
+ @realY = 1080.0
7
+ @virtualX = 1280.0
8
+ @virtualY = 720.0
9
+ # 瘦客户机上移动n个像素,实际需要移动n+n*0.2的
10
+ @diffX = 0.2
11
+ @diffY = 0.2
12
+ def initialize()
13
+ getMouseEvent()
14
+ end
15
+ # 先设定独享桌面的分辨率
16
+ def self.setResolution(x = 1280, y = 720)
17
+ @virtualX = x
18
+ @virtualY = y
19
+ end
20
+ def self.getMouseEvent()
21
+ if @mouseEvent != ""
22
+ return true
23
+ end
24
+ str = `adb shell getevent -p`
25
+ begin
26
+ events = str.scan(/\/dev\/input\/event.\r\n.* Mouse.*/)
27
+ Log.debug("Events:#{events}")
28
+ if (events.size != 1)
29
+ Log.error("Mouse Not Found. It Cannot Work Without a Mouse Connected to The ThinClient")
30
+ return false
31
+ end
32
+ @mouseEvent = events[0].split(/\r/)[0]
33
+
34
+ @SYN_EVENT = "adb shell sendevent #{@mouseEvent} 0 0 0"
35
+
36
+ setResolution()
37
+ #print @mouseEvent
38
+ return true
39
+ rescue => ex
40
+ Log.error("#{ex}")
41
+ print ex
42
+ return false
43
+ end
44
+ end
45
+
46
+ # 向左移动(n个像素)
47
+ def self.left(n = 1)
48
+ begin
49
+ n = n.to_i
50
+ rescue => ex
51
+ Log.error("#{ex}")
52
+ print("#{ex}")
53
+ end
54
+ getMouseEvent()
55
+ n = n / (1 + @diffX)
56
+ system("adb shell sendevent #{@mouseEvent} 2 0 -#{n}")
57
+ system("#{@SYN_EVENT}")
58
+ end
59
+ # 向右移动(n个像素)
60
+ def self.right(n = 1)
61
+ begin
62
+ n = n.to_i
63
+ rescue => ex
64
+ Log.error("#{ex}")
65
+ print("#{ex}")
66
+ end
67
+ getMouseEvent()
68
+ n = n / (1 + @diffX)
69
+ system("adb shell sendevent #{@mouseEvent} 2 0 #{n}")
70
+ system("#{@SYN_EVENT}")
71
+ end
72
+ # 向上移动(n个像素)
73
+ def self.up(n = 1)
74
+ begin
75
+ n = n.to_i
76
+ rescue => ex
77
+ Log.error("#{ex}")
78
+ print("#{ex}")
79
+ end
80
+ getMouseEvent()
81
+ n = n / (1 + @diffY)
82
+ system("adb shell sendevent #{@mouseEvent} 2 1 -#{n}")
83
+ system("#{@SYN_EVENT}")
84
+ end
85
+ # 向下移动(n个像素)
86
+ def self.down(n = 1)
87
+ begin
88
+ n = n.to_i
89
+ rescue => ex
90
+ Log.error("#{ex}")
91
+ print("#{ex}")
92
+ end
93
+ getMouseEvent()
94
+ n = n / (1 + @diffY)
95
+ system("adb shell sendevent #{@mouseEvent} 2 1 #{n}")
96
+ system("#{@SYN_EVENT}")
97
+ end
98
+
99
+ # 移动到某个位置
100
+ def self.moveTo(x = nil, y = nil)
101
+ if false === getMouseEvent()
102
+ return false
103
+ end
104
+ if (x != nil && y != nil)
105
+ left(5000)
106
+ up(5000)
107
+ right(x)
108
+ down(y)
109
+ return
110
+ end
111
+ if (x != nil)
112
+ left(5000)
113
+ right(x)
114
+ end
115
+ if (y != nil)
116
+ up(5000)
117
+ down(y)
118
+ end
119
+ end
120
+
121
+
122
+
123
+ # 左键按下
124
+ def self.leftBtnDown()
125
+ system("adb shell sendevent #{@mouseEvent} 1 272 1")
126
+ system("#{@SYN_EVENT}")
127
+ end
128
+ # 左键抬起
129
+ def self.leftBtnUp()
130
+ system("adb shell sendevent #{@mouseEvent} 1 272 0")
131
+ system("#{@SYN_EVENT}")
132
+ end
133
+ # 右键按下
134
+ def self.rightBtnDown()
135
+ system("adb shell sendevent #{@mouseEvent} 1 273 1")
136
+ system("#{@SYN_EVENT}")
137
+ end
138
+ # 右键抬起
139
+ def self.rightBtnUp()
140
+ system("adb shell sendevent #{@mouseEvent} 1 273 0")
141
+ system("#{@SYN_EVENT}")
142
+ end
143
+ # 滚轮按下
144
+ def self.middleBtnDown()
145
+ system("adb shell sendevent #{@mouseEvent} 1 274 1")
146
+ system("#{@SYN_EVENT}")
147
+ end
148
+ # 滚轮抬起
149
+ def self.middleBtnUp()
150
+ system("adb shell sendevent #{@mouseEvent} 1 274 0")
151
+ system("#{@SYN_EVENT}")
152
+ end
153
+
154
+ # 单击(某个坐标)
155
+ def self.click(x = nil, y = nil)
156
+ moveTo(x, y)
157
+ leftBtnDown()
158
+ leftBtnUp()
159
+ end
160
+ # 双击(某个坐标)
161
+ def self.doubleClick(x = nil, y = nil)
162
+ moveTo(x, y)
163
+ leftBtnDown()
164
+ leftBtnUp()
165
+ leftBtnDown()
166
+ leftBtnUp()
167
+ end
168
+ # 按下(按下时间,某个坐标)
169
+ def self.press(t = 2, x = nil, y = nil)
170
+ moveTo(x, y)
171
+ leftBtnDown()
172
+ sleep(t)
173
+ leftBtnUp()
174
+ end
175
+ # 拖拽
176
+ def self.dragDrop(x1 = 0, y1 = 0, x2 = 0, y2 = 0)
177
+ moveTo(x1, y1)
178
+ leftBtnDown()
179
+ #moveTo(x2, y2)
180
+ begin
181
+ x1 = x1.to_i
182
+ y1 = y1.to_i
183
+ x2 = x2.to_i
184
+ y2 = y2.to_i
185
+ rescue => ex
186
+ Log.error("#{ex}")
187
+ print("#{ex}")
188
+ end
189
+ right(x2 - x1)
190
+ down(y2 - y1)
191
+ leftBtnUp()
192
+ end
193
+ # 右击
194
+ def self.rightClick(x = nil, y = nil)
195
+ moveTo(x, y)
196
+ rightBtnDown()
197
+ rightBtnUp()
198
+ end
199
+
200
+ # 滚轮向下滚动
201
+ def self.rollDown(n = 1)
202
+ begin
203
+ n = n.to_i
204
+ rescue => ex
205
+ Log.error("#{ex}")
206
+ print("#{ex}")
207
+ end
208
+ if false === getMouseEvent()
209
+ return
210
+ end
211
+ while (n > 0)
212
+ system("adb shell sendevent #{@mouseEvent} 2 8 -1")
213
+ system("#{@SYN_EVENT}")
214
+ n -= 1
215
+ end
216
+ end
217
+ # 滚轮向上滚动
218
+ def self.rollUp(n = 1)
219
+ begin
220
+ n = n.to_i
221
+ rescue => ex
222
+ Log.error("#{ex}")
223
+ print("#{ex}")
224
+ end
225
+ if false === getMouseEvent()
226
+ return
227
+ end
228
+ while (n > 0)
229
+ system("adb shell sendevent #{@mouseEvent} 2 8 1")
230
+ system("#{@SYN_EVENT}")
231
+ n -= 1
232
+ end
233
+ end
234
+ # 单击滚轮
235
+ def self.rollClick()
236
+ if false === getMouseEvent()
237
+ return
238
+ end
239
+ middleBtnDown()
240
+ middleBtnUp()
241
+ end
242
+
243
+ # 单击图片
244
+ def self.clickImage(img, similar = 0.8)
245
+ position = Image.getPositionOnScreen(img, similar)
246
+ if (position[:X] === 0 || position[:Y] === 0)
247
+ return false
248
+ end
249
+ click(position[:X], position[:Y])
250
+ return true
251
+ end
252
+
253
+ # 双击图片
254
+ def self.doubleClickImage(img, similar = 0.8)
255
+ position = Image.getPositionOnScreen(img, similar)
256
+ if (position[:X] === 0 || position[:Y] === 0)
257
+ return false
258
+ end
259
+ doubleClick(position[:X], position[:Y])
260
+ return true
261
+ end
262
+
263
+ # 右击图片
264
+ def self.rightClickImage(img, similar = 0.8)
265
+ position = Image.getPositionOnScreen(img, similar)
266
+ if (position[:X] === 0 || position[:Y] === 0)
267
+ return false
268
+ end
269
+ rightClick(position[:X], position[:Y])
270
+ return true
271
+ end
272
+
273
+ # 长按图片
274
+ def self.pressImage(img, t = 2, similar = 0.8)
275
+ position = Image.getPositionOnScreen(img, similar)
276
+ if (position[:X] === 0 || position[:Y] === 0)
277
+ return false
278
+ end
279
+ press(t, position[:X], position[:Y])
280
+ return true
281
+ end
282
+
283
+ # 拖拽图片到指定位置
284
+ def self.dragDropImage(img, x = 0, y = 0, similar = 0.8)
285
+ begin
286
+ if (x == nil || y == nil)
287
+ Log.error("Usage: dragDropImage(img, x, y)")
288
+ print("Usage: dragDropImage(img, x, y)")
289
+ return
290
+ end
291
+ x = x.to_i
292
+ y = y.to_i
293
+ rescue => ex
294
+ Log.error("#{ex}")
295
+ print("#{ex}")
296
+ end
297
+ position = Image.getPositionOnScreen(img, similar)
298
+ if (position[:X] === 0 || position[:Y] === 0)
299
+ return false
300
+ end
301
+ dragDrop(position[:X], position[:Y], x, y)
302
+ return true
303
+ end
304
+
305
+ # 拖拽图片1到图片2上
306
+ def self.dragDropImagetoImage(img1, img2, similar1 = 0.8, similar2 = 0.8)
307
+ position1 = Image.getPositionOnScreen(img, similar1)
308
+ position2 = Image.getPositionOnScreen(img2, similar2)
309
+ if (position1[:X] === 0 || position1[:Y] === 0 || position2[:X] === 0 || position2[:Y] ===0)
310
+ return false
311
+ end
312
+ dragDrop(position1[:X], position1[:Y], position2[:X], position2[:Y])
313
+ return true
314
+ end
315
+
316
+
317
+ end
318
+ end
@@ -0,0 +1,36 @@
1
+ require 'rubygems' if RUBY_VERSION =~ /^1.8/
2
+ require 'logger'
3
+
4
+ module ThinClient
5
+ class Log
6
+ def self.init()
7
+ @myLogger = Logger.new(File.new(File.join("ThinClient.log"), "a"))
8
+ @myLogger.datetime_format = "%m%d-%H:%M:%S"
9
+ end
10
+
11
+ def self.info(str)
12
+ init()
13
+ @myLogger.info(str)
14
+ end
15
+
16
+ def self.debug(str)
17
+ init()
18
+ @myLogger.debug(str)
19
+ end
20
+
21
+ def self.error(str)
22
+ init()
23
+ @myLogger.error(str)
24
+ end
25
+
26
+ def self.warn(str)
27
+ init()
28
+ @myLogger.warn(str)
29
+ end
30
+
31
+ def self.fatal(str)
32
+ init()
33
+ @myLogger.fatal(str)
34
+ end
35
+ end
36
+ end
@@ -0,0 +1,3 @@
1
+ module Thinclient
2
+ VERSION = "0.0.4"
3
+ end
@@ -0,0 +1,19 @@
1
+ # -*- encoding: utf-8 -*-
2
+ lib = File.expand_path('../lib', __FILE__)
3
+ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
4
+ require 'thinclient/version'
5
+
6
+ Gem::Specification.new do |gem|
7
+ gem.name = "thinclient"
8
+ gem.version = Thinclient::VERSION
9
+ gem.authors = ["wangbaomi"]
10
+ gem.email = ["system1029@gmail.com"]
11
+ gem.description = %q{SSL ThinClict}
12
+ gem.summary = %q{SSL ThinClict}
13
+ gem.homepage = ""
14
+
15
+ gem.files = `git ls-files`.split($/)
16
+ gem.executables = gem.files.grep(%r{^bin/}).map{ |f| File.basename(f) }
17
+ gem.test_files = gem.files.grep(%r{^(test|spec|features)/})
18
+ gem.require_paths = ["lib"]
19
+ end
metadata ADDED
@@ -0,0 +1,87 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: thinclient
3
+ version: !ruby/object:Gem::Version
4
+ hash: 23
5
+ prerelease:
6
+ segments:
7
+ - 0
8
+ - 0
9
+ - 4
10
+ version: 0.0.4
11
+ platform: ruby
12
+ authors:
13
+ - wangbaomi
14
+ autorequire:
15
+ bindir: bin
16
+ cert_chain: []
17
+
18
+ date: 2014-05-21 00:00:00 Z
19
+ dependencies: []
20
+
21
+ description: SSL ThinClict
22
+ email:
23
+ - system1029@gmail.com
24
+ executables:
25
+ - ImageMatch.exe
26
+ - opencv_core248.dll
27
+ - opencv_highgui248.dll
28
+ - opencv_imgproc248.dll
29
+ extensions: []
30
+
31
+ extra_rdoc_files: []
32
+
33
+ files:
34
+ - .gitignore
35
+ - Gemfile
36
+ - LICENSE.txt
37
+ - README.md
38
+ - Rakefile
39
+ - bin/ImageMatch.exe
40
+ - bin/opencv_core248.dll
41
+ - bin/opencv_highgui248.dll
42
+ - bin/opencv_imgproc248.dll
43
+ - lib/thinclient.rb
44
+ - lib/thinclient/error.rb
45
+ - lib/thinclient/image.rb
46
+ - lib/thinclient/input.rb
47
+ - lib/thinclient/keyboard.rb
48
+ - lib/thinclient/keycode.rb
49
+ - lib/thinclient/mouse.rb
50
+ - lib/thinclient/mylogger.rb
51
+ - lib/thinclient/version.rb
52
+ - thinclient.gemspec
53
+ homepage: ""
54
+ licenses: []
55
+
56
+ post_install_message:
57
+ rdoc_options: []
58
+
59
+ require_paths:
60
+ - lib
61
+ required_ruby_version: !ruby/object:Gem::Requirement
62
+ none: false
63
+ requirements:
64
+ - - ">="
65
+ - !ruby/object:Gem::Version
66
+ hash: 3
67
+ segments:
68
+ - 0
69
+ version: "0"
70
+ required_rubygems_version: !ruby/object:Gem::Requirement
71
+ none: false
72
+ requirements:
73
+ - - ">="
74
+ - !ruby/object:Gem::Version
75
+ hash: 3
76
+ segments:
77
+ - 0
78
+ version: "0"
79
+ requirements: []
80
+
81
+ rubyforge_project:
82
+ rubygems_version: 1.8.24
83
+ signing_key:
84
+ specification_version: 3
85
+ summary: SSL ThinClict
86
+ test_files: []
87
+