ssc.bot 0.1.0
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.
- checksums.yaml +7 -0
- data/CHANGELOG.md +40 -0
- data/Gemfile +25 -0
- data/LICENSE.txt +165 -0
- data/README.md +115 -0
- data/Rakefile +52 -0
- data/lib/ssc.bot.rb +44 -0
- data/lib/ssc.bot/chat_log.rb +283 -0
- data/lib/ssc.bot/chat_log/message.rb +86 -0
- data/lib/ssc.bot/chat_log/message_parsable.rb +62 -0
- data/lib/ssc.bot/chat_log/message_parser.rb +562 -0
- data/lib/ssc.bot/chat_log/messages.rb +193 -0
- data/lib/ssc.bot/chat_log_file.rb +52 -0
- data/lib/ssc.bot/error.rb +61 -0
- data/lib/ssc.bot/ssc_file.rb +132 -0
- data/lib/ssc.bot/user/jrobot_message_sender.rb +194 -0
- data/lib/ssc.bot/user/message_sender.rb +378 -0
- data/lib/ssc.bot/util.rb +90 -0
- data/lib/ssc.bot/version.rb +26 -0
- data/ssc.bot.gemspec +68 -0
- data/test/test_helper.rb +28 -0
- metadata +179 -0
@@ -0,0 +1,193 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
# encoding: UTF-8
|
3
|
+
# frozen_string_literal: true
|
4
|
+
|
5
|
+
#--
|
6
|
+
# This file is part of SSC.Bot.
|
7
|
+
# Copyright (c) 2020 Jonathan Bradley Whited (@esotericpig)
|
8
|
+
#
|
9
|
+
# SSC.Bot is free software: you can redistribute it and/or modify
|
10
|
+
# it under the terms of the GNU Lesser General Public License as published by
|
11
|
+
# the Free Software Foundation, either version 3 of the License, or
|
12
|
+
# (at your option) any later version.
|
13
|
+
#
|
14
|
+
# SSC.Bot is distributed in the hope that it will be useful,
|
15
|
+
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
16
|
+
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
17
|
+
# GNU Lesser General Public License for more details.
|
18
|
+
#
|
19
|
+
# You should have received a copy of the GNU Lesser General Public License
|
20
|
+
# along with SSC.Bot. If not, see <https://www.gnu.org/licenses/>.
|
21
|
+
#++
|
22
|
+
|
23
|
+
|
24
|
+
require 'attr_bool'
|
25
|
+
|
26
|
+
require 'ssc.bot/chat_log/message'
|
27
|
+
|
28
|
+
|
29
|
+
module SSCBot
|
30
|
+
class ChatLog
|
31
|
+
###
|
32
|
+
# @author Jonathan Bradley Whited (@esotericpig)
|
33
|
+
# @since 0.1.0
|
34
|
+
###
|
35
|
+
class PlayerMessage < Message
|
36
|
+
attr_reader :message
|
37
|
+
attr_reader :name
|
38
|
+
|
39
|
+
def initialize(line,type:,name:,message:)
|
40
|
+
super(line,type: type)
|
41
|
+
|
42
|
+
@message = message
|
43
|
+
@name = name
|
44
|
+
end
|
45
|
+
end
|
46
|
+
|
47
|
+
###
|
48
|
+
# @author Jonathan Bradley Whited (@esotericpig)
|
49
|
+
# @since 0.1.0
|
50
|
+
###
|
51
|
+
class ChatMessage < PlayerMessage
|
52
|
+
attr_reader :channel
|
53
|
+
|
54
|
+
def initialize(line,channel:,name:,message:)
|
55
|
+
super(line,type: :chat,name: name,message: message)
|
56
|
+
|
57
|
+
@channel = channel
|
58
|
+
end
|
59
|
+
end
|
60
|
+
|
61
|
+
###
|
62
|
+
# @author Jonathan Bradley Whited (@esotericpig)
|
63
|
+
# @since 0.1.0
|
64
|
+
###
|
65
|
+
class FreqMessage < PlayerMessage
|
66
|
+
def initialize(line,name:,message:)
|
67
|
+
super(line,type: :freq,name: name,message: message)
|
68
|
+
end
|
69
|
+
end
|
70
|
+
|
71
|
+
###
|
72
|
+
# @author Jonathan Bradley Whited (@esotericpig)
|
73
|
+
# @since 0.1.0
|
74
|
+
###
|
75
|
+
class KillMessage < Message
|
76
|
+
attr_reader :bounty
|
77
|
+
attr_reader :killed
|
78
|
+
attr_reader :killer
|
79
|
+
|
80
|
+
def initialize(line,killed:,bounty:,killer:)
|
81
|
+
super(line,type: :kill)
|
82
|
+
|
83
|
+
@bounty = bounty
|
84
|
+
@killed = killed
|
85
|
+
@killer = killer
|
86
|
+
end
|
87
|
+
end
|
88
|
+
|
89
|
+
###
|
90
|
+
# @author Jonathan Bradley Whited (@esotericpig)
|
91
|
+
# @since 0.1.0
|
92
|
+
###
|
93
|
+
class PrivateMessage < PlayerMessage
|
94
|
+
def initialize(line,name:,message:,type: :private)
|
95
|
+
super(line,type: type,name: name,message: message)
|
96
|
+
end
|
97
|
+
end
|
98
|
+
|
99
|
+
###
|
100
|
+
# @author Jonathan Bradley Whited (@esotericpig)
|
101
|
+
# @since 0.1.0
|
102
|
+
###
|
103
|
+
class PubMessage < PlayerMessage
|
104
|
+
def initialize(line,name:,message:)
|
105
|
+
super(line,type: :pub,name: name,message: message)
|
106
|
+
end
|
107
|
+
end
|
108
|
+
|
109
|
+
###
|
110
|
+
# @author Jonathan Bradley Whited (@esotericpig)
|
111
|
+
# @since 0.1.0
|
112
|
+
###
|
113
|
+
class QFindMessage < Message
|
114
|
+
attr_reader :arena
|
115
|
+
attr_reader :days
|
116
|
+
attr_reader :find_type # [:arena,:days,:hours,:zone]
|
117
|
+
attr_reader :hours
|
118
|
+
attr_reader? :more
|
119
|
+
attr_reader :player
|
120
|
+
attr_reader? :private
|
121
|
+
attr_reader :zone
|
122
|
+
|
123
|
+
def initialize(line,find_type:,arena: nil,days: nil,hours: nil,more: false,player: nil,private: false,zone: nil)
|
124
|
+
super(line,type: %s{?find})
|
125
|
+
|
126
|
+
@arena = arena
|
127
|
+
@days = days
|
128
|
+
@find_type = find_type
|
129
|
+
@hours = hours
|
130
|
+
@more = more
|
131
|
+
@player = player
|
132
|
+
@private = private
|
133
|
+
@zone = zone
|
134
|
+
end
|
135
|
+
end
|
136
|
+
|
137
|
+
###
|
138
|
+
# @author Jonathan Bradley Whited (@esotericpig)
|
139
|
+
# @since 0.1.0
|
140
|
+
###
|
141
|
+
class QLogMessage < Message
|
142
|
+
attr_reader :filename
|
143
|
+
attr_reader :log_type # [:open,:close]
|
144
|
+
|
145
|
+
def initialize(line,log_type:,filename: nil)
|
146
|
+
super(line,type: %s{?log})
|
147
|
+
|
148
|
+
@filename = filename
|
149
|
+
@log_type = log_type
|
150
|
+
end
|
151
|
+
end
|
152
|
+
|
153
|
+
###
|
154
|
+
# @author Jonathan Bradley Whited (@esotericpig)
|
155
|
+
# @since 0.1.0
|
156
|
+
###
|
157
|
+
class QNamelenMessage < Message
|
158
|
+
attr_reader :namelen
|
159
|
+
|
160
|
+
def initialize(line,namelen:)
|
161
|
+
super(line,type: %s{?namelen})
|
162
|
+
|
163
|
+
@namelen = namelen
|
164
|
+
end
|
165
|
+
end
|
166
|
+
|
167
|
+
###
|
168
|
+
# @author Jonathan Bradley Whited (@esotericpig)
|
169
|
+
# @since 0.1.0
|
170
|
+
###
|
171
|
+
class RemoteMessage < PrivateMessage
|
172
|
+
attr_reader? :own
|
173
|
+
attr_reader? :squad
|
174
|
+
|
175
|
+
def initialize(line,own:,squad:,name:,message:)
|
176
|
+
super(line,type: :remote,name: name,message: message)
|
177
|
+
|
178
|
+
@own = own
|
179
|
+
@squad = squad
|
180
|
+
end
|
181
|
+
end
|
182
|
+
|
183
|
+
###
|
184
|
+
# @author Jonathan Bradley Whited (@esotericpig)
|
185
|
+
# @since 0.1.0
|
186
|
+
###
|
187
|
+
class TeamMessage < PlayerMessage
|
188
|
+
def initialize(line,name:,message:)
|
189
|
+
super(line,type: :team,name: name,message: message)
|
190
|
+
end
|
191
|
+
end
|
192
|
+
end
|
193
|
+
end
|
@@ -0,0 +1,52 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
# encoding: UTF-8
|
3
|
+
# frozen_string_literal: true
|
4
|
+
|
5
|
+
#--
|
6
|
+
# This file is part of SSC.Bot.
|
7
|
+
# Copyright (c) 2020 Jonathan Bradley Whited (@esotericpig)
|
8
|
+
#
|
9
|
+
# SSC.Bot is free software: you can redistribute it and/or modify
|
10
|
+
# it under the terms of the GNU Lesser General Public License as published by
|
11
|
+
# the Free Software Foundation, either version 3 of the License, or
|
12
|
+
# (at your option) any later version.
|
13
|
+
#
|
14
|
+
# SSC.Bot is distributed in the hope that it will be useful,
|
15
|
+
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
16
|
+
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
17
|
+
# GNU Lesser General Public License for more details.
|
18
|
+
#
|
19
|
+
# You should have received a copy of the GNU Lesser General Public License
|
20
|
+
# along with SSC.Bot. If not, see <https://www.gnu.org/licenses/>.
|
21
|
+
#++
|
22
|
+
|
23
|
+
|
24
|
+
require 'ssc.bot/ssc_file'
|
25
|
+
|
26
|
+
require 'ssc.bot/chat_log/message'
|
27
|
+
require 'ssc.bot/chat_log/message_parsable'
|
28
|
+
require 'ssc.bot/chat_log/message_parser'
|
29
|
+
require 'ssc.bot/chat_log/messages'
|
30
|
+
|
31
|
+
|
32
|
+
module SSCBot
|
33
|
+
###
|
34
|
+
# @author Jonathan Bradley Whited (@esotericpig)
|
35
|
+
# @since 0.1.0
|
36
|
+
###
|
37
|
+
class ChatLogFile < SSCFile
|
38
|
+
include ChatLog::MessageParsable
|
39
|
+
|
40
|
+
def initialize(filename,mode=DEFAULT_MODE,parser: ChatLog::MessageParser.new(),**file_kargs)
|
41
|
+
super(filename,mode,**file_kargs)
|
42
|
+
|
43
|
+
@parser = parser
|
44
|
+
end
|
45
|
+
|
46
|
+
def parse_line()
|
47
|
+
line = get_line()
|
48
|
+
|
49
|
+
return line.nil?() ? nil : parse(line)
|
50
|
+
end
|
51
|
+
end
|
52
|
+
end
|
@@ -0,0 +1,61 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
# encoding: UTF-8
|
3
|
+
# frozen_string_literal: true
|
4
|
+
|
5
|
+
#--
|
6
|
+
# This file is part of SSC.Bot.
|
7
|
+
# Copyright (c) 2020 Jonathan Bradley Whited (@esotericpig)
|
8
|
+
#
|
9
|
+
# SSC.Bot is free software: you can redistribute it and/or modify
|
10
|
+
# it under the terms of the GNU Lesser General Public License as published by
|
11
|
+
# the Free Software Foundation, either version 3 of the License, or
|
12
|
+
# (at your option) any later version.
|
13
|
+
#
|
14
|
+
# SSC.Bot is distributed in the hope that it will be useful,
|
15
|
+
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
16
|
+
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
17
|
+
# GNU Lesser General Public License for more details.
|
18
|
+
#
|
19
|
+
# You should have received a copy of the GNU Lesser General Public License
|
20
|
+
# along with SSC.Bot. If not, see <https://www.gnu.org/licenses/>.
|
21
|
+
#++
|
22
|
+
|
23
|
+
|
24
|
+
module SSCBot
|
25
|
+
###
|
26
|
+
# @author Jonathan Bradley Whited (@esotericpig)
|
27
|
+
# @since 0.1.0
|
28
|
+
###
|
29
|
+
class Error < ::StandardError; end
|
30
|
+
|
31
|
+
###
|
32
|
+
# @author Jonathan Bradley Whited (@esotericpig)
|
33
|
+
# @since 0.1.0
|
34
|
+
###
|
35
|
+
class AbstractMethodError < Error
|
36
|
+
def initialize(msg=nil)
|
37
|
+
if msg.nil?()
|
38
|
+
method_name = caller[1]
|
39
|
+
|
40
|
+
if !method_name.nil?()
|
41
|
+
index = method_name.rindex('`')
|
42
|
+
|
43
|
+
if !index.nil?() && (index += 1) < method_name.length
|
44
|
+
method_name = method_name[index..-2]
|
45
|
+
|
46
|
+
msg = "abstract method{#{method_name}(...)} not implemented"
|
47
|
+
end
|
48
|
+
end
|
49
|
+
end
|
50
|
+
|
51
|
+
super(msg)
|
52
|
+
end
|
53
|
+
end
|
54
|
+
|
55
|
+
###
|
56
|
+
# @author Jonathan Bradley Whited (@esotericpig)
|
57
|
+
# @since 0.1.0
|
58
|
+
###
|
59
|
+
class ParseError < Error
|
60
|
+
end
|
61
|
+
end
|
@@ -0,0 +1,132 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
# encoding: UTF-8
|
3
|
+
# frozen_string_literal: true
|
4
|
+
|
5
|
+
#--
|
6
|
+
# This file is part of SSC.Bot.
|
7
|
+
# Copyright (c) 2020 Jonathan Bradley Whited (@esotericpig)
|
8
|
+
#
|
9
|
+
# SSC.Bot is free software: you can redistribute it and/or modify
|
10
|
+
# it under the terms of the GNU Lesser General Public License as published by
|
11
|
+
# the Free Software Foundation, either version 3 of the License, or
|
12
|
+
# (at your option) any later version.
|
13
|
+
#
|
14
|
+
# SSC.Bot is distributed in the hope that it will be useful,
|
15
|
+
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
16
|
+
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
17
|
+
# GNU Lesser General Public License for more details.
|
18
|
+
#
|
19
|
+
# You should have received a copy of the GNU Lesser General Public License
|
20
|
+
# along with SSC.Bot. If not, see <https://www.gnu.org/licenses/>.
|
21
|
+
#++
|
22
|
+
|
23
|
+
|
24
|
+
require 'ssc.bot/util'
|
25
|
+
|
26
|
+
|
27
|
+
module SSCBot
|
28
|
+
###
|
29
|
+
# @author Jonathan Bradley Whited (@esotericpig)
|
30
|
+
# @since 0.1.0
|
31
|
+
###
|
32
|
+
class SSCFile < ::File
|
33
|
+
DEFAULT_BUFFER_LEN = 520
|
34
|
+
DEFAULT_ENCODING = 'Windows-1252:UTF-8'
|
35
|
+
DEFAULT_MODE = 'rt'
|
36
|
+
DEFAULT_SEPARATOR = /\r?\n|\r/ # Instead, could use +/\R/+ for Ruby v2.0+
|
37
|
+
|
38
|
+
# Clear (truncate) the contents of +filename+.
|
39
|
+
#
|
40
|
+
# @param filename [String] the file to clear
|
41
|
+
# @param strip [Boolean] +true+ to strip +filename+ to help prevent fat-fingering, else +false+ to not
|
42
|
+
def self.clear_content(filename,strip: true,textmode: true,**opt)
|
43
|
+
filename = Util.u_strip(filename) if strip
|
44
|
+
|
45
|
+
return if filename.empty?()
|
46
|
+
return if !File.file?(filename) # Also checks if exists
|
47
|
+
|
48
|
+
# Clear the file.
|
49
|
+
# - Do NOT call truncate() as it's not available on all platforms.
|
50
|
+
open(filename,'w',textmode: textmode,**opt) do |file|
|
51
|
+
end
|
52
|
+
end
|
53
|
+
|
54
|
+
# If +filename+ exists, then it does nothing (does *not* update time),
|
55
|
+
# else, it creates the file.
|
56
|
+
#
|
57
|
+
# I just prefer this over +FileUtils.touch+.
|
58
|
+
#
|
59
|
+
# @param filename [String] the file to soft touch
|
60
|
+
# @param strip [Boolean] +true+ to strip +filename+ to help prevent fat-fingering, else +false+ to not
|
61
|
+
def self.soft_touch(filename,strip: true,textmode: true,**opt)
|
62
|
+
filename = Util.u_strip(filename) if strip
|
63
|
+
|
64
|
+
return if filename.empty?()
|
65
|
+
return if File.exist?(filename)
|
66
|
+
|
67
|
+
# Create the file.
|
68
|
+
open(filename,'a',textmode: textmode,**opt) do |file|
|
69
|
+
end
|
70
|
+
end
|
71
|
+
|
72
|
+
def initialize(filename,mode=DEFAULT_MODE,buffer_len: DEFAULT_BUFFER_LEN,encoding: DEFAULT_ENCODING,separator: DEFAULT_SEPARATOR,**opt)
|
73
|
+
super(filename,mode,encoding: encoding,**opt)
|
74
|
+
|
75
|
+
@sscbot_buffer = nil
|
76
|
+
@sscbot_buffer_len = buffer_len
|
77
|
+
@sscbot_separator = separator
|
78
|
+
end
|
79
|
+
|
80
|
+
def get_line()
|
81
|
+
if @sscbot_buffer.nil?()
|
82
|
+
# See comment at loop below.
|
83
|
+
# - Use gets() instead of eof?() because of this method's name.
|
84
|
+
line = gets(nil,@sscbot_buffer_len)
|
85
|
+
|
86
|
+
return nil if line.nil?() # Still EOF?
|
87
|
+
|
88
|
+
@sscbot_buffer = line
|
89
|
+
end
|
90
|
+
|
91
|
+
lines = @sscbot_buffer.split(@sscbot_separator,2)
|
92
|
+
|
93
|
+
# Will only have 2 if there was a separator.
|
94
|
+
if lines.length == 2
|
95
|
+
@sscbot_buffer = lines[1]
|
96
|
+
|
97
|
+
return lines[0]
|
98
|
+
end
|
99
|
+
|
100
|
+
# - Use a separator of nil to get all of the different types of newlines.
|
101
|
+
# - Use gets() [instead of read(), etc.] to work probably with text (e.g., UTF-8)
|
102
|
+
# and to not throw an error at EOF (returns nil).
|
103
|
+
while !(line = gets(nil,@sscbot_buffer_len)).nil?()
|
104
|
+
lines = line.split(@sscbot_separator,2)
|
105
|
+
|
106
|
+
# Will only have 2 if there was a separator.
|
107
|
+
if lines.length == 2
|
108
|
+
line = "#{@sscbot_buffer}#{lines[0]}"
|
109
|
+
@sscbot_buffer = lines[1]
|
110
|
+
|
111
|
+
return line
|
112
|
+
else
|
113
|
+
@sscbot_buffer << line
|
114
|
+
end
|
115
|
+
end
|
116
|
+
|
117
|
+
# EOF reached with text in the buffer.
|
118
|
+
line = @sscbot_buffer
|
119
|
+
@sscbot_buffer = nil
|
120
|
+
|
121
|
+
return line
|
122
|
+
end
|
123
|
+
|
124
|
+
def seek_to_end()
|
125
|
+
result = seek(0,:END)
|
126
|
+
|
127
|
+
get_line() # Justin Case
|
128
|
+
|
129
|
+
return result
|
130
|
+
end
|
131
|
+
end
|
132
|
+
end
|
@@ -0,0 +1,194 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
# encoding: UTF-8
|
3
|
+
# frozen_string_literal: true
|
4
|
+
|
5
|
+
#--
|
6
|
+
# This file is part of SSC.Bot.
|
7
|
+
# Copyright (c) 2020 Jonathan Bradley Whited (@esotericpig)
|
8
|
+
#
|
9
|
+
# SSC.Bot is free software: you can redistribute it and/or modify
|
10
|
+
# it under the terms of the GNU Lesser General Public License as published by
|
11
|
+
# the Free Software Foundation, either version 3 of the License, or
|
12
|
+
# (at your option) any later version.
|
13
|
+
#
|
14
|
+
# SSC.Bot is distributed in the hope that it will be useful,
|
15
|
+
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
16
|
+
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
17
|
+
# GNU Lesser General Public License for more details.
|
18
|
+
#
|
19
|
+
# You should have received a copy of the GNU Lesser General Public License
|
20
|
+
# along with SSC.Bot. If not, see <https://www.gnu.org/licenses/>.
|
21
|
+
#++
|
22
|
+
|
23
|
+
|
24
|
+
begin
|
25
|
+
require 'java'
|
26
|
+
rescue LoadError => e
|
27
|
+
raise e.exception('Must use JRuby for JRobotMessageSender')
|
28
|
+
end
|
29
|
+
|
30
|
+
require 'attr_bool'
|
31
|
+
|
32
|
+
require 'ssc.bot/util'
|
33
|
+
|
34
|
+
require 'ssc.bot/user/message_sender'
|
35
|
+
|
36
|
+
java_import 'java.awt.Robot'
|
37
|
+
java_import 'java.awt.Toolkit'
|
38
|
+
|
39
|
+
java_import 'java.awt.datatransfer.Clipboard'
|
40
|
+
java_import 'java.awt.datatransfer.ClipboardOwner'
|
41
|
+
java_import 'java.awt.datatransfer.StringSelection'
|
42
|
+
|
43
|
+
java_import 'java.awt.event.KeyEvent'
|
44
|
+
|
45
|
+
|
46
|
+
module SSCBot
|
47
|
+
module User
|
48
|
+
###
|
49
|
+
# @author Jonathan Bradley Whited (@esotericpig)
|
50
|
+
# @since 0.1.0
|
51
|
+
###
|
52
|
+
class JRobotMessageSender < MessageSender
|
53
|
+
attr_accessor :clipboard
|
54
|
+
attr_accessor :msg_key
|
55
|
+
attr_accessor :os
|
56
|
+
attr_accessor :robot
|
57
|
+
attr_accessor :shortcut_paste
|
58
|
+
attr_accessor :shortcut_paste_default
|
59
|
+
attr_accessor :shortcut_paste_macos
|
60
|
+
attr_accessor? :warn_user
|
61
|
+
attr_accessor :warn_user_key
|
62
|
+
attr_accessor :warn_user_sleep
|
63
|
+
|
64
|
+
def initialize(auto_delay: 110,msg_key: nil,os: Util::OS,warn_user: false,warn_user_key: KeyEvent::VK_BACK_SPACE,warn_user_sleep: 0.747,**kargs)
|
65
|
+
super(**kargs)
|
66
|
+
|
67
|
+
@clipboard = Toolkit.getDefaultToolkit().getSystemClipboard()
|
68
|
+
@msg_key = msg_key
|
69
|
+
@os = os
|
70
|
+
@robot = Robot.new()
|
71
|
+
@warn_user = warn_user
|
72
|
+
@warn_user_key = warn_user_key
|
73
|
+
@warn_user_sleep = warn_user_sleep
|
74
|
+
|
75
|
+
@robot.setAutoDelay(auto_delay)
|
76
|
+
|
77
|
+
@shortcut_paste = ->(ms) do
|
78
|
+
if ms.os == :macos
|
79
|
+
@shortcut_paste_macos.call(ms)
|
80
|
+
else
|
81
|
+
@shortcut_paste_default.call(ms)
|
82
|
+
end
|
83
|
+
end
|
84
|
+
@shortcut_paste_default = ->(ms) { ms.roll_keys(KeyEvent::VK_CONTROL,KeyEvent::VK_V) }
|
85
|
+
@shortcut_paste_macos = ->(ms) { ms.roll_keys(KeyEvent::VK_META,KeyEvent::VK_V) }
|
86
|
+
end
|
87
|
+
|
88
|
+
def backspace()
|
89
|
+
return type_key(KeyEvent::VK_BACK_SPACE)
|
90
|
+
end
|
91
|
+
|
92
|
+
def copy(str)
|
93
|
+
@clipboard.setContents(StringSelection.new(str),nil)
|
94
|
+
|
95
|
+
return self
|
96
|
+
end
|
97
|
+
|
98
|
+
def enter()
|
99
|
+
return type_key(KeyEvent::VK_ENTER)
|
100
|
+
end
|
101
|
+
|
102
|
+
def paste(str=nil)
|
103
|
+
copy(str) unless str.nil?()
|
104
|
+
|
105
|
+
@shortcut_paste.call(self)
|
106
|
+
|
107
|
+
return self
|
108
|
+
end
|
109
|
+
|
110
|
+
def press_key(*key_codes)
|
111
|
+
key_codes.each() do |key_code|
|
112
|
+
@robot.keyPress(key_code)
|
113
|
+
end
|
114
|
+
|
115
|
+
return self
|
116
|
+
end
|
117
|
+
|
118
|
+
def put(message)
|
119
|
+
# If do type_msg_key() and then warn_user(), then a backspace from
|
120
|
+
# warn_user() will cancel out the msg key.
|
121
|
+
# Could do type_msg_key().warn_user().type_msg_key(), but then if the
|
122
|
+
# client is in windowed mode and msg key is a tab, then a backspace
|
123
|
+
# from warn_user() will do nothing.
|
124
|
+
return warn_user().
|
125
|
+
type_msg_key().
|
126
|
+
paste(message)
|
127
|
+
end
|
128
|
+
|
129
|
+
def release_key(*key_codes)
|
130
|
+
key_codes.each() do |key_code|
|
131
|
+
@robot.keyRelease(key_code)
|
132
|
+
end
|
133
|
+
|
134
|
+
return self
|
135
|
+
end
|
136
|
+
|
137
|
+
def roll_keys(*key_codes)
|
138
|
+
key_codes.each() do |key_code|
|
139
|
+
@robot.keyPress(key_code)
|
140
|
+
end
|
141
|
+
|
142
|
+
(key_codes.length - 1).downto(0) do |i|
|
143
|
+
@robot.keyRelease(key_codes[i])
|
144
|
+
end
|
145
|
+
|
146
|
+
return self
|
147
|
+
end
|
148
|
+
|
149
|
+
def send_message()
|
150
|
+
enter()
|
151
|
+
end
|
152
|
+
|
153
|
+
def type(message)
|
154
|
+
# TODO: implement type(message)
|
155
|
+
super(message)
|
156
|
+
end
|
157
|
+
|
158
|
+
def type_key(*key_codes)
|
159
|
+
key_codes.each() do |key_code|
|
160
|
+
@robot.keyPress(key_code)
|
161
|
+
@robot.keyRelease(key_code)
|
162
|
+
end
|
163
|
+
|
164
|
+
return self
|
165
|
+
end
|
166
|
+
|
167
|
+
def type_msg_key()
|
168
|
+
if @msg_key
|
169
|
+
if @msg_key.respond_to?(:call)
|
170
|
+
@msg_key.call(self)
|
171
|
+
else
|
172
|
+
type_key(@msg_key)
|
173
|
+
end
|
174
|
+
end
|
175
|
+
|
176
|
+
return self
|
177
|
+
end
|
178
|
+
|
179
|
+
def warn_user()
|
180
|
+
if @warn_user
|
181
|
+
if @warn_user_key.respond_to?(:call)
|
182
|
+
@warn_user_key.call(self)
|
183
|
+
else
|
184
|
+
press_key(@warn_user_key)
|
185
|
+
sleep(@warn_user_sleep)
|
186
|
+
release_key(@warn_user_key)
|
187
|
+
end
|
188
|
+
end
|
189
|
+
|
190
|
+
return self
|
191
|
+
end
|
192
|
+
end
|
193
|
+
end
|
194
|
+
end
|