procon_bypass_man 0.1.20.2 → 0.1.21
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.circleci/config.yml +0 -5
- data/.github/workflows/ruby.yml +1 -1
- data/.rspec +1 -0
- data/CHANGELOG.md +16 -1
- data/Gemfile.lock +1 -1
- data/docs/getting_started.md +12 -7
- data/docs/setting/splatoon2_macro_dasei_cancel.md +73 -0
- data/lib/procon_bypass_man/buttons_setting_configuration/layer.rb +28 -5
- data/lib/procon_bypass_man/buttons_setting_configuration.rb +1 -1
- data/lib/procon_bypass_man/bypass.rb +0 -1
- data/lib/procon_bypass_man/domains/binary/processing_procon_binary.rb +1 -1
- data/lib/procon_bypass_man/{bypass → domains}/bypass_mode.rb +0 -0
- data/lib/procon_bypass_man/domains.rb +1 -0
- data/lib/procon_bypass_man/plugin/splatoon2/macro/dasei_cancel.rb +21 -0
- data/lib/procon_bypass_man/plugins.rb +1 -0
- data/lib/procon_bypass_man/procon/button_collection.rb +0 -8
- data/lib/procon_bypass_man/procon/macro.rb +48 -23
- data/lib/procon_bypass_man/procon/macro_builder.rb +31 -21
- data/lib/procon_bypass_man/procon/macro_registry.rb +7 -2
- data/lib/procon_bypass_man/procon/user_operation.rb +1 -1
- data/lib/procon_bypass_man/procon/value_objects/analog_stick.rb +9 -5
- data/lib/procon_bypass_man/procon.rb +32 -12
- data/lib/procon_bypass_man/support/analog_stick_hypotenuse_tilting_power_scaler.rb +59 -0
- data/lib/procon_bypass_man/{never_exit_accidentally.rb → support/never_exit_accidentally.rb} +0 -0
- data/lib/procon_bypass_man/version.rb +1 -1
- data/lib/procon_bypass_man/websocket/forever.rb +47 -0
- data/lib/procon_bypass_man/websocket/pbm_job_client.rb +3 -6
- data/lib/procon_bypass_man/websocket/watchdog.rb +19 -0
- data/lib/procon_bypass_man.rb +4 -1
- data/project_template/app.rb +1 -1
- data/sig/main.rbs +20 -0
- metadata +9 -4
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 44670b11efa75a8b57df0580f3c796d65419ec87914d8458ab0fc426527fb58b
|
4
|
+
data.tar.gz: 883add3b8224f5490ba62ab2caabbb42b251a86197080bb7f8d3f219c89d465c
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
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"
|
data/.github/workflows/ruby.yml
CHANGED
data/.rspec
CHANGED
data/CHANGELOG.md
CHANGED
@@ -1,4 +1,19 @@
|
|
1
|
-
## [0.1.
|
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
data/docs/getting_started.md
CHANGED
@@ -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
|
-
|
109
|
+
設定ファイル(setting.yaml)は、内部がRubyスクリプトになっているので構文エラーが起きることがあります。
|
110
110
|
discordで質問してみてください。
|
111
111
|
|
112
112
|
## procon_bypass_manのアップグレード方法
|
113
|
-
[
|
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
|
-
|
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
|
-
|
68
|
+
warn "#{mode_name}モードがinstallされていません"
|
69
69
|
end
|
70
70
|
|
71
71
|
layer = Layer.new(mode: mode_name)
|
@@ -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)
|
File without changes
|
@@ -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
|
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
|
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 =
|
73
|
-
|
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.
|
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
|
-
|
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:
|
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
|
126
|
+
def to_f(value)
|
117
127
|
if value.include?("_")
|
118
128
|
value.sub("_", ".").to_f
|
119
129
|
else
|
120
|
-
value.
|
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]
|
18
|
-
|
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
|
-
|
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
|
-
|
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
|
-
|
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 [
|
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
|
data/lib/procon_bypass_man/{never_exit_accidentally.rb → support/never_exit_accidentally.rb}
RENAMED
File without changes
|
@@ -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
|
-
|
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)
|
data/lib/procon_bypass_man.rb
CHANGED
@@ -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
|
data/project_template/app.rb
CHANGED
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.
|
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-
|
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/
|
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
|