procon_bypass_man 0.1.15 → 0.1.18

Sign up to get free protection for your applications and to get access to all the features.
Files changed (80) hide show
  1. checksums.yaml +4 -4
  2. data/.circleci/config.yml +1 -0
  3. data/.github/workflows/release.yml +2 -2
  4. data/.rubocop.yml +2 -0
  5. data/CHANGELOG.md +17 -0
  6. data/Gemfile +1 -0
  7. data/Gemfile.lock +29 -7
  8. data/README.md +32 -4
  9. data/Steepfile +31 -17
  10. data/docs/setting/left-analogstick-cap.md +60 -0
  11. data/docs/setting/splatoon2_macro_sokuwari_bubble.md +52 -0
  12. data/docs/setup_raspi.md +2 -0
  13. data/docs/setup_raspi.mitamae.rb +7 -8
  14. data/docs/setup_raspi_by_mitamae.md +37 -1
  15. data/docs/upgrade_pbm.md +32 -0
  16. data/lib/ext/em_pure_ruby.rb +25 -0
  17. data/lib/ext/module.rb +16 -0
  18. data/lib/procon_bypass_man/background.rb +0 -1
  19. data/lib/procon_bypass_man/buttons_setting_configuration/layer.rb +35 -13
  20. data/lib/procon_bypass_man/buttons_setting_configuration/loader.rb +4 -1
  21. data/lib/procon_bypass_man/buttons_setting_configuration/validator.rb +36 -0
  22. data/lib/procon_bypass_man/buttons_setting_configuration.rb +28 -13
  23. data/lib/procon_bypass_man/bypass/usb_hid_logger.rb +6 -4
  24. data/lib/procon_bypass_man/bypass.rb +13 -6
  25. data/lib/procon_bypass_man/commands/bypass_command.rb +2 -2
  26. data/lib/procon_bypass_man/commands/print_boot_message_command.rb +50 -1
  27. data/lib/procon_bypass_man/commands/print_message_command.rb +8 -0
  28. data/lib/procon_bypass_man/commands/run_remote_pbm_action_dispatch_command.rb +1 -1
  29. data/lib/procon_bypass_man/commands/send_reload_config_event_command.rb +1 -2
  30. data/lib/procon_bypass_man/commands.rb +1 -0
  31. data/lib/procon_bypass_man/configuration.rb +32 -1
  32. data/lib/procon_bypass_man/domains/binary/base.rb +25 -0
  33. data/lib/procon_bypass_man/domains/binary/has_immutable_binary.rb +5 -0
  34. data/lib/procon_bypass_man/domains/binary/has_mutable_binary.rb +5 -0
  35. data/lib/procon_bypass_man/domains/binary/inbound_procon_binary.rb +9 -0
  36. data/lib/procon_bypass_man/domains/binary/processing_procon_binary.rb +66 -0
  37. data/lib/procon_bypass_man/domains.rb +11 -0
  38. data/lib/procon_bypass_man/plugin/splatoon2/macro/fast_return.rb +1 -1
  39. data/lib/procon_bypass_man/plugin/splatoon2/macro/jump_to_left_key.rb +1 -1
  40. data/lib/procon_bypass_man/plugin/splatoon2/macro/jump_to_right_key.rb +1 -1
  41. data/lib/procon_bypass_man/plugin/splatoon2/macro/jump_to_up_key.rb +1 -1
  42. data/lib/procon_bypass_man/plugin/splatoon2/macro/sokuwari_for_splash_bomb.rb +22 -0
  43. data/lib/procon_bypass_man/plugin/splatoon2/version.rb +1 -1
  44. data/lib/procon_bypass_man/{plugin.rb → plugins.rb} +1 -0
  45. data/lib/procon_bypass_man/processor.rb +4 -5
  46. data/lib/procon_bypass_man/procon/button.rb +11 -0
  47. data/lib/procon_bypass_man/procon/button_collection.rb +9 -11
  48. data/lib/procon_bypass_man/procon/layer_changer.rb +3 -2
  49. data/lib/procon_bypass_man/procon/macro.rb +89 -0
  50. data/lib/procon_bypass_man/procon/macro_builder.rb +123 -0
  51. data/lib/procon_bypass_man/procon/macro_registry.rb +9 -27
  52. data/lib/procon_bypass_man/procon/mode_registry.rb +4 -4
  53. data/lib/procon_bypass_man/procon/press_button_aware.rb +9 -7
  54. data/lib/procon_bypass_man/procon/user_operation.rb +58 -61
  55. data/lib/procon_bypass_man/procon/{analog_stick.rb → value_objects/analog_stick.rb} +3 -4
  56. data/lib/procon_bypass_man/procon/value_objects/procon_reader.rb +34 -0
  57. data/lib/procon_bypass_man/procon.rb +20 -16
  58. data/lib/procon_bypass_man/remote_pbm_action/{lib → commands}/update_remote_pbm_action_status_command.rb +0 -0
  59. data/lib/procon_bypass_man/remote_pbm_action/restore_pbm_setting.rb +1 -1
  60. data/lib/procon_bypass_man/{value_objects → remote_pbm_action/value_objects}/remote_pbm_action_object.rb +0 -0
  61. data/lib/procon_bypass_man/remote_pbm_action.rb +1 -1
  62. data/lib/procon_bypass_man/runner.rb +3 -3
  63. data/lib/procon_bypass_man/scheduler.rb +0 -7
  64. data/lib/procon_bypass_man/support/compress_array.rb +5 -0
  65. data/lib/procon_bypass_man/support/http_client.rb +4 -0
  66. data/lib/procon_bypass_man/support/on_memory_cache.rb +3 -1
  67. data/lib/procon_bypass_man/support/server_pool.rb +4 -0
  68. data/lib/procon_bypass_man/version.rb +1 -1
  69. data/lib/procon_bypass_man/websocket/pbm_job_client.rb +90 -0
  70. data/lib/procon_bypass_man.rb +13 -6
  71. data/procon_bypass_man.gemspec +3 -1
  72. data/project_template/README.md +10 -5
  73. data/project_template/app.rb +3 -2
  74. data/sig/main.rbs +226 -41
  75. data/sig/on_memory_cache.rbs +16 -0
  76. metadata +56 -13
  77. data/lib/procon_bypass_man/background/jobs/fetch_and_run_remote_pbm_action_job.rb +0 -29
  78. data/lib/procon_bypass_man/boot_message.rb +0 -48
  79. data/lib/procon_bypass_man/commands/run_local_shell_command.rb +0 -6
  80. data/lib/procon_bypass_man/procon_reader.rb +0 -31
@@ -8,9 +8,8 @@ module ProconBypassMan
8
8
  self.flips = {}
9
9
  self.macros = {}
10
10
  self.remaps = {}
11
- self.left_analog_stick_caps = {}
11
+ self.left_analog_stick_caps = []
12
12
  self.disables = []
13
- instance_eval(&block) if block_given?
14
13
  end
15
14
 
16
15
  # @param [Symbol] button
@@ -50,19 +49,22 @@ module ProconBypassMan
50
49
  end
51
50
  hash[:flip_interval] = interval
52
51
  end
53
- if self.flips[button]
54
- raise "#{button}への設定をすでに割り当て済みです"
55
- else
56
- self.flips[button] = hash
57
- end
52
+
53
+ self.flips[button] = hash
58
54
  end
59
55
 
56
+ # @param [String, Class] プラグインのclass
60
57
  def macro(name, if_pressed: )
61
- if name.respond_to?(:name)
62
- macro_name = name.name.to_sym
63
- else
64
- macro_name = name
65
- end
58
+ macro_name = name.to_s.to_sym
59
+ self.macros[macro_name] = { if_pressed: if_pressed }
60
+ end
61
+
62
+ # 設定ファイルに直接マクロを打ち込める
63
+ # @param [String, Class] macroの識別子
64
+ # @paramh[Array<Symbol>] macroの本体. ボタンの配列
65
+ def open_macro(name, steps: , if_pressed: )
66
+ macro_name = name || "OpenMacro-#{steps.join}".to_sym
67
+ ProconBypassMan::Procon::MacroRegistry.install_plugin(macro_name, steps: steps)
66
68
  self.macros[macro_name] = { if_pressed: if_pressed }
67
69
  end
68
70
 
@@ -92,6 +94,10 @@ module ProconBypassMan
92
94
  raise "not support value"
93
95
  end
94
96
 
97
+ if if_pressed
98
+ hash[:if_pressed] = if_pressed
99
+ end
100
+
95
101
  case force_neutral
96
102
  when TrueClass
97
103
  raise "ボタンを渡してください"
@@ -105,7 +111,7 @@ module ProconBypassMan
105
111
  raise "not support value"
106
112
  end
107
113
 
108
- left_analog_stick_caps[if_pressed] = hash
114
+ left_analog_stick_caps << hash
109
115
  end
110
116
 
111
117
  def disable(button)
@@ -127,6 +133,22 @@ module ProconBypassMan
127
133
  def flip_buttons
128
134
  flips
129
135
  end
136
+
137
+ # @return [String]
138
+ def to_json(*)
139
+ to_hash.to_json
140
+ end
141
+
142
+ # @return [Hash]
143
+ def to_hash
144
+ { mode: mode,
145
+ flips: flips,
146
+ macros: macros,
147
+ remaps: remaps,
148
+ disables: disables,
149
+ left_analog_stick_caps: left_analog_stick_caps,
150
+ }
151
+ end
130
152
  end
131
153
  end
132
154
  end
@@ -3,6 +3,7 @@ module ProconBypassMan
3
3
  module Loader
4
4
  require 'digest/md5'
5
5
 
6
+ # @return [ProconBypassMan::ButtonsSettingConfiguration]
6
7
  def self.load(setting_path: )
7
8
  ProconBypassMan::ButtonsSettingConfiguration.switch_new_context(:validation) do |new_instance|
8
9
  yaml = YAML.load_file(setting_path) or raise "読み込みに失敗しました"
@@ -14,7 +15,9 @@ module ProconBypassMan
14
15
  raise ProconBypassMan::CouldNotLoadConfigError, validator.errors
15
16
  end
16
17
  rescue SyntaxError
17
- raise ProconBypassMan::CouldNotLoadConfigError, "Rubyのシンタックスエラーです"
18
+ raise ProconBypassMan::CouldNotLoadConfigError, "Rubyスクリプトのシンタックスエラーです"
19
+ rescue NoMethodError
20
+ raise ProconBypassMan::CouldNotLoadConfigError, "Rubyスクリプトに未定義の定数・変数があります"
18
21
  rescue Psych::SyntaxError
19
22
  raise ProconBypassMan::CouldNotLoadConfigError, "yamlのシンタックスエラーです"
20
23
  end
@@ -2,6 +2,8 @@ module ProconBypassMan
2
2
  class ButtonsSettingConfiguration
3
3
  class Validator
4
4
  def initialize(config)
5
+ @macro_plugins = config.macro_plugins
6
+ @mode_plugins = config.mode_plugins
5
7
  @layers = config.layers
6
8
  @prefix_keys = config.prefix_keys
7
9
  end
@@ -14,6 +16,8 @@ module ProconBypassMan
14
16
  validate_config_of_button_lonely
15
17
  validate_verify_button_existence
16
18
  validate_flip_and_remap_are_hate_each_other
19
+ validate_verify_mode_plugins
20
+ validate_verify_macro_plugins
17
21
 
18
22
  @errors.empty?
19
23
  end
@@ -86,6 +90,38 @@ module ProconBypassMan
86
90
  end
87
91
  end
88
92
  end
93
+
94
+ def validate_verify_mode_plugins
95
+ @mode_plugins.each do |key, mode|
96
+ begin
97
+ Module.const_get(key.to_s)
98
+ rescue NameError
99
+ next
100
+ end
101
+
102
+ if(const = Module.const_get(key.to_s))
103
+ if not const.respond_to?(:binaries) && mode.call
104
+ @errors[:mode] << "モード #{key}を読み込めませんでした。"
105
+ end
106
+ end
107
+ end
108
+ end
109
+
110
+ def validate_verify_macro_plugins
111
+ @macro_plugins.each do |key, macro|
112
+ begin
113
+ Module.const_get(key.to_s)
114
+ rescue NameError
115
+ next
116
+ end
117
+
118
+ if(const = Module.const_get(key.to_s))
119
+ if not const.respond_to?(:steps) && macro.call
120
+ @errors[:macro] << "マクロ #{key}を読み込めませんでした。"
121
+ end
122
+ end
123
+ end
124
+ end
89
125
  end
90
126
  end
91
127
  end
@@ -15,14 +15,21 @@ module ProconBypassMan
15
15
  :neutral_position
16
16
 
17
17
  def self.instance
18
- @@current_context_key ||= :main
19
18
  @@context ||= {}
20
- @@context[@@current_context_key] ||= new
19
+ @@context[current_context_key] ||= new
20
+ end
21
+
22
+ def self.current_context_key
23
+ @@current_context_key ||= :main
24
+ end
25
+
26
+ def self.instance=(val)
27
+ @@context[current_context_key] = val
21
28
  end
22
29
 
23
30
  def self.switch_new_context(key)
24
31
  @@context[key] = new
25
- previous_key = @@current_context_key
32
+ previous_key = current_context_key
26
33
  if block_given?
27
34
  @@current_context_key = key
28
35
  value = yield(@@context[key])
@@ -35,23 +42,31 @@ module ProconBypassMan
35
42
 
36
43
  def initialize
37
44
  reset!
45
+ self.class.instance = self
38
46
  end
39
47
 
40
48
  module ManualMode
41
49
  def self.name
42
- 'manual'
50
+ :manual
43
51
  end
44
52
  end
45
53
  def layer(direction, mode: ManualMode, &block)
46
- mode_name = case mode
47
- when String
48
- mode.to_sym
49
- when Symbol
50
- mode
51
- else
52
- mode.name.to_sym
53
- end
54
- unless ([ManualMode.name.to_sym] + ProconBypassMan::Procon::ModeRegistry.plugins.keys).include?(mode_name)
54
+ if ProconBypassMan::ButtonsSettingConfiguration::ManualMode == mode
55
+ mode_name = mode.name
56
+ else
57
+ mode_name = case mode
58
+ when ProconBypassMan::ButtonsSettingConfiguration::ManualMode
59
+ mode.name
60
+ when String
61
+ mode.to_sym
62
+ when Symbol
63
+ mode
64
+ else
65
+ mode.to_s.to_sym
66
+ end
67
+ end
68
+
69
+ unless ([ManualMode.name] + ProconBypassMan::Procon::ModeRegistry.plugins.keys).include?(mode_name)
55
70
  raise("#{mode_name} mode is unknown")
56
71
  end
57
72
 
@@ -28,10 +28,12 @@ class ProconBypassMan::Bypass
28
28
  end
29
29
  end
30
30
 
31
- ProconBypassMan.cache.fetch key: 'pressed_buttons_reporter', expires_in: 5 do
32
- ProconBypassMan::ReportPressedButtonsJob.perform_async(
33
- ProconBypassMan::ProconReader.new(binary: bypass_value.binary).to_hash
34
- )
31
+ if ProconBypassMan.config.enable_reporting_pressed_buttons
32
+ ProconBypassMan.cache.fetch key: 'pressed_buttons_reporter', expires_in: 5 do
33
+ ProconBypassMan::ReportPressedButtonsJob.perform_async(
34
+ bypass_value.binary.to_procon_reader.to_hash
35
+ )
36
+ end
35
37
  end
36
38
  end
37
39
  end
@@ -5,7 +5,7 @@ class ProconBypassMan::Bypass
5
5
 
6
6
  class BypassValue < Struct.new(:binary, :sent)
7
7
  def to_text
8
- "#{binary.unpack("H*").first} #{'x' unless sent}"
8
+ "#{binary.unpack.first} #{'x' unless sent}"
9
9
  end
10
10
  end
11
11
 
@@ -21,14 +21,14 @@ class ProconBypassMan::Bypass
21
21
  def send_gadget_to_procon!
22
22
  monitor.record(:start_function)
23
23
  input = nil
24
- self.bypass_value = BypassValue.new(input, sent = false)
24
+ self.bypass_value = BypassValue.new(nil, sent = false)
25
25
 
26
26
  run_callbacks(:send_gadget_to_procon) do
27
27
  begin
28
28
  break if $will_terminate_token
29
29
  # TODO blocking readにしたいが、接続時のフェーズによって長さが違うので厳しい
30
30
  input = self.gadget.read_nonblock(64)
31
- self.bypass_value.binary = input
31
+ self.bypass_value.binary = ProconBypassMan::Domains::InboundProconBinary.new(binary: input)
32
32
  rescue IO::EAGAINWaitReadable
33
33
  monitor.record(:eagain_wait_readable_on_read)
34
34
  sleep(0.001)
@@ -50,14 +50,14 @@ class ProconBypassMan::Bypass
50
50
  def send_procon_to_gadget!
51
51
  monitor.record(:start_function)
52
52
  output = nil
53
- self.bypass_value = BypassValue.new(output, sent = false)
53
+ self.bypass_value = BypassValue.new(nil, sent = false)
54
54
 
55
55
  run_callbacks(:send_procon_to_gadget) do
56
56
  begin
57
57
  break if $will_terminate_token
58
58
  Timeout.timeout(1) do
59
59
  output = self.procon.read(64)
60
- self.bypass_value.binary = output
60
+ self.bypass_value.binary = ProconBypassMan::Domains::InboundProconBinary.new(binary: output)
61
61
  end
62
62
  rescue Timeout::Error
63
63
  ProconBypassMan.logger.debug { "read timeout! do sleep. by send_procon_to_gadget!" }
@@ -72,8 +72,15 @@ class ProconBypassMan::Bypass
72
72
  retry
73
73
  end
74
74
 
75
+ # blocking readをしているのでnilが入ることはないが、雑なテストでnilが通るので分岐を入れる。できれば消したい
76
+ break if output.nil?
77
+
75
78
  begin
76
- self.gadget.write_nonblock(ProconBypassMan::Processor.new(output).process)
79
+ self.gadget.write_nonblock(
80
+ ProconBypassMan::Processor.new(
81
+ ProconBypassMan::Domains::InboundProconBinary.new(binary: output)
82
+ ).process
83
+ )
77
84
  self.bypass_value.sent = true
78
85
  rescue IO::EAGAINWaitReadable
79
86
  monitor.record(:eagain_wait_readable_on_write)
@@ -40,7 +40,7 @@ class ProconBypassMan::BypassCommand
40
40
  monitor1.shutdown
41
41
  puts "10秒経過したのでThread1を終了します"
42
42
  break
43
- rescue Errno::EIO, Errno::ENODEV, Errno::EPROTO, IOError => e
43
+ rescue Errno::EIO, Errno::ENODEV, Errno::EPROTO, IOError, Errno::ESHUTDOWN => e
44
44
  ProconBypassMan::SendErrorCommand.execute(error: "Switchとの切断されました.終了処理を開始します. #{e.full_message}")
45
45
  Process.kill "TERM", Process.ppid
46
46
  rescue Errno::ETIMEDOUT => e
@@ -62,7 +62,7 @@ class ProconBypassMan::BypassCommand
62
62
  rescue EOFError => e
63
63
  ProconBypassMan::SendErrorCommand.execute(error: "Proconが切断されました。終了処理を開始します. #{e.full_message}")
64
64
  Process.kill "TERM", Process.ppid
65
- rescue Errno::EIO, Errno::ENODEV, Errno::EPROTO, IOError => e
65
+ rescue Errno::EIO, Errno::ENODEV, Errno::EPROTO, IOError, Errno::ESHUTDOWN => e
66
66
  ProconBypassMan::SendErrorCommand.execute(error: "Proconが切断されました。終了処理を開始します2. #{e.full_message}")
67
67
  Process.kill "TERM", Process.ppid
68
68
  end
@@ -1,7 +1,56 @@
1
1
  class ProconBypassMan::PrintBootMessageCommand
2
+ class BootMessage
3
+ def initialize
4
+ @table = {}
5
+ @table[:ruby_version] = RUBY_VERSION
6
+ @table[:pbm_version] = ProconBypassMan::VERSION
7
+ @table[:pid] = $$
8
+ @table[:root_path] = ProconBypassMan.root
9
+ @table[:pid_path] = ProconBypassMan.pid_path
10
+ @table[:setting_path] = ProconBypassMan::ButtonsSettingConfiguration.instance.setting_path
11
+ @table[:uptime_from_boot] = ProconBypassMan::Uptime.from_boot
12
+ @table[:use_pbmenv] = !(!!`which pbmenv`.empty?)
13
+ @table[:session_id] = ProconBypassMan.session_id
14
+ @table[:device_id] = ProconBypassMan.device_id
15
+
16
+ # 開発中のHEADを取りたかったけど、Gem::Specification経由から取得する必要がありそう
17
+ # build_version = `git rev-parse --short HEAD`.chomp
18
+ # if build_version.empty?
19
+ # @table[:build_version] = 'release version'
20
+ # else
21
+ # @table[:build_version] = build_version
22
+ # end
23
+
24
+ # build version: #{@table[:build_version]}
25
+ end
26
+
27
+ # @return [String]
28
+ def to_s
29
+ booted_message = <<~EOF
30
+ ----
31
+ RUBY_VERSION: #{@table[:ruby_version]}
32
+ ProconBypassMan::VERSION: #{@table[:pbm_version]}
33
+ pid: #{@table[:pid]}
34
+ root: #{@table[:root_path]}
35
+ pid_path: #{@table[:pid_path]}
36
+ setting_path: #{@table[:setting_path]}
37
+ uptime from boot: #{@table[:uptime_from_boot]} sec
38
+ use_pbmenv: #{@table[:use_pbmenv]}
39
+ session_id: #{ProconBypassMan.session_id}
40
+ device_id: #{ProconBypassMan.device_id}
41
+ ----
42
+ EOF
43
+ end
44
+
45
+ # @return [Hash]
46
+ def to_hash
47
+ @table
48
+ end
49
+ end
50
+
2
51
  # @return [void]
3
52
  def self.execute
4
- message = ProconBypassMan::BootMessage.new
53
+ message = BootMessage.new
5
54
  ProconBypassMan::ReportBootJob.perform_async(message.to_hash)
6
55
  ProconBypassMan::ReportLoadConfigJob.perform_async(ProconBypassMan.config.raw_setting)
7
56
  puts message.to_s
@@ -0,0 +1,8 @@
1
+ class ProconBypassMan::PrintMessageCommand
2
+ # @return [void]
3
+ # @param [String] text
4
+ def self.execute(text: )
5
+ ProconBypassMan.logger.info text
6
+ puts text
7
+ end
8
+ end
@@ -13,7 +13,7 @@ class ProconBypassMan::RunRemotePbmActionDispatchCommand
13
13
  when ProconBypassMan::RemotePbmAction::ACTION_RESTORE_SETTING
14
14
  ProconBypassMan::RemotePbmAction::RestorePbmSettingAction.new(pbm_job_uuid: uuid).run!(job_args: job_args)
15
15
  else
16
- ProconBypassMan::SendErrorCommand.execute(error: "#{action}は対応していないアクションです")
16
+ raise "#{action}は対応していないアクションです"
17
17
  end
18
18
  rescue ProconBypassMan::RemotePbmAction::ActionUnexpectedError => e
19
19
  ProconBypassMan::SendErrorCommand.execute(error: e)
@@ -1,8 +1,7 @@
1
1
  class ProconBypassMan::SendReloadConfigEventCommand
2
2
  # @return [void]
3
3
  def self.execute
4
- puts "設定ファイルの再読み込みができました"
5
- ProconBypassMan.logger.info "設定ファイルの再読み込みができました"
4
+ ProconBypassMan::PrintMessageCommand.execute(text: "設定ファイルの再読み込みができました")
6
5
  ProconBypassMan::ReportReloadConfigJob.perform_async(
7
6
  ProconBypassMan.config.raw_setting
8
7
  )
@@ -1,4 +1,5 @@
1
1
  require "procon_bypass_man/commands/print_boot_message_command"
2
+ require "procon_bypass_man/commands/print_message_command"
2
3
  require "procon_bypass_man/commands/write_session_id_command"
3
4
  require "procon_bypass_man/commands/write_device_id_command"
4
5
  require "procon_bypass_man/commands/send_reload_config_event_command"
@@ -41,7 +41,7 @@ class ProconBypassMan::Configuration
41
41
  end
42
42
 
43
43
  attr_accessor :enable_critical_error_logging
44
- attr_writer :verbose_bypass_log, :raw_setting
44
+ attr_writer :verbose_bypass_log, :raw_setting, :enable_reporting_pressed_buttons
45
45
 
46
46
  def root=(path)
47
47
  @root = path
@@ -111,6 +111,33 @@ class ProconBypassMan::Configuration
111
111
  @server_pool ||= ProconBypassMan::ServerPool.new(servers: api_servers)
112
112
  end
113
113
 
114
+ # @return [String, NilClass]
115
+ def current_server
116
+ server_pool.server
117
+ end
118
+
119
+ # @return [String, NilClass]
120
+ def current_ws_server
121
+ if (uri = URI.parse(server_pool.server))
122
+ if uri.port == 443
123
+ return "ws://#{uri.host}"
124
+ else
125
+ return "ws://#{uri.host}:#{uri.port}"
126
+ end
127
+ end
128
+ rescue URI::InvalidURIError
129
+ nil
130
+ end
131
+
132
+ # @return [String, NilClass]
133
+ def current_ws_server_url
134
+ return unless current_ws_server
135
+ "#{current_ws_server}/websocket/"
136
+ end
137
+
138
+ # @return [Boolean]
139
+ def enable_ws?; !!current_server; end
140
+
114
141
  # @return [Array<String>]
115
142
  def api_servers
116
143
  if !!ENV["API_SERVER"]
@@ -127,4 +154,8 @@ class ProconBypassMan::Configuration
127
154
  def raw_setting
128
155
  @raw_setting ||= {}
129
156
  end
157
+
158
+ def enable_reporting_pressed_buttons
159
+ @enable_reporting_pressed_buttons ||= false
160
+ end
130
161
  end
@@ -0,0 +1,25 @@
1
+ class ProconBypassMan::Domains::Binary::Base
2
+ # @param [String] binary
3
+ def initialize(binary: )
4
+ @binary = binary
5
+ end
6
+
7
+ # @return [String] バイナリ
8
+ def binary
9
+ raise NotImplementedError
10
+ end
11
+
12
+ # @return [String]
13
+ def raw
14
+ binary
15
+ end
16
+
17
+ def unpack
18
+ binary.unpack("H*")
19
+ end
20
+
21
+ # @return [ProconBypassMan::ProconReader]
22
+ def to_procon_reader
23
+ ProconBypassMan::ProconReader.new(binary: binary)
24
+ end
25
+ end
@@ -0,0 +1,5 @@
1
+ module ProconBypassMan::Domains::HasImmutableBinary
2
+ def binary
3
+ @binary.freeze
4
+ end
5
+ end
@@ -0,0 +1,5 @@
1
+ module ProconBypassMan::Domains::HasMutableBinary
2
+ def binary
3
+ @binary
4
+ end
5
+ end
@@ -0,0 +1,9 @@
1
+ # proconから取得したばかりのバイナリ
2
+ class ProconBypassMan::Domains::InboundProconBinary < ProconBypassMan::Domains::Binary::Base
3
+ include ProconBypassMan::Domains::HasImmutableBinary
4
+
5
+ # @return [Boolean]
6
+ def user_operation_data?
7
+ binary[0] == "\x30".b
8
+ end
9
+ end
@@ -0,0 +1,66 @@
1
+ # バイナリの書き換えのみをする
2
+ class ProconBypassMan::Domains::ProcessingProconBinary < ProconBypassMan::Domains::Binary::Base
3
+ include ProconBypassMan::Domains::HasMutableBinary
4
+
5
+ ALL_ZERO_BIT = ["0"].pack("H*").freeze
6
+
7
+ def set_no_action!
8
+ binary[3] = ALL_ZERO_BIT
9
+ binary[4] = ALL_ZERO_BIT
10
+ binary[5] = ALL_ZERO_BIT
11
+ end
12
+
13
+ # @param [ProconBypassMan::Domains::ProcessingProconBinary]
14
+ # @return [ProconBypassMan::Domains::ProcessingProconBinary]
15
+ # アナログスティックは上書きし、ボタンだけマージする
16
+ def write_as_merge!(target_binary)
17
+ current_buttons = ProconBypassMan::ProconReader.new(binary: binary).pressing
18
+ target_buttons = ProconBypassMan::ProconReader.new(binary: target_binary.raw).pressing
19
+
20
+ set_no_action!
21
+ (current_buttons + target_buttons).uniq.each do |button|
22
+ write_as_press_button(button)
23
+ end
24
+
25
+ # override analog stick
26
+ tb = [target_binary.raw].pack("H*")
27
+ binary[6] = tb[6]
28
+ binary[7] = tb[7]
29
+ binary[8] = tb[8]
30
+ binary[9] = tb[9]
31
+ binary[10] = tb[10]
32
+ binary[11] = tb[11]
33
+
34
+ self
35
+ end
36
+
37
+ # @param [Symbol] button
38
+ def write_as_press_button(button)
39
+ raise "already pressing button(#{button})" if ProconBypassMan::PressButtonAware.new(binary).pressing_button?(button)
40
+
41
+ button_obj = ProconBypassMan::Procon::Button.new(button)
42
+ value = binary[button_obj.byte_position].unpack("C").first + (2**button_obj.bit_position)
43
+ binary[button_obj.byte_position] = ["%02X" % value.to_s].pack("H*")
44
+ end
45
+
46
+ # @param [Symbol] button
47
+ def write_as_unpress_button(button)
48
+ raise "not press button(#{button}) yet" if not ProconBypassMan::PressButtonAware.new(binary).pressing_button?(button)
49
+
50
+ button_obj = ProconBypassMan::Procon::Button.new(button)
51
+ value = binary[button_obj.byte_position].unpack("C").first - (2**button_obj.bit_position)
52
+ binary[button_obj.byte_position] = ["%02X" % value.to_s].pack("H*")
53
+ end
54
+
55
+ # @param [Symbol] button
56
+ def write_as_press_button_only(button)
57
+ set_no_action!
58
+ write_as_press_button(button)
59
+ end
60
+
61
+ # @param [Integer] cap
62
+ def write_as_apply_left_analog_stick_cap(cap: )
63
+ analog_stick_cap = ProconBypassMan::Procon::AnalogStickCap.new(binary)
64
+ binary[6..8] = analog_stick_cap.capped_position(cap_hypotenuse: cap).to_binary
65
+ end
66
+ end
@@ -0,0 +1,11 @@
1
+ module ProconBypassMan
2
+ module Domains
3
+ module Binary; end
4
+ end
5
+ end
6
+
7
+ require_relative "domains/binary/base"
8
+ require_relative "domains/binary/has_mutable_binary"
9
+ require_relative "domains/binary/has_immutable_binary"
10
+ require_relative "domains/binary/inbound_procon_binary"
11
+ require_relative "domains/binary/processing_procon_binary"
@@ -3,7 +3,7 @@ module ProconBypassMan
3
3
  module Splatoon2
4
4
  module Macro
5
5
  module FastReturn
6
- def self.name
6
+ def self.display_name
7
7
  :fast_return
8
8
  end
9
9
 
@@ -3,7 +3,7 @@ module ProconBypassMan
3
3
  module Splatoon2
4
4
  module Macro
5
5
  module JumpToLeftKey
6
- def self.name
6
+ def self.display_name
7
7
  :jump_to_left_key
8
8
  end
9
9
 
@@ -3,7 +3,7 @@ module ProconBypassMan
3
3
  module Splatoon2
4
4
  module Macro
5
5
  module JumpToRightKey
6
- def self.name
6
+ def self.display_name
7
7
  :jump_to_right_key
8
8
  end
9
9
 
@@ -3,7 +3,7 @@ module ProconBypassMan
3
3
  module Splatoon2
4
4
  module Macro
5
5
  module JumpToUpKey
6
- def self.name
6
+ def self.display_name
7
7
  :jump_to_up_key
8
8
  end
9
9
 
@@ -0,0 +1,22 @@
1
+ module ProconBypassMan
2
+ module Plugin
3
+ module Splatoon2
4
+ module Macro
5
+ module SokuwariForSplashBomb
6
+ def self.display_name
7
+ :sokuwari_for_splash_bomb
8
+ end
9
+
10
+ # procon_bypass_man: 0.1.18以上が必要
11
+ def self.steps
12
+ [ :toggle_r_for_0_2sec,
13
+ :toggle_thumbr_for_0_14sec,
14
+ :toggle_thumbr_and_toggle_zr_for_0_34sec,
15
+ :toggle_r_for_1sec,
16
+ ].freeze
17
+ end
18
+ end
19
+ end
20
+ end
21
+ end
22
+ end
@@ -3,7 +3,7 @@
3
3
  module ProconBypassMan
4
4
  module Plugin
5
5
  module Splatoon2
6
- VERSION = "0.1.2"
6
+ VERSION = "0.1.3"
7
7
  end
8
8
  end
9
9
  end