ssc.nob 0.1.0-java → 0.1.1-java

Sign up to get free protection for your applications and to get access to all the features.
@@ -1,87 +1,107 @@
1
- #!/usr/bin/env ruby
2
1
  # encoding: UTF-8
3
2
  # frozen_string_literal: true
4
3
 
5
4
  #--
6
5
  # This file is part of SSC.Nob.
7
- # Copyright (c) 2020 Jonathan Bradley Whited (@esotericpig)
8
- #
9
- # SSC.Nob is free software: you can redistribute it and/or modify
10
- # it under the terms of the GNU 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.Nob 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 General Public License for more details.
18
- #
19
- # You should have received a copy of the GNU General Public License
20
- # along with SSC.Nob. If not, see <https://www.gnu.org/licenses/>.
6
+ # Copyright (c) 2020-2021 Jonathan Bradley Whited
7
+ #
8
+ # SPDX-License-Identifier: GPL-3.0-or-later
21
9
  #++
22
10
 
23
11
 
12
+ require 'java'
24
13
  require 'psych'
25
14
 
26
15
  require 'ssc.nob/error'
27
16
  require 'ssc.nob/userface'
28
17
  require 'ssc.nob/util'
29
18
 
19
+ java_import 'java.awt.event.KeyEvent'
20
+
30
21
 
31
22
  module SSCNob
32
23
  ###
33
- # @author Jonathan Bradley Whited (@esotericpig)
24
+ # @author Jonathan Bradley Whited
34
25
  # @since 0.1.0
35
26
  ###
36
27
  class Config
37
28
  include Uface
38
-
29
+
39
30
  attr_reader :file
31
+ attr_accessor :msg_key
40
32
  attr_accessor :ssc_dir
41
33
  attr_accessor :username
42
-
34
+
43
35
  def initialize(file='ssc.nob.yml')
44
36
  super()
45
-
37
+
46
38
  @file = File.expand_path(file)
39
+ @msg_key = nil
47
40
  @ssc_dir = nil
48
41
  @username = nil
49
42
  end
50
-
51
- def build_ssc_log_dir()
43
+
44
+ def build_msg_key
45
+ # Can be a single space ' '.
46
+ return @msg_key if @msg_key.nil? || @msg_key.length == 1
47
+
48
+ fuzzy_key = Util.strip(@msg_key).downcase
49
+
50
+ if fuzzy_key.empty?
51
+ @msg_key = nil
52
+
53
+ return @msg_key
54
+ end
55
+
56
+ KeyEvent.constants.each do |c|
57
+ name = c.to_s.downcase
58
+
59
+ if name.start_with?('vk_') && name.include?(fuzzy_key)
60
+ return KeyEvent.const_get(c)
61
+ end
62
+ end
63
+
64
+ raise UserError,"that's an invalid msg key{#{@msg_key}}, user."
65
+ end
66
+
67
+ def build_ssc_log_dir
52
68
  return File.join(@ssc_dir,'logs')
53
69
  end
54
-
55
- def check_ssc_dir()
70
+
71
+ def check_msg_key
72
+ build_msg_key
73
+ end
74
+
75
+ def check_ssc_dir
56
76
  @ssc_dir = Util.strip(@ssc_dir)
57
-
58
- if @ssc_dir.nil?() || @ssc_dir.empty?()
77
+
78
+ if @ssc_dir.nil? || @ssc_dir.empty?
59
79
  raise UserError,"that's a blank folder name, user."
60
80
  end
61
-
81
+
62
82
  @ssc_dir = File.expand_path(@ssc_dir)
63
-
83
+
64
84
  if !Dir.exist?(@ssc_dir)
65
85
  raise UserError,"that folder{#{@ssc_dir}} doesn't exist, user."
66
86
  end
67
87
  if !File.directory?(@ssc_dir)
68
88
  raise UserError,"that's a file{#{@ssc_dir}}, not a folder, user."
69
89
  end
70
-
71
- ssc_log_dir = build_ssc_log_dir()
72
-
90
+
91
+ ssc_log_dir = build_ssc_log_dir
92
+
73
93
  if !Dir.exist?(ssc_log_dir) || !File.directory?(ssc_log_dir)
74
94
  raise UserError,"why's there no 'logs' folder{#{ssc_log_dir}}, user?"
75
95
  end
76
96
  end
77
-
78
- def check_username()
97
+
98
+ def check_username
79
99
  raise UserError,"that's a blank username, user." if Util.blank?(@username)
80
100
  end
81
-
101
+
82
102
  def load_file!(mode: 'rt:BOM|UTF-8',**kargs)
83
103
  data = File.read(@file,mode: mode,**kargs)
84
-
104
+
85
105
  yaml = Psych.safe_load(data,
86
106
  aliases: false,
87
107
  filename: @file,
@@ -89,63 +109,78 @@ module SSCNob
89
109
  symbolize_names: true,
90
110
  **kargs,
91
111
  )
92
-
112
+
113
+ @msg_key = yaml[:msg_key]
93
114
  @ssc_dir = Util.strip(yaml[:ssc_dir])
94
- @ssc_dir = File.expand_path(@ssc_dir) if !@ssc_dir.nil?() && !@ssc_dir.empty?()
115
+ @ssc_dir = File.expand_path(@ssc_dir) if !@ssc_dir.nil? && !@ssc_dir.empty?
95
116
  @username = yaml[:username]
96
117
  end
97
-
118
+
98
119
  def save_file(mode: 'wt',**kargs)
99
120
  File.open(@file,mode: mode,**kargs) do |fout|
100
- fout.write(to_s())
121
+ fout.write(to_s)
101
122
  end
102
123
  end
103
-
104
- def user_init!()
124
+
125
+ def user_init!
105
126
  if File.exist?(@file)
106
- load_file!()
127
+ load_file!
107
128
  end
108
-
109
- if valid?()
110
- uface.type("Welcome back, ")
129
+
130
+ if valid?
131
+ uface.type('Welcome back, ')
111
132
  puts "#{uface.user(@username)}."
112
133
  uface.type("Here's a hot cup of coffee: ")
113
134
  puts uface.coffee
114
135
  else
115
136
  uface.types('Welcome, new user.')
116
137
  puts
117
-
138
+
118
139
  @username = uface.ask("What's your #{uface.user('username')}? ")
119
- check_username()
120
-
140
+ check_username
141
+
121
142
  @ssc_dir = uface.ask("Where's your #{uface.ssc} folder? ")
122
- check_ssc_dir()
123
-
143
+ check_ssc_dir
144
+
145
+ puts(<<~MSGKEY)
146
+ What's your #{uface.color('Message Key').aqua.bold}?
147
+ - Can input a key code, like 'VK_TAB' or 'TAB'
148
+ - Can input a letter, like 'm'
149
+ - Can input nothing
150
+ MSGKEY
151
+ @msg_key = uface.ask('> ')
152
+ check_msg_key
153
+
124
154
  puts
125
155
  puts uface.gt(@file)
126
156
  if uface.agree('Save this configuration (y/n)? ')
127
- save_file()
157
+ save_file
128
158
  end
129
159
  end
130
160
  end
131
-
132
- def valid?()
161
+
162
+ def valid?
133
163
  begin
134
- check_ssc_dir()
135
- check_username()
136
- rescue UserError
164
+ check_msg_key
165
+ check_ssc_dir
166
+ check_username
167
+ rescue UserError => e
168
+ puts e.to_s.capitalize
169
+ puts
170
+
137
171
  return false
138
172
  end
139
-
173
+
140
174
  return true
141
175
  end
142
-
143
- def to_s()
176
+
177
+ def to_s
144
178
  yaml = {
179
+ 'msg_key' => @msg_key,
145
180
  'username' => @username,
146
181
  'ssc_dir' => @ssc_dir,
147
182
  }
148
-
183
+
149
184
  return Psych.dump(yaml,header: true)
150
185
  end
151
186
  end
data/lib/ssc.nob/error.rb CHANGED
@@ -1,32 +1,20 @@
1
- #!/usr/bin/env ruby
2
1
  # encoding: UTF-8
3
2
  # frozen_string_literal: true
4
3
 
5
4
  #--
6
5
  # This file is part of SSC.Nob.
7
- # Copyright (c) 2020 Jonathan Bradley Whited (@esotericpig)
8
- #
9
- # SSC.Nob is free software: you can redistribute it and/or modify
10
- # it under the terms of the GNU 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.Nob 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 General Public License for more details.
18
- #
19
- # You should have received a copy of the GNU General Public License
20
- # along with SSC.Nob. If not, see <https://www.gnu.org/licenses/>.
6
+ # Copyright (c) 2020-2021 Jonathan Bradley Whited
7
+ #
8
+ # SPDX-License-Identifier: GPL-3.0-or-later
21
9
  #++
22
10
 
23
11
 
24
12
  module SSCNob
25
13
  ###
26
- # @author Jonathan Bradley Whited (@esotericpig)
14
+ # @author Jonathan Bradley Whited
27
15
  # @since 0.1.0
28
16
  ###
29
17
  class Error < ::StandardError; end
30
-
18
+
31
19
  class UserError < Error; end
32
20
  end
@@ -1,23 +1,11 @@
1
- #!/usr/bin/env ruby
2
1
  # encoding: UTF-8
3
2
  # frozen_string_literal: true
4
3
 
5
4
  #--
6
5
  # This file is part of SSC.Nob.
7
- # Copyright (c) 2020 Jonathan Bradley Whited (@esotericpig)
8
- #
9
- # SSC.Nob is free software: you can redistribute it and/or modify
10
- # it under the terms of the GNU 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.Nob 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 General Public License for more details.
18
- #
19
- # You should have received a copy of the GNU General Public License
20
- # along with SSC.Nob. If not, see <https://www.gnu.org/licenses/>.
6
+ # Copyright (c) 2020-2021 Jonathan Bradley Whited
7
+ #
8
+ # SPDX-License-Identifier: GPL-3.0-or-later
21
9
  #++
22
10
 
23
11
 
@@ -36,129 +24,118 @@ java_import 'java.awt.event.KeyEvent'
36
24
 
37
25
  module SSCNob
38
26
  ###
39
- # @author Jonathan Bradley Whited (@esotericpig)
27
+ # @author Jonathan Bradley Whited
40
28
  # @since 0.1.0
41
29
  ###
42
30
  class SSCBot
43
31
  MESSAGE_FLOOD_COUNT = 8
44
- MESSAGE_FLOOD_TIME = 5
45
-
32
+ MESSAGE_FLOOD_TIME = 6
33
+
46
34
  attr_accessor :auto_delay_time
47
35
  attr_reader :char_codes
48
36
  attr_reader :clipboard
49
37
  attr_reader :last_message_time
50
38
  attr_reader :message_count
51
- attr_accessor :message_key
52
39
  attr_reader :robot
53
-
54
- # TODO: save message_key in config
55
- def initialize(auto_delay_time: 0.2,message_key: KeyEvent::VK_TAB)
40
+
41
+ def initialize(auto_delay_time: 0.1)
56
42
  super()
57
-
43
+
58
44
  @auto_delay_time = auto_delay_time
59
45
  @char_codes = {}
60
- @clipboard = Toolkit.getDefaultToolkit().getSystemClipboard()
61
- @last_message_time = Time.now()
46
+ @clipboard = Toolkit.getDefaultToolkit.getSystemClipboard
47
+ @last_message_time = Time.now
62
48
  @message_count = 0
63
- @message_key = message_key
64
- @robot = Robot.new()
65
-
49
+ @robot = Robot.new
50
+
66
51
  @robot.setAutoDelay(0) # Don't use Java's, too slow
67
-
68
- build_char_codes()
52
+
53
+ build_char_codes
69
54
  end
70
-
71
- def auto_delay()
55
+
56
+ def auto_delay
72
57
  sleep(@auto_delay_time)
73
-
58
+
74
59
  return self
75
60
  end
76
-
61
+
77
62
  def chat_message(channel,msg)
78
63
  return pub_message(";#{channel};#{msg}")
79
64
  end
80
-
65
+
81
66
  def copy(str)
82
- @clipboard.setContents(StringSelection.new(str),nil);
83
-
67
+ @clipboard.setContents(StringSelection.new(str),nil)
68
+
84
69
  return self
85
70
  end
86
-
87
- def enter()
71
+
72
+ def enter
88
73
  return type_key(KeyEvent::VK_ENTER)
89
74
  end
90
-
75
+
91
76
  def paste(str=nil)
92
- copy(str) unless str.nil?()
93
-
77
+ copy(str) unless str.nil?
78
+
94
79
  # FIXME: change to VK_META for macOS
95
80
  roll_keys(KeyEvent::VK_CONTROL,KeyEvent::VK_V)
96
-
81
+
97
82
  return self
98
83
  end
99
-
100
- def prevent_flooding()
84
+
85
+ def prevent_flooding
101
86
  @message_count += 1
102
-
87
+
103
88
  if @message_count >= MESSAGE_FLOOD_COUNT
104
- time_diff = Time.now() - @last_message_time
105
-
106
- if time_diff <= MESSAGE_FLOOD_TIME
107
- sleep(MESSAGE_FLOOD_TIME - time_diff)
108
- end
109
-
89
+ time_diff = Time.now - @last_message_time
90
+ time_diff = (MESSAGE_FLOOD_TIME - time_diff).round
91
+ time_diff = 1 if time_diff < 1 # Always sleep for at least 1 sec
92
+
93
+ sleep(time_diff)
94
+
110
95
  @message_count = 0
111
96
  end
112
-
113
- @last_message_time = Time.now()
114
-
115
- return self
116
- end
117
-
118
- def pub_message(msg)
119
- type_key(@message_key).paste(msg).enter()
120
-
121
- sleep(1.2)
122
-
97
+
98
+ @last_message_time = Time.now
99
+
123
100
  return self
124
101
  end
125
-
102
+
126
103
  def roll_keys(*key_codes)
127
- key_codes.each() do |key_code|
104
+ key_codes.each do |key_code|
128
105
  @robot.keyPress(key_code)
129
- auto_delay()
106
+ auto_delay
130
107
  end
131
-
108
+
132
109
  (key_codes.length - 1).downto(0) do |i|
133
110
  @robot.keyRelease(key_codes[i])
134
- auto_delay()
111
+ auto_delay
135
112
  end
136
-
113
+
137
114
  return self
138
115
  end
139
-
116
+
140
117
  def type(str)
141
- str.each_char() do |c|
118
+ str.each_char do |c|
142
119
  key_codes = @char_codes[c]
143
-
144
- next if key_codes.nil?()
145
-
120
+
121
+ next if key_codes.nil?
122
+
146
123
  roll_keys(*key_codes)
147
124
  end
148
-
125
+
149
126
  return self
150
127
  end
151
-
128
+
152
129
  def type_key(key_code)
153
130
  @robot.keyPress(key_code)
154
- auto_delay()
131
+ auto_delay
155
132
  @robot.keyRelease(key_code)
156
- auto_delay()
157
-
133
+ auto_delay
134
+
158
135
  return self
159
136
  end
160
-
161
- def build_char_codes()
137
+
138
+ def build_char_codes
162
139
  @char_codes.store("\b",[KeyEvent::VK_BACK_SPACE])
163
140
  @char_codes.store("\f",[KeyEvent::VK_PAGE_DOWN])
164
141
  @char_codes.store("\n",[KeyEvent::VK_ENTER])
@@ -167,15 +144,15 @@ module SSCNob
167
144
  @char_codes.store(' ',[KeyEvent::VK_SPACE])
168
145
  @char_codes.store('!',[KeyEvent::VK_SHIFT,KeyEvent::VK_EXCLAMATION_MARK])
169
146
  @char_codes.store('"',[KeyEvent::VK_SHIFT,KeyEvent::VK_QUOTEDBL])
170
- @char_codes.store('#',[KeyEvent::VK_SHIFT,KeyEvent::VK_3])
171
- @char_codes.store('$',[KeyEvent::VK_SHIFT,KeyEvent::VK_4])
147
+ @char_codes.store('#',[KeyEvent::VK_SHIFT,KeyEvent::VK_NUMBER_SIGN])
148
+ @char_codes.store('$',[KeyEvent::VK_SHIFT,KeyEvent::VK_DOLLAR])
172
149
  @char_codes.store('%',[KeyEvent::VK_SHIFT,KeyEvent::VK_5])
173
- @char_codes.store('&',[KeyEvent::VK_SHIFT,KeyEvent::VK_7])
150
+ @char_codes.store('&',[KeyEvent::VK_SHIFT,KeyEvent::VK_AMPERSAND])
174
151
  @char_codes.store('\'',[KeyEvent::VK_QUOTE])
175
- @char_codes.store('(',[KeyEvent::VK_SHIFT,KeyEvent::VK_9])
176
- @char_codes.store(')',[KeyEvent::VK_SHIFT,KeyEvent::VK_0])
177
- @char_codes.store('*',[KeyEvent::VK_SHIFT,KeyEvent::VK_8])
178
- @char_codes.store('+',[KeyEvent::VK_SHIFT,KeyEvent::VK_EQUALS])
152
+ @char_codes.store('(',[KeyEvent::VK_SHIFT,KeyEvent::VK_LEFT_PARENTHESIS])
153
+ @char_codes.store(')',[KeyEvent::VK_SHIFT,KeyEvent::VK_RIGHT_PARENTHESIS])
154
+ @char_codes.store('*',[KeyEvent::VK_SHIFT,KeyEvent::VK_ASTERISK])
155
+ @char_codes.store('+',[KeyEvent::VK_SHIFT,KeyEvent::VK_PLUS])
179
156
  @char_codes.store(',',[KeyEvent::VK_COMMA])
180
157
  @char_codes.store('-',[KeyEvent::VK_MINUS])
181
158
  @char_codes.store('.',[KeyEvent::VK_PERIOD])
@@ -259,6 +236,8 @@ module SSCNob
259
236
  @char_codes.store('|',[KeyEvent::VK_SHIFT,KeyEvent::VK_BACK_SLASH])
260
237
  @char_codes.store('}',[KeyEvent::VK_SHIFT,KeyEvent::VK_BRACERIGHT])
261
238
  @char_codes.store('~',[KeyEvent::VK_SHIFT,KeyEvent::VK_BACK_QUOTE])
239
+ @char_codes.store('¡',[KeyEvent::VK_SHIFT,KeyEvent::VK_INVERTED_EXCLAMATION_MARK])
240
+ @char_codes.store('€',[KeyEvent::VK_SHIFT,KeyEvent::VK_EURO_SIGN])
262
241
  end
263
242
  end
264
243
  end