procon_bypass_man 0.1.20.2 → 0.1.23

Sign up to get free protection for your applications and to get access to all the features.
Files changed (86) hide show
  1. checksums.yaml +4 -4
  2. data/.circleci/config.yml +9 -5
  3. data/.github/workflows/ruby.yml +1 -1
  4. data/.gitignore +1 -0
  5. data/.rspec +1 -0
  6. data/CHANGELOG.md +30 -1
  7. data/Gemfile.lock +4 -4
  8. data/README.md +4 -1
  9. data/docs/getting_started.md +81 -11
  10. data/docs/setting/left-analogstick-cap.md +1 -1
  11. data/docs/setting/splatoon2_macro_dasei_cancel.md +77 -0
  12. data/docs/setting/splatoon2_macro_sokuwari_bubble.md +4 -0
  13. data/docs/setting/splatoon2_shake_tansan.md +47 -0
  14. data/lib/procon_bypass_man/background/jobs/post_completed_remote_macro_job.rb +17 -0
  15. data/lib/procon_bypass_man/background.rb +1 -0
  16. data/lib/procon_bypass_man/buttons_setting_configuration/layer.rb +155 -70
  17. data/lib/procon_bypass_man/buttons_setting_configuration/loader.rb +2 -0
  18. data/lib/procon_bypass_man/buttons_setting_configuration/param_normalizer/button.rb +28 -0
  19. data/lib/procon_bypass_man/buttons_setting_configuration/param_normalizer/button_list.rb +31 -0
  20. data/lib/procon_bypass_man/buttons_setting_configuration/param_normalizer/disable_macro_if_pressed.rb +28 -0
  21. data/lib/procon_bypass_man/buttons_setting_configuration/param_normalizer/flip_if_pressed.rb +31 -0
  22. data/lib/procon_bypass_man/buttons_setting_configuration/param_normalizer/force_neutral.rb +28 -0
  23. data/lib/procon_bypass_man/buttons_setting_configuration/param_normalizer/if_pressed.rb +26 -0
  24. data/lib/procon_bypass_man/buttons_setting_configuration/param_normalizer/if_pressed_allows_nil.rb +28 -0
  25. data/lib/procon_bypass_man/buttons_setting_configuration/param_normalizer/open_macro_steps.rb +26 -0
  26. data/lib/procon_bypass_man/buttons_setting_configuration/param_normalizer.rb +17 -0
  27. data/lib/procon_bypass_man/buttons_setting_configuration.rb +6 -5
  28. data/lib/procon_bypass_man/bypass/usb_hid_logger.rb +4 -0
  29. data/lib/procon_bypass_man/bypass.rb +45 -23
  30. data/lib/procon_bypass_man/commands/bypass_command.rb +30 -10
  31. data/lib/procon_bypass_man/commands/print_boot_message_command.rb +1 -1
  32. data/lib/procon_bypass_man/configuration.rb +8 -1
  33. data/lib/procon_bypass_man/device_connector.rb +55 -174
  34. data/lib/procon_bypass_man/plugin/splatoon2/macro/charge_tansan_bomb.rb +21 -0
  35. data/lib/procon_bypass_man/plugin/splatoon2/macro/dasei_cancel.rb +21 -0
  36. data/lib/procon_bypass_man/plugin/splatoon2/version.rb +1 -1
  37. data/lib/procon_bypass_man/plugins.rb +2 -0
  38. data/lib/procon_bypass_man/procon/analog_stick_cap.rb +4 -23
  39. data/lib/procon_bypass_man/procon/analog_stick_manipulator.rb +36 -0
  40. data/lib/procon_bypass_man/procon/button_collection.rb +0 -8
  41. data/lib/procon_bypass_man/procon/layer_changer.rb +4 -1
  42. data/lib/procon_bypass_man/procon/macro.rb +53 -25
  43. data/lib/procon_bypass_man/procon/macro_builder.rb +43 -35
  44. data/lib/procon_bypass_man/procon/macro_plugin_map.rb +23 -0
  45. data/lib/procon_bypass_man/procon/macro_registry.rb +26 -10
  46. data/lib/procon_bypass_man/procon/suppress_rumble.rb +13 -0
  47. data/lib/procon_bypass_man/procon/user_operation.rb +30 -16
  48. data/lib/procon_bypass_man/procon/value_objects/analog_stick.rb +9 -5
  49. data/lib/procon_bypass_man/procon/value_objects/analog_stick_position.rb +18 -0
  50. data/lib/procon_bypass_man/{domains → procon/value_objects}/binary/base.rb +0 -0
  51. data/lib/procon_bypass_man/{domains → procon/value_objects}/binary/has_immutable_binary.rb +0 -0
  52. data/lib/procon_bypass_man/{domains → procon/value_objects}/binary/has_mutable_binary.rb +0 -0
  53. data/lib/procon_bypass_man/{domains → procon/value_objects}/binary/inbound_procon_binary.rb +5 -0
  54. data/lib/procon_bypass_man/{domains → procon/value_objects}/binary/processing_procon_binary.rb +7 -2
  55. data/lib/procon_bypass_man/procon/value_objects/binary.rb +11 -0
  56. data/lib/procon_bypass_man/{bypass → procon/value_objects}/bypass_mode.rb +0 -0
  57. data/lib/procon_bypass_man/procon/value_objects/rumble_binary.rb +18 -0
  58. data/lib/procon_bypass_man/procon.rb +59 -17
  59. data/lib/procon_bypass_man/remote_macro/queue_over_process.rb +62 -0
  60. data/lib/procon_bypass_man/remote_macro/remote_macro_object.rb +30 -0
  61. data/lib/procon_bypass_man/remote_macro/remote_macro_receiver.rb +37 -0
  62. data/lib/procon_bypass_man/remote_macro/remote_macro_sender.rb +8 -0
  63. data/lib/procon_bypass_man/remote_macro/task.rb +6 -0
  64. data/lib/procon_bypass_man/remote_macro/task_queue.rb +13 -0
  65. data/lib/procon_bypass_man/remote_macro.rb +14 -0
  66. data/lib/procon_bypass_man/remote_pbm_action/value_objects/remote_pbm_action_object.rb +1 -1
  67. data/lib/procon_bypass_man/remote_pbm_action.rb +1 -0
  68. data/lib/procon_bypass_man/runner.rb +11 -7
  69. data/lib/procon_bypass_man/support/analog_stick_hypotenuse_tilting_power_scaler.rb +59 -0
  70. data/lib/procon_bypass_man/support/cycle_sleep.rb +22 -0
  71. data/lib/procon_bypass_man/support/device_mouse_finder.rb +60 -0
  72. data/lib/procon_bypass_man/{device_procon_finder.rb → support/device_procon_finder.rb} +0 -2
  73. data/lib/procon_bypass_man/{never_exit_accidentally.rb → support/never_exit_accidentally.rb} +0 -0
  74. data/lib/procon_bypass_man/support/remote_macro_http_client.rb +9 -0
  75. data/lib/procon_bypass_man/support/safe_timeout.rb +7 -1
  76. data/lib/procon_bypass_man/{usb_device_controller.rb → support/usb_device_controller.rb} +7 -4
  77. data/lib/procon_bypass_man/version.rb +1 -1
  78. data/lib/procon_bypass_man/websocket/{pbm_job_client.rb → client.rb} +34 -12
  79. data/lib/procon_bypass_man/websocket/forever.rb +47 -0
  80. data/lib/procon_bypass_man/websocket/watchdog.rb +19 -0
  81. data/lib/procon_bypass_man.rb +25 -23
  82. data/procon_bypass_man.gemspec +1 -1
  83. data/project_template/app.rb +13 -4
  84. data/sig/main.rbs +21 -13
  85. metadata +46 -14
  86. data/lib/procon_bypass_man/domains.rb +0 -11
@@ -1,4 +1,13 @@
1
+ require "procon_bypass_man/procon/macro_plugin_map"
2
+
1
3
  class ProconBypassMan::Procon
4
+ require "procon_bypass_man/procon/value_objects/analog_stick"
5
+ require "procon_bypass_man/procon/value_objects/analog_stick_position"
6
+ require "procon_bypass_man/procon/value_objects/procon_reader"
7
+ require "procon_bypass_man/procon/value_objects/rumble_binary"
8
+ require "procon_bypass_man/procon/value_objects/binary"
9
+ require "procon_bypass_man/procon/value_objects/bypass_mode"
10
+
2
11
  require "procon_bypass_man/procon/consts"
3
12
  require "procon_bypass_man/procon/mode_registry"
4
13
  require "procon_bypass_man/procon/macro"
@@ -9,6 +18,7 @@ class ProconBypassMan::Procon
9
18
  require "procon_bypass_man/procon/user_operation"
10
19
  require "procon_bypass_man/procon/flip_cache"
11
20
  require "procon_bypass_man/procon/press_button_aware"
21
+ require "procon_bypass_man/procon/suppress_rumble"
12
22
 
13
23
  attr_accessor :user_operation
14
24
 
@@ -19,6 +29,7 @@ class ProconBypassMan::Procon
19
29
  ongoing_macro: MacroRegistry.load(:null),
20
30
  ongoing_mode: ModeRegistry.load(:manual),
21
31
  }
32
+ @@left_stick_tilting_power_scaler = ProconBypassMan::AnalogStickTiltingPowerScaler.new
22
33
  end
23
34
  reset!
24
35
 
@@ -38,6 +49,7 @@ class ProconBypassMan::Procon
38
49
  ProconBypassMan::ButtonsSettingConfiguration.instance.layers[current_layer_key]
39
50
  end
40
51
 
52
+ # 内部ステータスを書き換えるフェーズ
41
53
  def apply!
42
54
  layer_changer = ProconBypassMan::Procon::LayerChanger.new(binary: user_operation.binary)
43
55
  if layer_changer.change_layer?
@@ -46,14 +58,52 @@ class ProconBypassMan::Procon
46
58
  return
47
59
  end
48
60
 
49
- if ongoing_macro.finished?
61
+ analog_stick = ProconBypassMan::Procon::AnalogStick.new(binary: user_operation.binary.raw)
62
+ dumped_tilting_power = @@left_stick_tilting_power_scaler.add_sample(analog_stick.relative_hypotenuse)
63
+
64
+ enable_all_macro = true
65
+ enable_macro_map = Hash.new {|h,k| h[k] = true }
66
+ current_layer.disable_macros.each do |disable_macro|
67
+ if (disable_macro[:if_pressed] == [true] || user_operation.pressing_all_buttons?(disable_macro[:if_pressed]))
68
+ if disable_macro[:name] == :all
69
+ enable_all_macro = false
70
+ else
71
+ enable_macro_map[disable_macro[:name]] = false
72
+ end
73
+ end
74
+ end
75
+
76
+ if ongoing_macro.finished? && enable_all_macro
50
77
  current_layer.macros.each do |macro_name, options|
78
+ next unless enable_macro_map[macro_name]
79
+
80
+ if(if_tilted_left_stick_value = options[:if_tilted_left_stick])
81
+ threshold = (if_tilted_left_stick_value.is_a?(Hash) && if_tilted_left_stick_value[:threshold]) || ProconBypassMan::AnalogStickTiltingPowerScaler::DEFAULT_THRESHOLD
82
+ if dumped_tilting_power&.tilting?(threshold: threshold, current_position_x: analog_stick.relative_x, current_position_y: analog_stick.relative_y) && user_operation.pressing_all_buttons?(options[:if_pressed])
83
+ @@status[:ongoing_macro] = MacroRegistry.load(macro_name)
84
+ break
85
+ end
86
+
87
+ next
88
+ end
89
+
51
90
  if user_operation.pressing_all_buttons?(options[:if_pressed])
52
- @@status[:ongoing_macro] = MacroRegistry.load(macro_name)
91
+ @@status[:ongoing_macro] = MacroRegistry.load(macro_name, force_neutral_buttons: options[:force_neutral])
92
+ break
53
93
  end
54
94
  end
55
95
  end
56
96
 
97
+ # remote macro
98
+ if task = ProconBypassMan::RemoteMacro::TaskQueueInProcess.non_blocking_shift
99
+ ProconBypassMan::Procon::MacroRegistry.cleanup_remote_macros!
100
+ macro_name = task.name || "RemoteMacro-#{task.steps.join}".to_sym
101
+ ProconBypassMan::Procon::MacroRegistry.install_plugin(macro_name, steps: task.steps, macro_type: :remote)
102
+ @@status[:ongoing_macro] = MacroRegistry.load(macro_name, macro_type: :remote) do
103
+ ProconBypassMan::PostCompletedRemoteMacroJob.perform_async(task.uuid)
104
+ end
105
+ end
106
+
57
107
  case current_layer.mode
58
108
  when :manual
59
109
  @@status[:ongoing_mode] = ModeRegistry.load(:manual)
@@ -88,15 +138,17 @@ class ProconBypassMan::Procon
88
138
  status
89
139
  end
90
140
 
91
- # @return [ProconBypassMan::Domains::ProcessingProconBinary]
141
+ # @return [String]
92
142
  def to_binary
93
143
  if ongoing_mode.name != :manual
94
144
  return user_operation.binary.raw
95
145
  end
96
146
 
97
- if ongoing_macro.ongoing?
98
- step = ongoing_macro.next_step or return(user_operation.binary.raw)
99
- user_operation.press_button_only(step)
147
+ if ongoing_macro.ongoing? && (step = ongoing_macro.next_step)
148
+ ongoing_macro.force_neutral_buttons&.each do |force_neutral_button|
149
+ user_operation.unpress_button(force_neutral_button)
150
+ end
151
+ user_operation.press_button_only_or_tilt_sticks(step)
100
152
  return user_operation.binary.raw
101
153
  end
102
154
 
@@ -105,7 +157,7 @@ class ProconBypassMan::Procon
105
157
  end
106
158
 
107
159
  current_layer.left_analog_stick_caps.each do |config|
108
- if config[:if_pressed].nil? || user_operation.pressing_all_buttons?(config[:if_pressed])
160
+ if !config[:if_pressed] || user_operation.pressing_all_buttons?(config[:if_pressed])
109
161
  config[:force_neutral]&.each do |force_neutral_button|
110
162
  user_operation.unpress_button(force_neutral_button)
111
163
  end
@@ -143,14 +195,4 @@ class ProconBypassMan::Procon
143
195
 
144
196
  user_operation.binary.raw
145
197
  end
146
-
147
- private
148
-
149
- def method_missing(name)
150
- if name.to_s =~ /\Apressed_[a-z]+\?\z/
151
- user_operation.public_send(name)
152
- else
153
- super
154
- end
155
- end
156
198
  end
@@ -0,0 +1,62 @@
1
+ class ProconBypassMan::QueueOverProcess
2
+ attr_reader :drb
3
+
4
+ @@drb_server = nil
5
+ @@drb_server_thread = nil
6
+
7
+ def self.start!
8
+ return unless ProconBypassMan.config.enable_remote_macro?
9
+ require 'drb/drb'
10
+
11
+ FileUtils.rm_rf(file_path) if File.exist?(file_path)
12
+ begin
13
+ @@drb_server = DRb.start_service(url, Queue.new, safe_level: 1)
14
+ rescue Errno::EADDRINUSE => e
15
+ ProconBypassMan.logger.error e
16
+ raise
17
+ end
18
+
19
+ @@drb_server_thread =
20
+ Thread.new do
21
+ DRb.thread.join
22
+ end
23
+ end
24
+
25
+ def self.shutdown
26
+ if @@drb_server
27
+ @@drb_server_thread.kill
28
+ @@drb_server.stop_service
29
+ end
30
+ end
31
+
32
+ def self.push(value)
33
+ return unless ProconBypassMan.config.enable_remote_macro?
34
+
35
+ drb.push(value)
36
+ end
37
+
38
+ def self.pop
39
+ return unless ProconBypassMan.config.enable_remote_macro?
40
+
41
+ drb.pop
42
+ end
43
+
44
+ def self.drb
45
+ return unless ProconBypassMan.config.enable_remote_macro?
46
+
47
+ @@drb ||= new.drb
48
+ end
49
+
50
+ PROTOCOL = "drbunix"
51
+ def self.url
52
+ "#{PROTOCOL}:/tmp/procon_bypass_man_queue"
53
+ end
54
+
55
+ def self.file_path
56
+ url.gsub("#{PROTOCOL}:", "")
57
+ end
58
+
59
+ def initialize
60
+ @drb = DRbObject.new_with_uri(self.class.url)
61
+ end
62
+ end
@@ -0,0 +1,30 @@
1
+ module ProconBypassMan
2
+ class RemoteMacroObject
3
+ # valueobjectがvalidatorの責務も持っている. 今度分離する
4
+ class ValidationError < StandardError; end
5
+ class MustBeNotNilError < ValidationError; end
6
+ class NonSupportAction < ValidationError; end
7
+
8
+ attr_accessor :name, :uuid, :steps
9
+
10
+ # @param [String] name
11
+ # @param [String] uuid
12
+ # @param [Array] steps
13
+ def initialize(name: , uuid:, steps: )
14
+ @name = name
15
+ @uuid = uuid
16
+ @steps = steps
17
+ freeze
18
+ end
19
+
20
+ # @raise [MustBeNotNilError]
21
+ # @raise [NonSupportAction]
22
+ # @return [void]
23
+ def validate!
24
+ self.uuid or raise MustBeNotNilError, "uuidは値が必須です"
25
+ unless self.steps.is_a?(Array)
26
+ raise ValidationError, "stepsは配列です"
27
+ end
28
+ end
29
+ end
30
+ end
@@ -0,0 +1,37 @@
1
+ class ProconBypassMan::RemoteMacroReceiver
2
+ # forkしたプロセスで動かすクラス。sock経由で命令を受け取ってmacoのキューに積んでいく
3
+ def self.start_with_foreground!
4
+ return unless ProconBypassMan.config.enable_remote_macro?
5
+
6
+ run
7
+ end
8
+
9
+ def self.start!
10
+ return unless ProconBypassMan.config.enable_remote_macro?
11
+
12
+ Thread.start do
13
+ start_with_foreground!
14
+ end
15
+ end
16
+
17
+ def self.run
18
+ while(task = ProconBypassMan::QueueOverProcess.pop)
19
+ receive(task)
20
+ end
21
+ shutdown
22
+ rescue Errno::ENOENT, Errno::ECONNRESET, Errno::ECONNREFUSED => e
23
+ ProconBypassMan.logger.debug(e)
24
+ end
25
+
26
+
27
+ # @param [ProconBypassMan::RemoteMacro::Task] task
28
+ def self.receive(task)
29
+ ProconBypassMan.logger.info "[remote macro][receiver] name: #{task.name}, uuid: #{task.uuid}, steps: #{task.steps}"
30
+ ProconBypassMan::RemoteMacro::TaskQueueInProcess.push(task)
31
+ true
32
+ end
33
+
34
+ def self.shutdown
35
+ ProconBypassMan.logger.info("ProconBypassMan::RemoteMacroReceiverを終了します。")
36
+ end
37
+ end
@@ -0,0 +1,8 @@
1
+ class ProconBypassMan::RemoteMacroSender
2
+ def self.execute(name: , uuid: , steps: )
3
+ ProconBypassMan.logger.info "[remote macro][sender] name: #{name}, uuid: #{uuid}, steps: #{steps}"
4
+ ProconBypassMan::QueueOverProcess.push(
5
+ ProconBypassMan::RemoteMacro::Task.new(name, uuid, steps)
6
+ )
7
+ end
8
+ end
@@ -0,0 +1,6 @@
1
+ module ProconBypassMan
2
+ module RemoteMacro
3
+ class Task < Struct.new(:name, :uuid, :steps)
4
+ end
5
+ end
6
+ end
@@ -0,0 +1,13 @@
1
+ module ProconBypassMan
2
+ module RemoteMacro
3
+ class TaskQueue < ::Queue
4
+ def present?
5
+ not empty?
6
+ end
7
+
8
+ def non_blocking_shift
9
+ present? && shift
10
+ end
11
+ end
12
+ end
13
+ end
@@ -0,0 +1,14 @@
1
+ module ProconBypassMan
2
+ module RemoteMacro
3
+ require "procon_bypass_man/remote_macro/remote_macro_object"
4
+ require "procon_bypass_man/remote_macro/remote_macro_receiver"
5
+ require "procon_bypass_man/remote_macro/remote_macro_sender"
6
+ require "procon_bypass_man/remote_macro/queue_over_process"
7
+ require "procon_bypass_man/remote_macro/task"
8
+ require "procon_bypass_man/remote_macro/task_queue"
9
+
10
+ ACTION_KEY = "remote_macro"
11
+
12
+ TaskQueueInProcess = ProconBypassMan::RemoteMacro::TaskQueue.new
13
+ end
14
+ end
@@ -11,7 +11,7 @@ module ProconBypassMan
11
11
  # @param [String] status
12
12
  # @param [String] #uuid
13
13
  # @param [Time] created_at
14
- # @return [Hash] job_args
14
+ # @param [Hash] job_args
15
15
  def initialize(action: , status:, uuid:, created_at:, job_args: )
16
16
  self.action = action
17
17
  self.status = status
@@ -6,6 +6,7 @@ module ProconBypassMan
6
6
  require "procon_bypass_man/remote_pbm_action/stop_pbm_action"
7
7
  require "procon_bypass_man/remote_pbm_action/restore_pbm_setting.rb"
8
8
  require "procon_bypass_man/remote_pbm_action/commands/update_remote_pbm_action_status_command"
9
+ require "procon_bypass_man/remote_pbm_action/value_objects/remote_pbm_action_object"
9
10
 
10
11
  ACTION_CHANGE_PBM_VERSION = "change_pbm_version"
11
12
  ACTION_REBOOT_OS = "reboot_os"
@@ -14,7 +14,7 @@ class ProconBypassMan::Runner
14
14
 
15
15
  def run
16
16
  self_read, self_write = IO.pipe
17
- %w(TERM INT USR1 USR2).each do |sig|
17
+ %w(TERM INT USR2).each do |sig|
18
18
  begin
19
19
  trap sig do
20
20
  self_write.puts(sig)
@@ -25,19 +25,23 @@ class ProconBypassMan::Runner
25
25
  end
26
26
 
27
27
  loop do
28
- $will_terminate_token = false
29
28
  # NOTE メインプロセスではThreadをいくつか起動しているので念のためパフォーマンスを優先するためにforkしていく
30
- child_pid = Kernel.fork { ProconBypassMan::BypassCommand.new(gadget: @gadget, procon: @procon).execute }
29
+ child_pid = Kernel.fork {
30
+ $will_terminate_token = false
31
+ DRb.start_service if defined?(DRb)
32
+ ProconBypassMan::RemoteMacroReceiver.start!
33
+ ProconBypassMan::BypassCommand.new(gadget: @gadget, procon: @procon).execute # ここでblockingする
34
+ next
35
+ }
31
36
 
32
37
  begin
33
- # TODO 小プロセスが消滅した時に、メインプロセスは生き続けてしまい、何もできなくなる問題がある
38
+ # TODO 子プロセスが消滅した時に、メインプロセスは生き続けてしまい、何もできなくなる問題がある
34
39
  while(readable_io = IO.select([self_read]))
35
40
  signal = readable_io.first[0].gets.strip
36
41
  handle_signal(signal)
37
42
  end
38
43
  rescue InterruptForRestart
39
- $will_terminate_token = true
40
- Process.kill("TERM", child_pid)
44
+ Process.kill("USR2", child_pid)
41
45
  Process.wait
42
46
  ProconBypassMan::PrintMessageCommand.execute(text: "Reloading config file")
43
47
  begin
@@ -49,10 +53,10 @@ class ProconBypassMan::Runner
49
53
  end
50
54
  ProconBypassMan::PrintMessageCommand.execute(text: "バイパス処理を再開します")
51
55
  rescue Interrupt
52
- $will_terminate_token = true
53
56
  Process.kill("TERM", child_pid)
54
57
  Process.wait
55
58
  ProconBypassMan::PrintMessageCommand.execute(text: "処理を終了します")
59
+ ProconBypassMan::UsbDeviceController.reset
56
60
  @gadget&.close
57
61
  @procon&.close
58
62
  break
@@ -0,0 +1,59 @@
1
+ class ProconBypassMan::AnalogStickTiltingPowerScaler
2
+ DEFAULT_THRESHOLD = 500
3
+
4
+ class PowerChunk
5
+ def initialize(list)
6
+ @list = list
7
+ end
8
+
9
+ def moving_power
10
+ max = @list.max
11
+ min = @list.min
12
+ moving_power = (max - min).abs
13
+ end
14
+
15
+ def tilting?(threshold: DEFAULT_THRESHOLD, current_position_x: , current_position_y: )
16
+ # スティックがニュートラルな時
17
+ if (-200..200).include?(current_position_x) && (-200..200).include?(current_position_y)
18
+ return false
19
+ end
20
+
21
+ moving_power >= threshold
22
+ end
23
+ end
24
+
25
+ def initialize
26
+ @map = {}
27
+ end
28
+
29
+ # @return [NilClass, Chunk] ローテトしたらvalueを返す
30
+ def add_sample(value)
31
+ rotated = nil
32
+ current_key = key
33
+ if @map[current_key].nil?
34
+ rotated = rotate
35
+ @map = { current_key => [] } # renew or initialize
36
+ end
37
+
38
+ @map[current_key] << value
39
+ rotated
40
+ end
41
+
42
+ private
43
+
44
+ # 0.1sec刻みで進行する
45
+ def key
46
+ time = Time.now
47
+ m1 = time.strftime('%L')[0]
48
+ [time.to_i, m1].join.to_i
49
+ end
50
+
51
+ def rotate
52
+ list = @map.values.first
53
+ if list
54
+ return PowerChunk.new(list)
55
+ else
56
+ return nil
57
+ end
58
+ end
59
+ end
@@ -0,0 +1,22 @@
1
+ # n秒間sleepしつつ、mainスレッドをm秒間隔で動かしたい時に使う
2
+ class ProconBypassMan::CycleSleep
3
+ attr_accessor :cycle_interval, :execution_cycle
4
+
5
+ def initialize(cycle_interval: , execution_cycle: )
6
+ @cycle_interval = cycle_interval
7
+ @execution_cycle = execution_cycle
8
+ @counter = 0
9
+ end
10
+
11
+ def sleep_or_execute
12
+ result = nil
13
+ if @counter >= @execution_cycle
14
+ @counter = 0
15
+ result = yield
16
+ else
17
+ @counter += 1
18
+ end
19
+ sleep(@cycle_interval)
20
+ return result
21
+ end
22
+ end
@@ -0,0 +1,60 @@
1
+ class ProconBypassMan::DeviceMouseFinder
2
+ class USBDevice < Struct.new(:display_name, :event_no)
3
+ # TODO bInterfaceProtocolの値を見てmouseかを判断したい
4
+ def mouse?
5
+ !!(display_name =~ /mouse/i)
6
+ end
7
+
8
+ def keyboard?
9
+ !!(display_name =~ /keyboard/i)
10
+ end
11
+
12
+ def event_device_path
13
+ "/dev/input/#{event_no}"
14
+ end
15
+ end
16
+
17
+ class Parser
18
+ def self.parse(shell_output)
19
+ instance = new
20
+ instance.set_usb_devices_from(shell_output)
21
+ instance
22
+ end
23
+
24
+ def set_usb_devices_from(shell_output)
25
+ @usb_devices =
26
+ shell_output.split(/\n\n/).map do |text|
27
+ display_name = /N: Name="(.+?)"$/ =~ text && $1
28
+ event_no = /H: Handlers=.*?(event\d).*?$/ =~ text && $1
29
+ USBDevice.new(display_name, event_no)
30
+ end
31
+ end
32
+
33
+ def usb_devices
34
+ @usb_devices ||= []
35
+ end
36
+ end
37
+
38
+ def self.find
39
+ new.find
40
+ end
41
+
42
+ # @return [String, NilClass]
43
+ def find
44
+ find_path
45
+ end
46
+
47
+ private
48
+
49
+ def find_path
50
+ Parser.parse(shell_output).usb_devices.detect(&:mouse?)&.event_device_path
51
+ end
52
+
53
+ def shell_output
54
+ `bash -c '#{shell}'`
55
+ end
56
+
57
+ def shell
58
+ 'cat /proc/bus/input/devices'
59
+ end
60
+ end
@@ -31,8 +31,6 @@ class ProconBypassMan::DeviceProconFinder
31
31
 
32
32
  def get_list_shell
33
33
  <<~SHELL
34
- #!/bin/bash
35
-
36
34
  FILES=/dev/hidraw*
37
35
  for f in $FILES
38
36
  do
@@ -0,0 +1,9 @@
1
+ module ProconBypassMan
2
+ class RemoteMacroHttpClient < HttpClient
3
+ def post(job_id: )
4
+ super(request_body: {
5
+ job_id: job_id,
6
+ })
7
+ end
8
+ end
9
+ end
@@ -7,8 +7,14 @@ module ProconBypassMan
7
7
  @timeout = timeout
8
8
  end
9
9
 
10
+ # @raise [Timeout]
10
11
  def throw_if_timeout!
11
- raise Timeout if @timeout < Time.now
12
+ raise Timeout if timeout?
13
+ end
14
+
15
+ # @return [Boolean]
16
+ def timeout?
17
+ @timeout < Time.now
12
18
  end
13
19
  end
14
20
  end
@@ -1,8 +1,12 @@
1
1
  class ProconBypassMan::UsbDeviceController
2
2
  class << self
3
3
  def reset
4
- system('echo > /sys/kernel/config/usb_gadget/procon/UDC')
5
- system('ls /sys/class/udc > /sys/kernel/config/usb_gadget/procon/UDC')
4
+ [ "echo > /sys/kernel/config/usb_gadget/procon/UDC",
5
+ "ls /sys/class/udc > /sys/kernel/config/usb_gadget/procon/UDC",
6
+ ].each do |shell|
7
+ system shell
8
+ ProconBypassMan.logger.debug { "[SHELL] #{shell}" }
9
+ end
6
10
  sleep 0.5
7
11
  end
8
12
 
@@ -10,8 +14,6 @@ class ProconBypassMan::UsbDeviceController
10
14
  return if initialized?
11
15
 
12
16
  shell = <<~EOH
13
- #!/bin/bash
14
-
15
17
  cd /sys/kernel/config/usb_gadget/
16
18
  mkdir -p procon
17
19
  cd procon
@@ -44,6 +46,7 @@ class ProconBypassMan::UsbDeviceController
44
46
  EOH
45
47
 
46
48
  `bash -c '#{shell}'`
49
+ sleep(1)
47
50
  end
48
51
 
49
52
  def initialized?
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module ProconBypassMan
4
- VERSION = "0.1.20.2"
4
+ VERSION = "0.1.23"
5
5
  end