procon_bypass_man 0.1.20.2 → 0.1.21

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 (33) hide show
  1. checksums.yaml +4 -4
  2. data/.circleci/config.yml +0 -5
  3. data/.github/workflows/ruby.yml +1 -1
  4. data/.rspec +1 -0
  5. data/CHANGELOG.md +16 -1
  6. data/Gemfile.lock +1 -1
  7. data/docs/getting_started.md +12 -7
  8. data/docs/setting/splatoon2_macro_dasei_cancel.md +73 -0
  9. data/lib/procon_bypass_man/buttons_setting_configuration/layer.rb +28 -5
  10. data/lib/procon_bypass_man/buttons_setting_configuration.rb +1 -1
  11. data/lib/procon_bypass_man/bypass.rb +0 -1
  12. data/lib/procon_bypass_man/domains/binary/processing_procon_binary.rb +1 -1
  13. data/lib/procon_bypass_man/{bypass → domains}/bypass_mode.rb +0 -0
  14. data/lib/procon_bypass_man/domains.rb +1 -0
  15. data/lib/procon_bypass_man/plugin/splatoon2/macro/dasei_cancel.rb +21 -0
  16. data/lib/procon_bypass_man/plugins.rb +1 -0
  17. data/lib/procon_bypass_man/procon/button_collection.rb +0 -8
  18. data/lib/procon_bypass_man/procon/macro.rb +48 -23
  19. data/lib/procon_bypass_man/procon/macro_builder.rb +31 -21
  20. data/lib/procon_bypass_man/procon/macro_registry.rb +7 -2
  21. data/lib/procon_bypass_man/procon/user_operation.rb +1 -1
  22. data/lib/procon_bypass_man/procon/value_objects/analog_stick.rb +9 -5
  23. data/lib/procon_bypass_man/procon.rb +32 -12
  24. data/lib/procon_bypass_man/support/analog_stick_hypotenuse_tilting_power_scaler.rb +59 -0
  25. data/lib/procon_bypass_man/{never_exit_accidentally.rb → support/never_exit_accidentally.rb} +0 -0
  26. data/lib/procon_bypass_man/version.rb +1 -1
  27. data/lib/procon_bypass_man/websocket/forever.rb +47 -0
  28. data/lib/procon_bypass_man/websocket/pbm_job_client.rb +3 -6
  29. data/lib/procon_bypass_man/websocket/watchdog.rb +19 -0
  30. data/lib/procon_bypass_man.rb +4 -1
  31. data/project_template/app.rb +1 -1
  32. data/sig/main.rbs +20 -0
  33. metadata +9 -4
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: b74bbbe94f6c14a8e8cfbabb306e7229cab042ea9d5fae34ddfe134df0911528
4
- data.tar.gz: b42ea9a421add0181270f5c957c9d10079598871634f5f20da8e7101349c981e
3
+ metadata.gz: 44670b11efa75a8b57df0580f3c796d65419ec87914d8458ab0fc426527fb58b
4
+ data.tar.gz: 883add3b8224f5490ba62ab2caabbb42b251a86197080bb7f8d3f219c89d465c
5
5
  SHA512:
6
- metadata.gz: df4ce5c1fc721fe5aa06236a0909c143f49b3616b4c02ca4202f0de7519206a22f5de864e58e50390e47dfe631475cdf1a04c3b4e99ed492913825cf0315039f
7
- data.tar.gz: 8fed8f7f1181bfb51b6b214984af09b0bc1d8b83573174fa276e97e857a0569affb14148aeabf52f0ba3b90cc30083548c191346649e8c534832fcba3b6aee25
6
+ metadata.gz: f9cf91dc93c58559217332670431f901a7eae8923476b26e63aca0908f52e3bdea1122df4fe00f533e80e556f91caa173c52dc27661c9ced4049fd7cbbc8f712
7
+ data.tar.gz: 17cf3cdaa06556ca4debb6ab7697a6946b6de69d197b8f9f217c1bd0786aa525c2fd8fb673ad81df089c08689bc8b238d1d8fbdea1b9c41a55684b32bca970db
data/.circleci/config.yml CHANGED
@@ -96,7 +96,6 @@ build_jobs: &build_jobs
96
96
  matrix:
97
97
  parameters:
98
98
  ruby-version:
99
- - "2.7"
100
99
  - "3.0.1"
101
100
  - "3.0.2"
102
101
  - "3.1.1"
@@ -104,7 +103,6 @@ build_jobs: &build_jobs
104
103
  matrix:
105
104
  parameters:
106
105
  ruby-version:
107
- - "2.7"
108
106
  - "3.0.1"
109
107
  - "3.0.2"
110
108
  - "3.1.1"
@@ -112,7 +110,6 @@ build_jobs: &build_jobs
112
110
  matrix:
113
111
  parameters:
114
112
  ruby-version:
115
- - "2.7"
116
113
  - "3.0.1"
117
114
  - "3.0.2"
118
115
  - "3.1.1"
@@ -122,7 +119,6 @@ build_jobs: &build_jobs
122
119
  matrix:
123
120
  parameters:
124
121
  ruby-version:
125
- - "2.7"
126
122
  # - "3.0.1" # たまにSEGVするので
127
123
  - "3.0.2"
128
124
  - "3.1.1"
@@ -132,7 +128,6 @@ build_jobs: &build_jobs
132
128
  matrix:
133
129
  parameters:
134
130
  ruby-version:
135
- - "2.7"
136
131
  - "3.0.1"
137
132
  - "3.0.2"
138
133
  - "3.1.1"
@@ -16,7 +16,7 @@ jobs:
16
16
  runs-on: ubuntu-latest
17
17
  strategy:
18
18
  matrix:
19
- ruby-version: ['2.7', '3.0.1']
19
+ ruby-version: ['3.0.1', '3.1.1']
20
20
 
21
21
  steps:
22
22
  - uses: actions/checkout@v2
data/.rspec CHANGED
@@ -1 +1,2 @@
1
1
  --require spec_helper
2
+ -f d
data/CHANGELOG.md CHANGED
@@ -1,4 +1,19 @@
1
- ## [0.1.20.2] - 2022-2-18
1
+ ## [0.1.21] - 2022-03-03
2
+ - install_macro_pluginしていないマクロをlayer内で使うとクラッシュしていた問題を修正しました
3
+ - 数十時間起動しっぱなしだとpbm-cloudとのwebsocketの接続が切断される問題を修正しました
4
+ - 誤発動を防ぐために、マクロを無効にする設定ができるようになりました
5
+ - すべてのマクロを無効にする
6
+ - disable_macro :all
7
+ - disable_macro :all, if_pressed: [:a]
8
+ - 特定のマクロを無効にする
9
+ - disable_macro TheMacro
10
+ - disable_macro TheMacro, if_pressed: [:a]
11
+ - スティックを傾けたタイミングでマクロを発動するオプションを実装しました
12
+ - これによってスプラトゥーン2の惰性キャンセルができるようになります
13
+ - ただし、精度がイマイチなので今後改善していきます
14
+ - 詳しくは `スプラトゥーン2: 惰性キャンセル マクロの設定方法` を参照してください
15
+
16
+ ## [0.1.20.2] - 2022-02-18
2
17
  - 起動時にreniceするようにしました
3
18
  - 起動時にusb gadgetモードを有効にするようにしました
4
19
  - pbm-cloudからprocon_bypass_manをアップグレードできるようになりました
data/Gemfile.lock CHANGED
@@ -1,7 +1,7 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- procon_bypass_man (0.1.20.2)
4
+ procon_bypass_man (0.1.21)
5
5
  action_cable_client
6
6
  pbmenv (>= 0.1.9)
7
7
  sorted_set
@@ -12,12 +12,12 @@
12
12
  * レイヤー
13
13
  * モード
14
14
  * マクロ
15
- * 左スティックの感度調整
15
+ * [左スティックの感度調整](#左スティックの感度調整)
16
16
  * 設定ファイルの書き方
17
17
  * プラグインの書き方
18
- * 設定ファイルの書き方がわからない、エラーが起きるとき
18
+ * [設定ファイルの書き方がわからない、エラーが起きるとき](#設定ファイルの書き方がわからない、エラーが起きるとき)
19
19
  * [procon_bypass_manのアップグレード方法](#procon_bypass_manのアップグレード方法)
20
- * procon_bypass_man_cloudについて
20
+ * [procon_bypass_man_cloudについて](#procon_bypass_man_cloudについて)
21
21
 
22
22
  ## はじめに
23
23
  ### procon_bypass_manで解決したいこと
@@ -96,7 +96,7 @@ pbmenvを使っていない場合は、 https://github.com/splaplapla/procon_byp
96
96
  * 後で書きます
97
97
 
98
98
  ## 左スティックの感度調整
99
- * 後で書きます
99
+ [左スティックの感度調整](/docs/setting/left-analogstick-cap.md)
100
100
 
101
101
  ## 設定ファイルの書き方
102
102
  * 後で書きます
@@ -106,11 +106,16 @@ pbmenvを使っていない場合は、 https://github.com/splaplapla/procon_byp
106
106
 
107
107
  ## 設定ファイルの書き方がわからない、エラーが起きるとき
108
108
 
109
- 設定部分は、Rubyスクリプトになっているので構文エラーが起きることがあります。
109
+ 設定ファイル(setting.yaml)は、内部がRubyスクリプトになっているので構文エラーが起きることがあります。
110
110
  discordで質問してみてください。
111
111
 
112
112
  ## procon_bypass_manのアップグレード方法
113
- [/docs/upgrade_pbm.md](/docs/upgrade_pbm.md)
113
+ [procon_bypass_manのアップグレード方法](/docs/upgrade_pbm.md)
114
114
 
115
115
  ## procon_bypass_man_cloudについて
116
- * 後で書きます
116
+ https://pbm-cloud.herokuapp.com/
117
+ procon_bypass_man_cloudの運用をWEBで完結できるようになる無料のWEBサービスです。
118
+
119
+ procon_bypass_man_cloudとの接続が完了後、Raspberry Piを起動時にprocon_bypass_man_cloudが自動で立ち上がるように設定すれば、Raspberry Piへのログインが不要で設定ファイルの変更やprocon_bypass_man_cloudのアップグレードができます。
120
+ セットアップ方法などでわからないことがあればdiscordで質問してみてください。
121
+ セットアップ方法は https://pbm-cloud.herokuapp.com/faq に書いています。
@@ -0,0 +1,73 @@
1
+ # スプラトゥーン2: 惰性キャンセル マクロの設定方法
2
+
3
+ * 本マクロは実験段階で、オプション名などの仕様が変更される可能性が高いです
4
+ * procon_bypass_man: 0.1.21以上が必要です
5
+
6
+ ## 1. install_macro_pluginでマクロを有効化します
7
+ * `setting.yml` に`install_macro_plugin ProconBypassMan::Plugin::Splatoon2::Macro::DaseiCancel` と書きます
8
+ * これを記述することで、layer内でmacroを呼び出せるようになります
9
+
10
+ ```ruby
11
+ install_macro_plugin ProconBypassMan::Plugin::Splatoon2::Macro::DaseiCancel
12
+ ```
13
+
14
+ ## 2. どのlayerで発動するかを宣言します
15
+ * `setting.yml` のlayer内に`macro ProconBypassMan::Plugin::Splatoon2::Macro::DaseiCancel, if_pressed: [:zl]` と書きます
16
+ * `if_pressed` がどのボタンを押したときにこのマクロが発動するかの設定です
17
+ * 惰性キャンセルなのでイカ状態になるためにzlを押します
18
+ * `if_tilted_left_stick` がスティックを倒した時に発動するオプションで、trueを渡すと有効になります
19
+ * また、傾けた時の閾値を変更することができて、trueの代わりに `{ threshold: 500 }` と書くことができます
20
+ * デフォルトが500で、ここの数値を上げると、スティックを倒した判定がより厳しくなります。最大1400くらいです。
21
+ * 連打中に、マクロの発動を無効にしたい場合は `disable_macro` で無効にできます
22
+
23
+ ```ruby
24
+ layer :up do
25
+ macro ProconBypassMan::Plugin::Splatoon2::Macro::DaseiCancel, if_tilted_left_stick: true, if_pressed: [:zl]
26
+ end
27
+ ```
28
+ ```ruby
29
+ layer :up do
30
+ macro ProconBypassMan::Plugin::Splatoon2::Macro::DaseiCancel, if_tilted_left_stick: { threshold: 500 }, if_pressed: [:zl]
31
+ end
32
+ ```
33
+ ```ruby
34
+ layer :up do
35
+ disable_macro :all, if_pressed: :a
36
+ disable_macro :all, if_pressed: :zr
37
+ macro ProconBypassMan::Plugin::Splatoon2::Macro::DaseiCancel, if_tilted_left_stick: true, if_pressed: [:zl]
38
+ end
39
+ ```
40
+
41
+ ## 3. 設定を反映させる
42
+ * 上記の記述を加えたsetting.ymlを起動中のprocon_bypass_manプロセスで読み込むには、プロセスにその旨を伝える必要があります
43
+ * ラズベリーパイを再起動して、プロセスを立ち上げ直す、でも目的は達成できますが、もっと簡単にsetting.ymlを再読み込みする必要があります
44
+ * 書き換えたsetting.ymlを、起動中のprocon_bypass_manプロセスへ即時反映するには、procon_bypass_manプロセスを動かしたまま、別のshellから 以下をを実行してください
45
+ * setting.ymlのシンタックスが正しければ、switchとの接続が継続したままsetting.ymlの内容を読み込んでいるはずです
46
+
47
+ ## 設定例1
48
+ ```yaml
49
+ version: 1.0
50
+ setting: |-
51
+ prefix_keys_for_changing_layer [:zr, :zl, :l]
52
+ install_macro_plugin ProconBypassMan::Plugin::Splatoon2::Macro::DaseiCancel
53
+
54
+ layer :up do
55
+ disable_macro :all, if_pressed: :a
56
+ disable_macro :all, if_pressed: :zr
57
+ macro ProconBypassMan::Plugin::Splatoon2::Macro::DaseiCancel, if_tilted_left_stick: true, if_pressed: [:zl]
58
+ end
59
+ ```
60
+
61
+ ## 設定例2
62
+ * `open_macro` キーワードを使っても同じことが実行可能です。
63
+ * この場合は、 `install_macro_plugin` が不要です。
64
+
65
+ ```yaml
66
+ version: 1.0
67
+ setting: |-
68
+ prefix_keys_for_changing_layer [:zr, :zl, :l]
69
+
70
+ layer :up do
71
+ open_macro :dacan, steps: [:pressing_r_for_0_03sec, :pressing_r_and_pressing_zl_for_0_2sec], if_tilted_left_stick: true, if_pressed: [:zl]
72
+ end
73
+ ```
@@ -1,12 +1,13 @@
1
1
  module ProconBypassMan
2
2
  class ButtonsSettingConfiguration
3
3
  class Layer
4
- attr_accessor :mode, :flips, :macros, :remaps, :left_analog_stick_caps, :disables
4
+ attr_accessor :mode, :flips, :macros, :disable_macros, :remaps, :left_analog_stick_caps, :disables
5
5
 
6
6
  def initialize(mode: :manual)
7
7
  self.mode = mode
8
8
  self.flips = {}
9
9
  self.macros = {}
10
+ self.disable_macros = []
10
11
  self.remaps = {}
11
12
  self.left_analog_stick_caps = []
12
13
  self.disables = []
@@ -54,18 +55,40 @@ module ProconBypassMan
54
55
  end
55
56
 
56
57
  # @param [String, Class] プラグインのclass
57
- def macro(name, if_pressed: )
58
+ def macro(name, if_pressed: , if_tilted_left_stick: nil)
58
59
  macro_name = name.to_s.to_sym
59
- self.macros[macro_name] = { if_pressed: if_pressed }
60
+ if ProconBypassMan::ButtonsSettingConfiguration.instance.macro_plugins[macro_name]
61
+ self.macros[macro_name] = { if_pressed: if_pressed, if_tilted_left_stick: if_tilted_left_stick }.compact
62
+ else
63
+ warn "#{macro_name}マクロがinstallされていません"
64
+ end
60
65
  end
61
66
 
62
67
  # 設定ファイルに直接マクロを打ち込める
63
68
  # @param [String, Class] macroの識別子
64
69
  # @paramh[Array<Symbol>] macroの本体. ボタンの配列
65
- def open_macro(name, steps: , if_pressed: )
70
+ def open_macro(name, steps: , if_pressed: , if_tilted_left_stick: nil)
66
71
  macro_name = name || "OpenMacro-#{steps.join}".to_sym
67
72
  ProconBypassMan::Procon::MacroRegistry.install_plugin(macro_name, steps: steps)
68
- self.macros[macro_name] = { if_pressed: if_pressed }
73
+ self.macros[macro_name] = { if_pressed: if_pressed, if_tilted_left_stick: if_tilted_left_stick }.compact
74
+ end
75
+
76
+ def disable_macro(name, if_pressed: nil)
77
+ hash = { name: name.to_s.to_sym, if_pressed: [] }
78
+ case if_pressed
79
+ when TrueClass, FalseClass
80
+ return # booleanはよくわからないのでreturn
81
+ when Symbol, String
82
+ hash[:if_pressed] = [if_pressed]
83
+ when Array
84
+ hash[:if_pressed] = if_pressed
85
+ when NilClass # 常に対象のmacroをdisableにする
86
+ hash[:if_pressed] = [true]
87
+ else
88
+ raise "not support value"
89
+ end
90
+
91
+ disable_macros << hash
69
92
  end
70
93
 
71
94
  def remap(button, to: )
@@ -65,7 +65,7 @@ module ProconBypassMan
65
65
  end
66
66
 
67
67
  unless ([ManualMode.name] + ProconBypassMan::Procon::ModeRegistry.plugins.keys).include?(mode_name)
68
- raise("#{mode_name} mode is unknown")
68
+ warn "#{mode_name}モードがinstallされていません"
69
69
  end
70
70
 
71
71
  layer = Layer.new(mode: mode_name)
@@ -1,5 +1,4 @@
1
1
  require "procon_bypass_man/bypass/usb_hid_logger"
2
- require "procon_bypass_man/bypass/bypass_mode"
3
2
 
4
3
  class ProconBypassMan::Bypass
5
4
  include ProconBypassMan::Bypass::UsbHidLogger
@@ -45,7 +45,7 @@ class ProconBypassMan::Domains::ProcessingProconBinary < ProconBypassMan::Domain
45
45
 
46
46
  # @param [Symbol] button
47
47
  def write_as_unpress_button(button)
48
- raise "not press button(#{button}) yet" if not ProconBypassMan::PressButtonAware.new(binary).pressing_button?(button)
48
+ raise "do not press button(#{button}) yet" if not ProconBypassMan::PressButtonAware.new(binary).pressing_button?(button)
49
49
 
50
50
  button_obj = ProconBypassMan::Procon::Button.new(button)
51
51
  value = binary[button_obj.byte_position].unpack("C").first - (2**button_obj.bit_position)
@@ -4,6 +4,7 @@ module ProconBypassMan
4
4
  end
5
5
  end
6
6
 
7
+ require_relative "domains/bypass_mode"
7
8
  require_relative "domains/binary/base"
8
9
  require_relative "domains/binary/has_mutable_binary"
9
10
  require_relative "domains/binary/has_immutable_binary"
@@ -0,0 +1,21 @@
1
+ module ProconBypassMan
2
+ module Plugin
3
+ module Splatoon2
4
+ module Macro
5
+ module DaseiCancel
6
+ def self.display_name
7
+ :dasei_cancel
8
+ end
9
+
10
+ def self.steps
11
+ [:pressing_r_for_0_03sec, :pressing_r_and_pressing_zl_for_0_2sec].freeze
12
+ end
13
+
14
+ def self.description
15
+ '惰性キャンセル'
16
+ end
17
+ end
18
+ end
19
+ end
20
+ end
21
+ end
@@ -4,6 +4,7 @@ require_relative "plugin/splatoon2/macro/jump_to_right_key"
4
4
  require_relative "plugin/splatoon2/macro/jump_to_up_key"
5
5
  require_relative "plugin/splatoon2/macro/jump_to_left_key"
6
6
  require_relative "plugin/splatoon2/macro/sokuwari_for_splash_bomb"
7
+ require_relative "plugin/splatoon2/macro/dasei_cancel"
7
8
  require_relative "plugin/splatoon2/mode/guruguru"
8
9
 
9
10
  module ProconBypassMan
@@ -37,12 +37,4 @@ class ProconBypassMan::Procon::ButtonCollection
37
37
  BUTTONS = ProconBypassMan::Procon::ButtonCollection::BUTTONS_MAP.keys.freeze
38
38
 
39
39
  LEFT_ANALOG_STICK = { byte_position: 6..8 }
40
-
41
- # @param [Array<Symbol>] buttons
42
- # @return [Array<Symbol>]
43
- def self.normalize(buttons)
44
- buttons.select { |x|
45
- !!ProconBypassMan::Procon::ButtonCollection::BUTTONS_MAP[x]
46
- }
47
- end
48
40
  end
@@ -1,13 +1,51 @@
1
1
  class ProconBypassMan::Procon::Macro
2
- class NestedStep
2
+ class BaseNestedStep
3
3
  def initialize(value)
4
4
  @hash = value
5
+ end
6
+
7
+ private
8
+
9
+ def incr_step_index!
10
+ if step_index
11
+ @hash[:step_index] += 1
12
+ else
13
+ @hash[:step_index] = 0
14
+ end
15
+ end
16
+
17
+ def current_step
18
+ @hash[:steps][step_index]
19
+ end
20
+ end
21
+
22
+ class OnetimeNestedStep < BaseNestedStep
23
+ def over?
24
+ current_step.nil?
25
+ end
26
+
27
+ def next_step
28
+ step = current_step
29
+ incr_step_index!
30
+ step
31
+ end
32
+
33
+ private
34
+
35
+ def step_index
36
+ @hash[:step_index] ||= 0
37
+ end
38
+ end
39
+
40
+ class NestedStep < BaseNestedStep
41
+ def initialize(value)
42
+ super
5
43
  unless @hash[:end_at]
6
44
  @hash[:end_at] = (Time.now + @hash[:continue_for]).round(4)
7
45
  end
8
46
  end
9
47
 
10
- def over_end_at?
48
+ def over?
11
49
  (@hash[:end_at] < Time.now).tap do |result|
12
50
  if result
13
51
  ProconBypassMan.logger.debug { "[Macro] nested step is finished(#{@hash})" }
@@ -17,8 +55,6 @@ class ProconBypassMan::Procon::Macro
17
55
 
18
56
  def next_step
19
57
  incr_step_index!
20
-
21
- debug_incr_called_count!
22
58
  if step = current_step
23
59
  return step
24
60
  else
@@ -29,30 +65,13 @@ class ProconBypassMan::Procon::Macro
29
65
 
30
66
  private
31
67
 
32
- def current_step
33
- @hash[:steps][step_index]
34
- end
35
-
36
68
  def step_index
37
69
  @hash[:step_index]
38
70
  end
39
71
 
40
- def incr_step_index!
41
- if step_index
42
- @hash[:step_index] += 1
43
- else
44
- @hash[:step_index] = 0
45
- end
46
- end
47
-
48
72
  def reset_step_index!
49
73
  @hash[:step_index] = 0
50
74
  end
51
-
52
- def debug_incr_called_count!
53
- @hash[:debug_called_count] ||= 0
54
- @hash[:debug_called_count] += 1
55
- end
56
75
  end
57
76
 
58
77
  attr_accessor :name, :steps
@@ -69,8 +88,14 @@ class ProconBypassMan::Procon::Macro
69
88
  end
70
89
 
71
90
  if step.is_a?(Hash)
72
- nested_step = NestedStep.new(step)
73
- if nested_step.over_end_at?
91
+ nested_step =
92
+ if step[:continue_for]
93
+ NestedStep.new(step)
94
+ else
95
+ OnetimeNestedStep.new(step)
96
+ end
97
+
98
+ if nested_step.over?
74
99
  steps.shift # NestedStepを破棄する
75
100
  return next_step
76
101
  else
@@ -56,7 +56,7 @@ class ProconBypassMan::Procon::MacroBuilder
56
56
 
57
57
  # @return [Arary<Symbol>]
58
58
  def build
59
- steps = @steps.map { |step|
59
+ steps = @steps.flat_map { |step|
60
60
  if is_reserved?(step: step) || v1_format?(step: step)
61
61
  step.to_sym
62
62
  elsif value = build_if_v2_format?(step: step)
@@ -65,7 +65,8 @@ class ProconBypassMan::Procon::MacroBuilder
65
65
  nil
66
66
  end
67
67
  }
68
- steps.compact.flatten
68
+
69
+ steps.compact
69
70
  end
70
71
 
71
72
  private
@@ -81,31 +82,40 @@ class ProconBypassMan::Procon::MacroBuilder
81
82
  end
82
83
 
83
84
  def build_if_v2_format?(step: )
84
- # 時間指定なし
85
- if(match = step.match(%r!\Atoggle_(\w+)\z!)) && (button_candidate = match[1]) && is_button(button_candidate)
86
- button = button_candidate
87
- return [button.to_sym, :none]
88
- end
89
-
90
- # 時間指定あり
91
- if %r!^(pressing_|toggle_)! =~ step && (subjects = step.scan(%r!pressing_[^_]+|toggle_[^_]+!)) && (match = step.match(%r!_for_([\d_]+)(sec)?\z!))
92
- sec = match[1]
93
- return [
94
- { continue_for: to_num(sec),
95
- steps: SubjectMerger.merge(subjects.map { |x| Subject.new(x) }),
96
- }
97
- ]
98
- end
99
-
100
85
  # no-op command
101
86
  if(match = step.match(%r!wait_for_([\d_]+)(sec)?\z!))
102
87
  sec = match[1]
103
88
  return [
104
- { continue_for: to_num(sec),
89
+ { continue_for: to_f(sec),
105
90
  steps: [:none],
106
91
  }
107
92
  ]
108
93
  end
94
+
95
+ if %r!^(pressing_|toggle_)! =~ step && (subjects = step.scan(%r!pressing_[^_]+|toggle_[^_]+!)) && (match = step.match(%r!_for_([\d_]+)(sec)?\z!))
96
+ if sec = match[1]
97
+ return {
98
+ continue_for: to_f(sec),
99
+ steps: SubjectMerger.merge(subjects.map { |x| Subject.new(x) }).select { |x|
100
+ if x.is_a?(Array)
101
+ x.select { |y| is_button(y) || RESERVED_WORD_NONE == y }
102
+ else
103
+ is_button(x) || RESERVED_WORD_NONE == x
104
+ end
105
+ },
106
+ }
107
+ end
108
+ end
109
+
110
+ if %r!^(pressing_|toggle_)! =~ step && (subjects = step.scan(%r!pressing_[^_]+|toggle_[^_]+!))
111
+ return SubjectMerger.merge(subjects.map { |x| Subject.new(x) }).select { |x|
112
+ if x.is_a?(Array)
113
+ x.select { |y| is_button(y) || RESERVED_WORD_NONE == y }
114
+ else
115
+ is_button(x) || RESERVED_WORD_NONE == x
116
+ end
117
+ }
118
+ end
109
119
  end
110
120
 
111
121
  # @return [Boolean]
@@ -113,11 +123,11 @@ class ProconBypassMan::Procon::MacroBuilder
113
123
  !!ProconBypassMan::Procon::ButtonCollection::BUTTONS_MAP[step.to_sym]
114
124
  end
115
125
 
116
- def to_num(value)
126
+ def to_f(value)
117
127
  if value.include?("_")
118
128
  value.sub("_", ".").to_f
119
129
  else
120
- value.to_i
130
+ value.to_f
121
131
  end
122
132
  end
123
133
  end
@@ -13,9 +13,14 @@ class ProconBypassMan::Procon::MacroRegistry
13
13
  }
14
14
  end
15
15
 
16
+ # @return [ProconBypassMan::Procon::Macro]
16
17
  def self.load(name)
17
- steps = PRESETS[name] || plugins[name].call || raise("unknown macro")
18
- ProconBypassMan::Procon::Macro.new(name: name, steps: steps.dup)
18
+ if(steps = PRESETS[name] || plugins[name]&.call)
19
+ return ProconBypassMan::Procon::Macro.new(name: name, steps: steps.dup)
20
+ else
21
+ warn "installされていないマクロ(#{name})を使うことはできません"
22
+ return self.load(:null)
23
+ end
19
24
  end
20
25
 
21
26
  def self.reset!
@@ -62,7 +62,7 @@ class ProconBypassMan::Procon::UserOperation
62
62
  # @param [Symbol] button
63
63
  # @return [Boolean]
64
64
  def pressing_button?(button)
65
- ProconBypassMan::PressButtonAware.new(@binary.raw).pressing_button?(button)
65
+ pressing_all_buttons?([button])
66
66
  end
67
67
 
68
68
  # @param [Array<Symbol>] buttons
@@ -1,6 +1,6 @@
1
1
  class ProconBypassMan::Procon::AnalogStick
2
2
  attr_accessor :neutral_position
3
- attr_accessor :bin_x, :bin_y
3
+ attr_writer :bin_x, :bin_y
4
4
 
5
5
  def initialize(binary: )
6
6
  @neutral_position = ProconBypassMan::ButtonsSettingConfiguration.instance.neutral_position
@@ -13,18 +13,22 @@ class ProconBypassMan::Procon::AnalogStick
13
13
  end
14
14
 
15
15
  def abs_x
16
- bin_x.to_i(2)
16
+ @bin_x.to_i(2)
17
17
  end
18
18
 
19
19
  def abs_y
20
- bin_y.to_i(2)
20
+ @bin_y.to_i(2)
21
21
  end
22
22
 
23
23
  def relative_x
24
- bin_x.to_i(2) - neutral_position.x
24
+ @bin_x.to_i(2) - neutral_position.x
25
25
  end
26
26
 
27
27
  def relative_y
28
- bin_y.to_i(2) - neutral_position.y
28
+ @bin_y.to_i(2) - neutral_position.y
29
+ end
30
+
31
+ def relative_hypotenuse
32
+ Math.sqrt((relative_x**2) + (relative_y**2)).floor(6)
29
33
  end
30
34
  end
@@ -19,6 +19,7 @@ class ProconBypassMan::Procon
19
19
  ongoing_macro: MacroRegistry.load(:null),
20
20
  ongoing_mode: ModeRegistry.load(:manual),
21
21
  }
22
+ @@left_stick_tilting_power_scaler = ProconBypassMan::AnalogStickTiltingPowerScaler.new
22
23
  end
23
24
  reset!
24
25
 
@@ -38,6 +39,7 @@ class ProconBypassMan::Procon
38
39
  ProconBypassMan::ButtonsSettingConfiguration.instance.layers[current_layer_key]
39
40
  end
40
41
 
42
+ # 内部ステータスを書き換えるフェーズ
41
43
  def apply!
42
44
  layer_changer = ProconBypassMan::Procon::LayerChanger.new(binary: user_operation.binary)
43
45
  if layer_changer.change_layer?
@@ -46,10 +48,38 @@ class ProconBypassMan::Procon
46
48
  return
47
49
  end
48
50
 
49
- if ongoing_macro.finished?
51
+ analog_stick = ProconBypassMan::Procon::AnalogStick.new(binary: user_operation.binary.raw)
52
+ dumped_tilting_power = @@left_stick_tilting_power_scaler.add_sample(analog_stick.relative_hypotenuse)
53
+
54
+ enable_all_macro = true
55
+ enable_macro_map = Hash.new {|h,k| h[k] = true }
56
+ current_layer.disable_macros.each do |disable_macro|
57
+ if (disable_macro[:if_pressed] == [true] || user_operation.pressing_all_buttons?(disable_macro[:if_pressed]))
58
+ if disable_macro[:name] == :all
59
+ enable_all_macro = false
60
+ else
61
+ enable_macro_map[disable_macro[:name]] = false
62
+ end
63
+ end
64
+ end
65
+
66
+ if ongoing_macro.finished? && enable_all_macro
50
67
  current_layer.macros.each do |macro_name, options|
68
+ next unless enable_macro_map[macro_name]
69
+
70
+ if(if_tilted_left_stick_value = options[:if_tilted_left_stick])
71
+ threshold = (if_tilted_left_stick_value.is_a?(Hash) && if_tilted_left_stick_value[:threshold]) || ProconBypassMan::AnalogStickTiltingPowerScaler::DEFAULT_THRESHOLD
72
+ 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])
73
+ @@status[:ongoing_macro] = MacroRegistry.load(macro_name)
74
+ break
75
+ end
76
+
77
+ next
78
+ end
79
+
51
80
  if user_operation.pressing_all_buttons?(options[:if_pressed])
52
81
  @@status[:ongoing_macro] = MacroRegistry.load(macro_name)
82
+ break
53
83
  end
54
84
  end
55
85
  end
@@ -88,7 +118,7 @@ class ProconBypassMan::Procon
88
118
  status
89
119
  end
90
120
 
91
- # @return [ProconBypassMan::Domains::ProcessingProconBinary]
121
+ # @return [String]
92
122
  def to_binary
93
123
  if ongoing_mode.name != :manual
94
124
  return user_operation.binary.raw
@@ -143,14 +173,4 @@ class ProconBypassMan::Procon
143
173
 
144
174
  user_operation.binary.raw
145
175
  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
176
  end
@@ -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
@@ -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.21"
5
5
  end
@@ -0,0 +1,47 @@
1
+ module ProconBypassMan
2
+ module Websocket
3
+ class Forever
4
+ # 動作確認方法
5
+ # - 10秒ごとにrefreshするのでタイムアウトは起きない
6
+ # - ProconBypassMan::Websocket::Forever.run { loop { puts(:hi); sleep(10); ProconBypassMan::Websocket::Watchdog.active! } }
7
+ # - タイムアウトが起きること
8
+ # - ProconBypassMan::Websocket::Forever.run { puts(:hi); sleep(3000); }
9
+ # - ブロックを1回評価するとThreadが死ぬので100秒後にタイムアウトが起きること
10
+ # - ProconBypassMan::Websocket::Forever.run { puts(:hi); sleep(10); ProconBypassMan::Websocket::Watchdog.active! }
11
+ def self.run(&block)
12
+ loop do
13
+ new.run(&block)
14
+ end
15
+ end
16
+
17
+ def run(&block)
18
+ raise("need a block") unless block_given?
19
+
20
+ ws_thread = work_one(callable: block)
21
+ wait_and_kill_if_outdated(ws_thread)
22
+ end
23
+
24
+ # @return [Thread]
25
+ def work_one(callable: )
26
+ Thread.start do
27
+ callable.call
28
+ rescue => e
29
+ ProconBypassMan.logger.error("websocket client with forever: #{e.full_message}")
30
+ end
31
+ end
32
+
33
+ def wait_and_kill_if_outdated(thread)
34
+ loop do
35
+ if Watchdog.outdated?
36
+ Watchdog.active!
37
+ ProconBypassMan.logger.error("watchdog timeout!!")
38
+ thread.kill
39
+ return
40
+ end
41
+
42
+ sleep(10)
43
+ end
44
+ end
45
+ end
46
+ end
47
+ end
@@ -7,12 +7,7 @@ module ProconBypassMan
7
7
  return unless ProconBypassMan.config.enable_ws?
8
8
 
9
9
  Thread.start do
10
- loop do
11
- run
12
- rescue => e
13
- ProconBypassMan.logger.error("websocket client: #{e.full_message}")
14
- retry
15
- end
10
+ Forever.run { run }
16
11
  end
17
12
  end
18
13
 
@@ -55,6 +50,8 @@ module ProconBypassMan
55
50
  sleep 2
56
51
  }
57
52
  client.pinged { |msg|
53
+ Watchdog.active!
54
+
58
55
  ProconBypassMan.cache.fetch key: 'ws_pinged', expires_in: 10 do
59
56
  ProconBypassMan.logger.info('websocket client: pinged!!')
60
57
  ProconBypassMan.logger.info(msg)
@@ -0,0 +1,19 @@
1
+ module ProconBypassMan
2
+ module Websocket
3
+ class Watchdog
4
+ def self.outdated?
5
+ @@time < Time.now
6
+ end
7
+
8
+ def self.time
9
+ @@time
10
+ end
11
+
12
+ def self.active!
13
+ @@time = Time.now + 100
14
+ end
15
+
16
+ active!
17
+ end
18
+ end
19
+ end
@@ -25,11 +25,12 @@ require_relative "procon_bypass_man/support/report_http_client"
25
25
  require_relative "procon_bypass_man/support/update_remote_pbm_action_status_http_client"
26
26
  require_relative "procon_bypass_man/support/send_device_stats_http_client"
27
27
  require_relative "procon_bypass_man/support/server_pool"
28
+ require_relative "procon_bypass_man/support/analog_stick_hypotenuse_tilting_power_scaler"
29
+ require_relative "procon_bypass_man/support/never_exit_accidentally"
28
30
  require_relative "procon_bypass_man/background"
29
31
  require_relative "procon_bypass_man/commands"
30
32
  require_relative "procon_bypass_man/bypass"
31
33
  require_relative "procon_bypass_man/domains"
32
- require_relative "procon_bypass_man/never_exit_accidentally"
33
34
  require_relative "procon_bypass_man/device_connector"
34
35
  require_relative "procon_bypass_man/device_procon_finder"
35
36
  require_relative "procon_bypass_man/device_status"
@@ -47,6 +48,8 @@ require_relative "procon_bypass_man/remote_pbm_action/value_objects/remote_pbm_a
47
48
  require_relative "procon_bypass_man/scheduler"
48
49
  require_relative "procon_bypass_man/plugins"
49
50
  require_relative "procon_bypass_man/websocket/pbm_job_client"
51
+ require_relative "procon_bypass_man/websocket/watchdog"
52
+ require_relative "procon_bypass_man/websocket/forever"
50
53
 
51
54
  STDOUT.sync = true
52
55
  Thread.abort_on_exception = true
@@ -5,7 +5,7 @@ require 'bundler/inline'
5
5
  gemfile do
6
6
  source 'https://rubygems.org'
7
7
  git_source(:github) {|repo_name| "https://github.com/#{repo_name}" }
8
- gem 'procon_bypass_man', '0.1.20.2'
8
+ gem 'procon_bypass_man', '0.1.21'
9
9
  end
10
10
 
11
11
  ProconBypassMan.configure do |config|
data/sig/main.rbs CHANGED
@@ -531,6 +531,26 @@ module ProconBypassMan
531
531
  end
532
532
  end
533
533
 
534
+ class ProconBypassMan::BypassMode
535
+ TYPE_NORMAL: ::Symbol
536
+
537
+ TYPE_AGGRESSIVE: ::Symbol
538
+
539
+ TYPES: ::Array[::Symbol]
540
+
541
+ DEFAULT_GADGET_TO_PROCON_INTERVAL: ::Float
542
+
543
+ attr_accessor mode: ::Symbol
544
+
545
+ attr_accessor gadget_to_procon_interval: ::Float
546
+
547
+ def self.default_value: () -> ::ProconBypassMan::BypassMode
548
+
549
+ def initialize: (mode: ::Symbol mode, gadget_to_procon_interval: ::Float gadget_to_procon_interval) -> void
550
+
551
+ def to_s: () -> ::String
552
+ end
553
+
534
554
  class ProconBypassMan::Domains::Binary::Base
535
555
  # @param [String] binary
536
556
  def initialize: (binary: untyped binary) -> void
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: procon_bypass_man
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.20.2
4
+ version: 0.1.21
5
5
  platform: ruby
6
6
  authors:
7
7
  - jiikko
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2022-02-19 00:00:00.000000000 Z
11
+ date: 2022-03-03 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: pbmenv
@@ -79,6 +79,7 @@ files:
79
79
  - docs/getting_started.md
80
80
  - docs/how_to_connect_procon.md
81
81
  - docs/setting/left-analogstick-cap.md
82
+ - docs/setting/splatoon2_macro_dasei_cancel.md
82
83
  - docs/setting/splatoon2_macro_sokuwari_bubble.md
83
84
  - docs/setting/splatoon2_recommended_setting.md
84
85
  - docs/setup_raspi.md
@@ -110,7 +111,6 @@ files:
110
111
  - lib/procon_bypass_man/buttons_setting_configuration/loader.rb
111
112
  - lib/procon_bypass_man/buttons_setting_configuration/validator.rb
112
113
  - lib/procon_bypass_man/bypass.rb
113
- - lib/procon_bypass_man/bypass/bypass_mode.rb
114
114
  - lib/procon_bypass_man/bypass/usb_hid_logger.rb
115
115
  - lib/procon_bypass_man/commands.rb
116
116
  - lib/procon_bypass_man/commands/bypass_command.rb
@@ -132,8 +132,9 @@ files:
132
132
  - lib/procon_bypass_man/domains/binary/has_mutable_binary.rb
133
133
  - lib/procon_bypass_man/domains/binary/inbound_procon_binary.rb
134
134
  - lib/procon_bypass_man/domains/binary/processing_procon_binary.rb
135
+ - lib/procon_bypass_man/domains/bypass_mode.rb
135
136
  - lib/procon_bypass_man/io_monitor.rb
136
- - lib/procon_bypass_man/never_exit_accidentally.rb
137
+ - lib/procon_bypass_man/plugin/splatoon2/macro/dasei_cancel.rb
137
138
  - lib/procon_bypass_man/plugin/splatoon2/macro/fast_return.rb
138
139
  - lib/procon_bypass_man/plugin/splatoon2/macro/jump_to_left_key.rb
139
140
  - lib/procon_bypass_man/plugin/splatoon2/macro/jump_to_right_key.rb
@@ -168,9 +169,11 @@ files:
168
169
  - lib/procon_bypass_man/remote_pbm_action/value_objects/remote_pbm_action_object.rb
169
170
  - lib/procon_bypass_man/runner.rb
170
171
  - lib/procon_bypass_man/scheduler.rb
172
+ - lib/procon_bypass_man/support/analog_stick_hypotenuse_tilting_power_scaler.rb
171
173
  - lib/procon_bypass_man/support/callbacks.rb
172
174
  - lib/procon_bypass_man/support/compress_array.rb
173
175
  - lib/procon_bypass_man/support/http_client.rb
176
+ - lib/procon_bypass_man/support/never_exit_accidentally.rb
174
177
  - lib/procon_bypass_man/support/on_memory_cache.rb
175
178
  - lib/procon_bypass_man/support/report_http_client.rb
176
179
  - lib/procon_bypass_man/support/safe_timeout.rb
@@ -182,7 +185,9 @@ files:
182
185
  - lib/procon_bypass_man/support/yaml_writer.rb
183
186
  - lib/procon_bypass_man/usb_device_controller.rb
184
187
  - lib/procon_bypass_man/version.rb
188
+ - lib/procon_bypass_man/websocket/forever.rb
185
189
  - lib/procon_bypass_man/websocket/pbm_job_client.rb
190
+ - lib/procon_bypass_man/websocket/watchdog.rb
186
191
  - procon_bypass_man.gemspec
187
192
  - project_template/README.md
188
193
  - project_template/app.rb