procon_bypass_man 0.1.22 → 0.2.1

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.
Files changed (67) hide show
  1. checksums.yaml +4 -4
  2. data/.circleci/config.yml +1 -1
  3. data/.github/workflows/gitleacks.yml +12 -0
  4. data/.github/workflows/release.yml +1 -0
  5. data/.github/workflows/ruby.yml +1 -1
  6. data/CHANGELOG.md +22 -0
  7. data/Gemfile.lock +5 -5
  8. data/docs/getting_started.md +9 -1
  9. data/docs/setup_raspi.md +0 -1
  10. data/lib/procon_bypass_man/buttons_setting_configuration/loader.rb +1 -1
  11. data/lib/procon_bypass_man/{commands → bypass}/bypass_command.rb +36 -24
  12. data/lib/procon_bypass_man/bypass/usb_hid_logger.rb +3 -0
  13. data/lib/procon_bypass_man/bypass.rb +40 -23
  14. data/lib/procon_bypass_man/commands/print_boot_message_command.rb +2 -3
  15. data/lib/procon_bypass_man/commands/send_error_command.rb +2 -2
  16. data/lib/procon_bypass_man/commands.rb +0 -3
  17. data/lib/procon_bypass_man/configuration.rb +22 -3
  18. data/lib/procon_bypass_man/device_connection/command.rb +28 -0
  19. data/lib/procon_bypass_man/device_connection/executor.rb +190 -0
  20. data/lib/procon_bypass_man/device_connection/output_report_generator.rb +42 -0
  21. data/lib/procon_bypass_man/device_connection/output_report_markerable.rb +28 -0
  22. data/lib/procon_bypass_man/device_connection/output_report_sub_command_table.rb +133 -0
  23. data/lib/procon_bypass_man/device_connection/output_report_watcher.rb +41 -0
  24. data/lib/procon_bypass_man/device_connection/pre_bypass.rb +67 -0
  25. data/lib/procon_bypass_man/device_connection/procon_setting_overrider.rb +78 -0
  26. data/lib/procon_bypass_man/device_connection/spoofing_output_report_watcher.rb +39 -0
  27. data/lib/procon_bypass_man/device_connection.rb +16 -0
  28. data/lib/procon_bypass_man/device_model.rb +17 -0
  29. data/lib/procon_bypass_man/io_monitor.rb +20 -1
  30. data/lib/procon_bypass_man/procon/macro_builder.rb +5 -3
  31. data/lib/procon_bypass_man/procon/suppress_rumble.rb +13 -0
  32. data/lib/procon_bypass_man/{domains → procon/value_objects}/analog_stick_position.rb +0 -0
  33. data/lib/procon_bypass_man/{domains → procon/value_objects}/binary/base.rb +0 -0
  34. data/lib/procon_bypass_man/{domains → procon/value_objects}/binary/has_immutable_binary.rb +0 -0
  35. data/lib/procon_bypass_man/{domains → procon/value_objects}/binary/has_mutable_binary.rb +0 -0
  36. data/lib/procon_bypass_man/{domains → procon/value_objects}/binary/inbound_procon_binary.rb +5 -0
  37. data/lib/procon_bypass_man/{domains → procon/value_objects}/binary/processing_procon_binary.rb +0 -0
  38. data/lib/procon_bypass_man/procon/value_objects/binary.rb +11 -0
  39. data/lib/procon_bypass_man/{domains → procon/value_objects}/bypass_mode.rb +0 -0
  40. data/lib/procon_bypass_man/procon/value_objects/rumble_binary.rb +18 -0
  41. data/lib/procon_bypass_man/procon.rb +8 -0
  42. data/lib/procon_bypass_man/procon_display/http_request.rb +31 -0
  43. data/lib/procon_bypass_man/procon_display/http_response.rb +23 -0
  44. data/lib/procon_bypass_man/procon_display/server.rb +33 -0
  45. data/lib/procon_bypass_man/procon_display/server_app.rb +17 -0
  46. data/lib/procon_bypass_man/procon_display/status.rb +20 -0
  47. data/lib/procon_bypass_man/procon_display.rb +10 -0
  48. data/lib/procon_bypass_man/{commands → remote_pbm_action/commands}/run_remote_pbm_action_dispatch_command.rb +0 -0
  49. data/lib/procon_bypass_man/remote_pbm_action/restore_pbm_setting.rb +7 -1
  50. data/lib/procon_bypass_man/remote_pbm_action.rb +1 -0
  51. data/lib/procon_bypass_man/runner.rb +10 -13
  52. data/lib/procon_bypass_man/support/cycle_sleep.rb +22 -0
  53. data/lib/procon_bypass_man/support/device_mouse_finder.rb +60 -0
  54. data/lib/procon_bypass_man/{device_procon_finder.rb → support/device_procon_finder.rb} +0 -0
  55. data/lib/procon_bypass_man/support/never_exit_accidentally.rb +3 -3
  56. data/lib/procon_bypass_man/support/safe_timeout.rb +7 -1
  57. data/lib/procon_bypass_man/{usb_device_controller.rb → support/usb_device_controller.rb} +9 -4
  58. data/lib/procon_bypass_man/support/yaml_loader.rb +12 -0
  59. data/lib/procon_bypass_man/version.rb +1 -1
  60. data/lib/procon_bypass_man/websocket/client.rb +1 -4
  61. data/lib/procon_bypass_man.rb +66 -51
  62. data/project_template/app.rb +23 -7
  63. data/sig/main.rbs +4 -16
  64. metadata +37 -16
  65. data/lib/procon_bypass_man/commands/connect_device_command.rb +0 -18
  66. data/lib/procon_bypass_man/device_connector.rb +0 -293
  67. data/lib/procon_bypass_man/domains.rb +0 -13
@@ -1,293 +0,0 @@
1
- class ProconBypassMan::DeviceConnector
2
- class BytesMismatchError < StandardError; end
3
- class NotFoundProconError < StandardError; end
4
-
5
- class Value
6
- attr_accessor :read_from, :values
7
- def initialize(values: , read_from: )
8
- @values = values
9
- @read_from = read_from
10
- end
11
- end
12
-
13
- def self.connect
14
- s = new(throw_error_if_timeout: true, enable_at_exit: false)
15
- s.add([
16
- ["0000"],
17
- ["0000"],
18
- ["8005"],
19
- ["0000"],
20
- ], read_from: :switch)
21
- # 1. Sends current connection status, and if the Joy-Con are connected,
22
- s.add([["8001"]], read_from: :switch)
23
- s.add([/^8101/], read_from: :procon) # <<< 81010003176d96e7a5480000000, macaddressとコントローラー番号を返す
24
- # 2. Sends handshaking packets over UART to the Joy-Con or Pro Controller Broadcom chip. This command can only be called once per session.
25
- s.add([["8002"]], read_from: :switch)
26
- s.add([/^8102/], read_from: :procon)
27
- # 3
28
- s.add([/^0100/], read_from: :switch)
29
- s.add([/^21/], read_from: :procon)
30
- # 4. Forces the Joy-Con or Pro Controller to only talk over USB HID without any timeouts. This is required for the Pro Controller to not time out and revert to Bluetooth.
31
- s.add([["8004"]], read_from: :switch)
32
- s.drain_all
33
- return [s.switch, s.procon]
34
- end
35
-
36
- def initialize(throw_error_if_timeout: false, throw_error_if_mismatch: false , enable_at_exit: true)
37
- @stack = []
38
- @initialized_devices = false
39
- @throw_error_if_timeout = throw_error_if_timeout
40
- @throw_error_if_mismatch = throw_error_if_mismatch
41
- @enable_at_exit = enable_at_exit
42
- end
43
-
44
- def add(values, read_from: )
45
- @stack << Value.new(values: values, read_from: read_from)
46
- end
47
-
48
- def drain_all
49
- debug_log_buffer = []
50
- unless @initialized_devices
51
- init_devices
52
- end
53
-
54
- while(item = @stack.shift)
55
- item.values.each do |value|
56
- data = nil
57
- timer = ProconBypassMan::SafeTimeout.new
58
- begin
59
- timer.throw_if_timeout!
60
- data = from_device(item).read_nonblock(64)
61
- debug_log_buffer << "read_from(#{item.read_from}): #{data.unpack("H*")}"
62
- rescue IO::EAGAINWaitReadable
63
- # debug_log_buffer << "read_from(#{item.read_from}): IO::EAGAINWaitReadable"
64
- retry
65
- end
66
-
67
- result =
68
- case value
69
- when String, Array
70
- value == data.unpack("H*")
71
- when Regexp
72
- value =~ data.unpack("H*").first
73
- else
74
- raise "#{value}は知りません"
75
- end
76
- if result
77
- ProconBypassMan.logger.info "OK(expected: #{value}, got: #{data.unpack("H*")})"
78
- debug_log_buffer << "OK(expected: #{value}, got: #{data.unpack("H*")})"
79
- else
80
- ProconBypassMan.logger.info "NG(expected: #{value}, got: #{data.unpack("H*")})"
81
- debug_log_buffer << "NG(expected: #{value}, got: #{data.unpack("H*")})"
82
- raise BytesMismatchError if @throw_error_if_mismatch
83
- end
84
- to_device(item).write_nonblock(data)
85
- end
86
- end
87
- rescue ProconBypassMan::SafeTimeout::Timeout
88
- ProconBypassMan.logger.error "timeoutになりました"
89
- copressed_buffer_text = ProconBypassMan::CompressArray.new(debug_log_buffer).compress.join("\n")
90
- ProconBypassMan::SendErrorCommand.execute(error: copressed_buffer_text)
91
- raise if @throw_error_if_timeout
92
- end
93
-
94
- # switchに任意の命令を入力して、switchから読み取る
95
- def write_switch(data, only_write: false)
96
- if data.encoding.name == "UTF-8"
97
- data = [data].pack("H*")
98
- end
99
- unless @initialized_devices
100
- init_devices
101
- end
102
-
103
- timer = ProconBypassMan::SafeTimeout.new
104
- data = nil
105
- begin
106
- timer.throw_if_timeout!
107
- switch.write_nonblock(data)
108
- rescue IO::EAGAINWaitReadable
109
- retry
110
- rescue ProconBypassMan::SafeTimeout::Timeout
111
- ProconBypassMan.logger.error "writeでtimeoutになりました"
112
- raise
113
- end
114
- return(data.unpack("H*")) if only_write
115
-
116
- timer = ProconBypassMan::SafeTimeout.new
117
- begin
118
- timer.throw_if_timeout!
119
- data = switch.read_nonblock(64)
120
- ProconBypassMan.logger.debug { " >>> #{data.unpack("H*")})" }
121
- rescue IO::EAGAINWaitReadable
122
- retry
123
- rescue ProconBypassMan::SafeTimeout::Timeout
124
- ProconBypassMan.logger.error "readでtimeoutになりました"
125
- raise
126
- end
127
- rescue ProconBypassMan::SafeTimeout::Timeout
128
- raise if @throw_error_if_timeout
129
- end
130
-
131
- def write_procon(data, only_write: false)
132
- if data.encoding.name == "UTF-8"
133
- data = [data].pack("H*")
134
- end
135
- unless @initialized_devices
136
- init_devices
137
- end
138
-
139
- timer = ProconBypassMan::SafeTimeout.new
140
- begin
141
- timer.throw_if_timeout!
142
- procon.write_nonblock(data)
143
- rescue IO::EAGAINWaitReadable
144
- retry
145
- rescue ProconBypassMan::SafeTimeout::Timeout
146
- ProconBypassMan.logger.error "writeでtimeoutになりました"
147
- raise
148
- end
149
- return(data.unpack("H*")) if only_write
150
-
151
- timer = ProconBypassMan::SafeTimeout.new
152
- begin
153
- timer.throw_if_timeout!
154
- data = procon.read_nonblock(64)
155
- ProconBypassMan.logger.error " <<< #{data.unpack("H*")})"
156
- rescue IO::EAGAINWaitReadable
157
- retry
158
- rescue ProconBypassMan::SafeTimeout::Timeout
159
- ProconBypassMan.logger.error "readでtimeoutになりました"
160
- raise
161
- end
162
- rescue ProconBypassMan::SafeTimeout::Timeout
163
- raise if @throw_error_if_timeout
164
- end
165
-
166
- def read_procon(only_read: false)
167
- unless @initialized_devices
168
- init_devices
169
- end
170
-
171
- data = nil
172
- timer = ProconBypassMan::SafeTimeout.new
173
- begin
174
- timer.throw_if_timeout!
175
- data = procon.read_nonblock(64)
176
- ProconBypassMan.logger.debug { " <<< #{data.unpack("H*")})" }
177
- rescue IO::EAGAINWaitReadable
178
- retry
179
- rescue ProconBypassMan::SafeTimeout::Timeout
180
- ProconBypassMan.logger.error "readでtimeoutになりました"
181
- raise
182
- end
183
- return(data.unpack("H*")) if only_read
184
-
185
- timer = ProconBypassMan::SafeTimeout.new
186
- begin
187
- timer.throw_if_timeout!
188
- switch.write_nonblock(data)
189
- rescue IO::EAGAINWaitReadable
190
- retry
191
- rescue ProconBypassMan::SafeTimeout::Timeout
192
- ProconBypassMan.logger.error "writeでtimeoutになりました"
193
- raise
194
- end
195
- rescue ProconBypassMan::SafeTimeout::Timeout
196
- raise if @throw_error_if_timeout
197
- end
198
-
199
- def read_switch(only_read: false)
200
- unless @initialized_devices
201
- init_devices
202
- end
203
-
204
- data = nil
205
- timer = ProconBypassMan::SafeTimeout.new
206
- begin
207
- timer.throw_if_timeout!
208
- data = switch.read_nonblock(64)
209
- ProconBypassMan.logger.debug { " >>> #{data.unpack("H*")})" }
210
- rescue IO::EAGAINWaitReadable
211
- retry
212
- rescue ProconBypassMan::SafeTimeout::Timeout
213
- ProconBypassMan.logger.error "readでtimeoutになりました"
214
- raise
215
- end
216
- return(data.unpack("H*")) if only_read
217
-
218
- timer = ProconBypassMan::SafeTimeout.new
219
- begin
220
- timer.throw_if_timeout!
221
- procon.write_nonblock(data)
222
- rescue IO::EAGAINWaitReadable
223
- retry
224
- rescue ProconBypassMan::SafeTimeout::Timeout
225
- ProconBypassMan.logger.error "writeでtimeoutになりました"
226
- raise
227
- end
228
- rescue ProconBypassMan::SafeTimeout::Timeout
229
- raise if @throw_error_if_timeout
230
- end
231
-
232
- def from_device(item)
233
- case item.read_from
234
- when :switch
235
- switch
236
- when :procon
237
- procon
238
- else
239
- raise
240
- end
241
- end
242
-
243
- # fromの対になる
244
- def to_device(item)
245
- case item.read_from
246
- when :switch
247
- procon
248
- when :procon
249
- switch
250
- else
251
- raise
252
- end
253
- end
254
-
255
- def switch
256
- @gadget
257
- end
258
-
259
- def procon
260
- @procon
261
- end
262
-
263
- def init_devices
264
- if @initialized_devices
265
- return
266
- end
267
- ProconBypassMan::UsbDeviceController.init
268
-
269
- if path = ProconBypassMan::DeviceProconFinder.find
270
- @procon = File.open(path, "w+b")
271
- ProconBypassMan.logger.info "proconのデバイスファイルは#{path}を使います"
272
- else
273
- raise(ProconBypassMan::DeviceConnector::NotFoundProconError)
274
- end
275
- @gadget = File.open('/dev/hidg0', "w+b")
276
-
277
- ProconBypassMan::UsbDeviceController.reset
278
-
279
- @initialized_devices = true
280
-
281
- if @enable_at_exit
282
- at_exit do
283
- @procon&.close
284
- @gadget&.close
285
- end
286
- end
287
- rescue Errno::ENXIO => e
288
- # /dev/hidg0 をopenできないときがある
289
- ProconBypassMan::SendErrorCommand.execute(error: "Errno::ENXIO (No such device or address @ rb_sysopen - /dev/hidg0)が起きました。resetします.\n #{e.full_message}")
290
- ProconBypassMan::UsbDeviceController.reset
291
- retry
292
- end
293
- end
@@ -1,13 +0,0 @@
1
- module ProconBypassMan
2
- module Domains
3
- module Binary; end
4
- end
5
- end
6
-
7
- require_relative "domains/bypass_mode"
8
- require_relative "domains/analog_stick_position"
9
- require_relative "domains/binary/base"
10
- require_relative "domains/binary/has_mutable_binary"
11
- require_relative "domains/binary/has_immutable_binary"
12
- require_relative "domains/binary/inbound_procon_binary"
13
- require_relative "domains/binary/processing_procon_binary"