procon_bypass_man 0.1.19.1 → 0.1.20

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.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 51f609e2bfb3366e10ae0cf76380ad969416040b73e0a4d0db91f6df783f0264
4
- data.tar.gz: ea030a8b78a102b9ef8e6c12fab196b7aab2d2b91519f57e0dc63327ca57f4b1
3
+ metadata.gz: 1ce5a36623cb9c5ec02d78df78f1c50d8b6f23f54cedf4297bfe76d122def428
4
+ data.tar.gz: 6d459721f4dcbf4bde02c62e1ffb0aba296a39718e95d7cb5bbbbc6d27c845a3
5
5
  SHA512:
6
- metadata.gz: 074f5f69ce22021c0a1393883d0a7cc5c20437ba77206968d1041d18ace23938e586b760aa480a4deca8f8e85904cc36d728890affc669e793911575a3fd7f36
7
- data.tar.gz: f6240a68720f29e76a214a34015062f6c78ae3bb1c6691d6c3f39e70ae3c3b87823ec50412efb6fe84ad9611f005b3cf82d470bc8b87238c6213af031c5642aa
6
+ metadata.gz: 3a15285db88ece865db72a73d94f8f5dceff3958bc1fccd6422e5b63441e9c9f6238d080883220b934b14bd5d7a25ce0509cce00ca2995e7385dce90c8297584
7
+ data.tar.gz: f4cbd2665d0733016eb2311b95578360a6f111f847f32bf79a798b215d0e0a59d914fe743b4fd9c3fdeedb8e2d4fefdd3fc442de4c9c285fad7cf56f6a708b5a
data/CHANGELOG.md CHANGED
@@ -1,3 +1,11 @@
1
+ ## [0.1.20] - 2022-02-13
2
+ - pbm-cloudから再起動・設定ファイルの適用指示があったときにackイベントを返すようになりました
3
+ - 起動オプションにnever_exit_accidentallyを追加しました。これを有効にすると想定外のエラーが起きたときにプロセスが停止しなくなります。デフォルトで無効です。
4
+ - pbm-cloudから設定ファイルの適用に失敗したときにファイルへの書き込みをしないようになりました
5
+ - まだadd_procon_gadget.shを実行していないときに、接続処理をする前に処理を停止するようにしました
6
+ - ラズパイの複数のUSBデバイスが刺さっていてもプロコンのデバイスを選択できるようにしました
7
+ - Switchからプロコンへ送信するバイパスを動かし続けるようにしました(切断対策)
8
+
1
9
  ## [0.1.19.1] - 2022-02-09
2
10
  - 設定ファイルをpbm-cloudから復元するときに設定ファイルの改行コードが消える不具合を修正しました
3
11
 
data/Gemfile.lock CHANGED
@@ -1,7 +1,7 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- procon_bypass_man (0.1.19.1)
4
+ procon_bypass_man (0.1.20)
5
5
  action_cable_client
6
6
  pbmenv
7
7
  sorted_set
data/README.md CHANGED
@@ -7,6 +7,7 @@
7
7
  * 設定ファイルはrubyスクリプトで記述します
8
8
  * 特定のタイトルに特化した振る舞いにしたい時は各プラグインを使ってください
9
9
  * ドキュメントは [getting_started.md](docs/getting_started.md) にまとめています
10
+ * https://pbm-cloud.herokuapp.com を使うと、webだけで運用が可能です
10
11
 
11
12
  ![image](https://user-images.githubusercontent.com/1664497/123414210-942f6980-d5ee-11eb-8192-955bd9e37e0b.png)
12
13
 
@@ -50,17 +51,6 @@ Switch <-- (PBM): ZR連打
50
51
  ## Plugins
51
52
  * https://github.com/splaplapla/procon_bypass_man-splatoon2
52
53
 
53
- ## 関連ソフトウェア
54
- * procon_bypass_man_cloud
55
- * webアプリケーション
56
- * https://github.com/splaplapla/procon_bypass_man_cloud
57
- * このwebアプリからOS自体の再起動、設定ファイルのバックアップ・変更、PBMのバージョンアップができます
58
- * ご自身でホストティングもできますが、 私がホスティングをしている https://pbm-cloud.herokuapp.com を使うことができます
59
- * [使い方](https://pbm-cloud.herokuapp.com/faq)
60
- * pbmenv
61
- * procon_bypass_manのバージョンマネージャー
62
- * https://github.com/splaplapla/pbmenv
63
-
64
54
  ## FAQ
65
55
  * どうやって動かすの?
66
56
  * このツールはRaspberry Pi4をUSBガジェットモードで起動して有線でプロコンとSwitchに接続して使います
@@ -4,11 +4,10 @@
4
4
  * [procon_bypass_manで解決したいこと](#procon_bypass_manで解決したいこと)
5
5
  * [procon_bypass_manでできること](#procon_bypass_manでできること)
6
6
  * [セットアップ](#セットアップ)
7
- * ラズベリーパイのセットアップ
8
- * procon_bypass_manのインストール
9
- * pbmenvを使う方法
10
- * pbmenvを使わない方法
11
- * とりあえず動かす方法
7
+ * [ラズベリーパイのセットアップ](#ラズベリーパイのセットアップ)
8
+ * [procon_bypass_manのインストール](#procon_bypass_manのインストール)
9
+ * [pbmenvを使う方法](#pbmenvを使う方法)
10
+ * [pbmenvを使わない方法](#pbmenvを使わない方法)
12
11
  * [普段使いをするためのセットアップ](#普段使いをするためのセットアップ)
13
12
  * レイヤー
14
13
  * モード
@@ -18,6 +17,7 @@
18
17
  * layer
19
18
  * プラグインの書き方
20
19
  * 設定ファイルの書き方がわからない、エラーが起きるとき
20
+ * procon_bypass_manのアップグレード方法
21
21
  * procon_bypass_man_cloudについて
22
22
 
23
23
  ## はじめに
@@ -29,6 +29,7 @@
29
29
  このツールを使うことで、使い慣れたコントローラーを使ってボタン連射ができます。また、設定内容はテキストで管理しているため一目瞭然です。
30
30
 
31
31
  ### procon_bypass_manでできること
32
+
32
33
  * 設定内容を即時に入れ替え(レイヤー管理)
33
34
  * 連射
34
35
  * 連射中は特定のキーの入力を無視したり、複数のキーをトリガーに連射することもできます
@@ -41,8 +42,35 @@
41
42
  * ボタンリマップ
42
43
 
43
44
  ## セットアップ
45
+ ### ラズベリーパイのセットアップ
46
+
44
47
  * 後で書きます
45
48
 
49
+ ### procon_bypass_manのインストール
50
+
51
+ pbmenvを使うと https://pbm-cloud.herokuapp.com と連携ができるのでおすすめですが、pbmenvを使わなくてもprocon_bypass_manをインストールすることは可能です。
52
+
53
+ #### pbmenvを使う方法
54
+
55
+ https://github.com/splaplapla/pbmenv
56
+ pbmenvはprocon_bypass_manのバージョンマネジャーです。procon_bypass_manはバージョンアップによって起動スクリプトに変更が入ることがあって、バージョンアップするときはpbmenvを使うとエラーが起きることなくインストールができるようになります。また、pbm-cloudと連携してすべての機能を使うには、pbmenvの利用が必須になります。
57
+
58
+ ```
59
+ gem install pbmenv
60
+ sudo pbmenv install latest
61
+ cd /usr/share/pbm/current
62
+ sudo /home/pi/.rbenv/versions/3.0.1/bin/ruby app.rb
63
+ ```
64
+
65
+ #### pbmenvを使わない方法
66
+
67
+ https://github.com/jiikko/procon_bypass_man_sample にある app.rb と setting.yml を Raspberry Pi にダウンロードし、ruby 3.0.1 をインストールすれば起動することができます。
68
+
69
+ ```
70
+ rbenv install 3.0.1
71
+ sudo /home/pi/.rbenv/versions/3.0.1/bin/ruby app.rb
72
+ ```
73
+
46
74
  ## 普段使いをするためのセットアップ
47
75
 
48
76
  procon_bypass_manを起動するだけでプロコンと接続ができるようになったら、Raspberry Piを起動したときにprocon_bypass_manも自動起動するように設定しましょう。
@@ -1,16 +1,21 @@
1
1
  # スプラトゥーン2: おすすめの設定
2
- ## 全般
3
- ### 簡単スニーキング
2
+ ## 1 全般
3
+ ### 1.1 デスしてから最速スパジャンのためのAボタン連打
4
+
5
+ `flip :a, if_pressed: [:a]`
6
+ Aボタンを連打にします。復帰してから最速で前線復帰ができます
7
+
8
+ ### 1.2 簡単スニーキング
4
9
 
5
10
  ボタンを押している間は、水飛沫のたたないスニーキングの感度まで調整することができます。
6
11
  [設定方法](/docs/setting/left-analogstick-cap.md)
7
12
 
8
- ### ナイス玉連打
13
+ ### 1.3 ナイス玉連打
9
14
 
10
15
  `flip :down, if_pressed: :down`
11
16
  十字キーの下ボタンは常に連打にしておくとナイス玉が来たときに楽です。
12
17
 
13
- ### マクロでスーパージャンプ
18
+ ### 1.4 最速スーパージャンプ
14
19
 
15
20
  ```
16
21
  install_macro_plugin ProconBypassMan::Plugin::Splatoon2::Macro::FastReturn
@@ -18,7 +23,7 @@ install_macro_plugin ProconBypassMan::Plugin::Splatoon2::Macro::JumpToUpKey
18
23
  install_macro_plugin ProconBypassMan::Plugin::Splatoon2::Macro::JumpToRightKey
19
24
  install_macro_plugin ProconBypassMan::Plugin::Splatoon2::Macro::JumpToLeftKey
20
25
 
21
- layer :up, mode: :manual do
26
+ layer :up do
22
27
  macro ProconBypassMan::Plugin::Splatoon2::Macro::FastReturn, if_pressed: [:y, :b, :down]
23
28
  macro ProconBypassMan::Plugin::Splatoon2::Macro::JumpToUpKey, if_pressed: [:y, :b, :up]
24
29
  macro ProconBypassMan::Plugin::Splatoon2::Macro::JumpToRightKey, if_pressed: [:y, :b, :right]
@@ -26,15 +31,97 @@ layer :up, mode: :manual do
26
31
  end
27
32
  ```
28
33
 
29
- リスポーンや味方にスーパージャンプするマクロがあります。トリガーは自由に設定できます。
34
+ マップを開かずにジャンプができます。トリガーは自由に設定できます。
30
35
 
31
- ## 武器に特化した設定
32
- ### パブロ向け
36
+ ## 2 武器に特化した設定
37
+ ### 2.1 パブロ向け
33
38
 
34
39
  `flip :zr, if_pressed: :zr, force_neutral: :zl`
35
40
  zrを連打にします。`force_neutral: :zl` というオプションをつけることで、ZRを押している間はZLを押しても無視されるようになります。パブロでは意味がありませんが、シューターだと煽りのような動作を抑制することができます。
36
41
 
37
- ### ボトルガイザー(フォイル)向け
42
+ ### 2.2 ボトルガイザー(フォイル)向け
38
43
 
39
44
  バブル即割のマクロがあります。
40
45
  [設定方法](/docs/setting/splatoon2_macro_sokuwari_bubble.md)
46
+
47
+ ## 3 設定例
48
+ ### 3.1 シンプルなパブロ向け
49
+
50
+ * ZRボタン, ZLボタン, Lボタンを同時押しながら十字キーを押すとレイヤーを切り替える
51
+ * ナイス玉が来たときにゲージを貯めるために十字キーの下を連打
52
+ * 復帰から最速ジャンプのためにAボタンを連打
53
+ * 筆を振るためにZRボタンを連打
54
+ * 筆ダッシュをするためにLボタンをZRボタンに変更
55
+
56
+ ```yaml
57
+ version: 1.0
58
+ setting: |-
59
+ prefix_keys_for_changing_layer [:zr, :zl, :l]
60
+
61
+ layer :up do
62
+ flip :zr, if_pressed: :zr, force_neutral: :zl
63
+ flip :a, if_pressed: [:a]
64
+ flip :down, if_pressed: :down
65
+ remap :l, to: :zr
66
+ end
67
+
68
+ layer :right do
69
+ end
70
+
71
+ layer :left do
72
+ end
73
+
74
+ layer :down do
75
+ end
76
+ ```
77
+
78
+ ### 3.2 全部盛り
79
+
80
+ * ZRボタン, ZLボタン, Lボタンを同時押しながら十字キーを押すとレイヤーを切り替える
81
+ * ナイス玉が来たときにゲージを貯めるために十字キーの下を連打
82
+ * 筆を振るためにZRボタンを連打
83
+ * 復帰から最速ジャンプのためにAボタンを連打
84
+ * YボタンとBボタンと十字キーの上を同時に押したときに、マップ開いた時の↑に設定されている味方にスーパージャンプ
85
+ * YボタンとBボタンと十字キーの左を同時に押したときに、マップ開いた時の←に設定されている味方にスーパージャンプ
86
+ * YボタンとBボタンと十字キーの右を同時に押したときに、マップ開いた時の→に設定されている味方にスーパージャンプ
87
+ * YボタンとBボタンと十字キーの下を同時に押したときに、リスポーンにスーパージャンプ
88
+ * ZLボタンと十字キーの右ボタンを同時に、バブル即割を発動
89
+ * 筆ダッシュをするためにLボタンをZRボタンに変更
90
+ * ZLボタンとAボタンを同時に押したときに移動するとスニーキング
91
+
92
+ ```yaml
93
+ version: 1.0
94
+ setting: |-
95
+ install_macro_plugin ProconBypassMan::Plugin::Splatoon2::Macro::FastReturn
96
+ install_macro_plugin ProconBypassMan::Plugin::Splatoon2::Macro::JumpToUpKey
97
+ install_macro_plugin ProconBypassMan::Plugin::Splatoon2::Macro::JumpToRightKey
98
+ install_macro_plugin ProconBypassMan::Plugin::Splatoon2::Macro::JumpToLeftKey
99
+ install_macro_plugin ProconBypassMan::Plugin::Splatoon2::Macro::SokuwariForSplashBomb
100
+
101
+ prefix_keys_for_changing_layer [:zr, :zl, :l]
102
+ set_neutral_position 2100, 2000
103
+
104
+ layer :up do
105
+ flip :zr, if_pressed: :zr, force_neutral: :zl
106
+ flip :a, if_pressed: [:a]
107
+ flip :down, if_pressed: :down
108
+
109
+ macro ProconBypassMan::Plugin::Splatoon2::Macro::FastReturn, if_pressed: [:y, :b, :down]
110
+ macro ProconBypassMan::Plugin::Splatoon2::Macro::JumpToUpKey, if_pressed: [:y, :b, :up]
111
+ macro ProconBypassMan::Plugin::Splatoon2::Macro::JumpToRightKey, if_pressed: [:y, :b, :right]
112
+ macro ProconBypassMan::Plugin::Splatoon2::Macro::JumpToLeftKey, if_pressed: [:y, :b, :left]
113
+ macro ProconBypassMan::Plugin::Splatoon2::Macro::SokuwariForSplashBomb, if_pressed: [:zl, :right]
114
+
115
+ remap :l, to: :zr
116
+ left_analog_stick_cap cap: 1100, if_pressed: [:zl, :a], force_neutral: :a
117
+ end
118
+
119
+ layer :right do
120
+ end
121
+
122
+ layer :left do
123
+ end
124
+
125
+ layer :down do
126
+ end
127
+ ```
@@ -0,0 +1,11 @@
1
+ class ProconBypassMan::ReportErrorReloadConfigJob < ProconBypassMan::ReportEventBaseJob
2
+ extend ProconBypassMan::HasExternalApiSetting
3
+
4
+ # @param [String] body
5
+ def self.perform(body)
6
+ ProconBypassMan::ReportHttpClient.new(
7
+ path: path,
8
+ server_pool: server_pool,
9
+ ).post(body: body, event_type: :error_reload_config)
10
+ end
11
+ end
@@ -0,0 +1,10 @@
1
+ class ProconBypassMan::ReportStartRebootJob < ProconBypassMan::ReportEventBaseJob
2
+ extend ProconBypassMan::HasExternalApiSetting
3
+
4
+ def self.perform
5
+ ProconBypassMan::ReportHttpClient.new(
6
+ path: path,
7
+ server_pool: server_pool,
8
+ ).post(body: nil, event_type: :start_reboot)
9
+ end
10
+ end
@@ -6,7 +6,9 @@ require "procon_bypass_man/background/job_performer"
6
6
  require "procon_bypass_man/background/jobs/base_job"
7
7
  require "procon_bypass_man/background/jobs/report_event_base_job"
8
8
  require "procon_bypass_man/background/jobs/report_boot_job"
9
+ require "procon_bypass_man/background/jobs/report_start_reboot_job"
9
10
  require "procon_bypass_man/background/jobs/report_reload_config_job"
11
+ require "procon_bypass_man/background/jobs/report_error_reload_config_job"
10
12
  require "procon_bypass_man/background/jobs/report_load_config_job"
11
13
  require "procon_bypass_man/background/jobs/report_error_job"
12
14
  require "procon_bypass_man/background/jobs/report_pressed_buttons_job"
@@ -5,6 +5,8 @@ module ProconBypassMan
5
5
 
6
6
  # @return [ProconBypassMan::ButtonsSettingConfiguration]
7
7
  def self.load(setting_path: )
8
+ ProconBypassMan::ButtonsSettingConfiguration.instance.setting_path = setting_path
9
+
8
10
  ProconBypassMan::ButtonsSettingConfiguration.switch_new_context(:validation) do |new_instance|
9
11
  yaml = YAML.load_file(setting_path) or raise "読み込みに失敗しました"
10
12
  new_instance.instance_eval(yaml["setting"])
@@ -12,17 +14,19 @@ module ProconBypassMan
12
14
  if validator.valid?
13
15
  next
14
16
  else
15
- raise ProconBypassMan::CouldNotLoadConfigError, validator.errors
17
+ raise ProconBypassMan::CouldNotLoadConfigError, validator.errors_to_s
16
18
  end
17
19
  rescue SyntaxError
20
+ fallback_setting_if_has_backup(current_setting_path: setting_path)
18
21
  raise ProconBypassMan::CouldNotLoadConfigError, "Rubyスクリプトのシンタックスエラーです"
19
22
  rescue NoMethodError
23
+ fallback_setting_if_has_backup(current_setting_path: setting_path)
20
24
  raise ProconBypassMan::CouldNotLoadConfigError, "Rubyスクリプトに未定義の定数・変数があります"
21
25
  rescue Psych::SyntaxError
26
+ fallback_setting_if_has_backup(current_setting_path: setting_path)
22
27
  raise ProconBypassMan::CouldNotLoadConfigError, "yamlのシンタックスエラーです"
23
28
  end
24
29
 
25
- ProconBypassMan::ButtonsSettingConfiguration.instance.setting_path = setting_path
26
30
  ProconBypassMan::ButtonsSettingConfiguration.instance.reset!
27
31
  ProconBypassMan.reset!
28
32
 
@@ -38,12 +42,27 @@ module ProconBypassMan
38
42
 
39
43
  File.write(ProconBypassMan.digest_path, Digest::MD5.hexdigest(yaml["setting"]))
40
44
 
45
+ if File.exist?(ProconBypassMan.fallback_setting_path)
46
+ FileUtils.rm_rf(ProconBypassMan.fallback_setting_path)
47
+ end
48
+
41
49
  ProconBypassMan::ButtonsSettingConfiguration.instance
42
50
  end
43
51
 
44
52
  def self.reload_setting
45
53
  self.load(setting_path: ProconBypassMan::ButtonsSettingConfiguration.instance.setting_path)
46
54
  end
55
+
56
+ def self.fallback_setting_if_has_backup(current_setting_path: )
57
+ return unless File.exist?(ProconBypassMan.fallback_setting_path)
58
+ return if current_setting_path.nil?
59
+
60
+ FileUtils.copy(
61
+ ProconBypassMan.fallback_setting_path,
62
+ current_setting_path,
63
+ )
64
+ FileUtils.rm_rf(ProconBypassMan.fallback_setting_path)
65
+ end
47
66
  end
48
67
  end
49
68
  end
@@ -32,6 +32,16 @@ module ProconBypassMan
32
32
  @errors ||= Hash.new {|h,k| h[k] = [] }
33
33
  end
34
34
 
35
+ # @return [Array<String>]
36
+ def errors_to_s
37
+ errors.map { |_x, message|
38
+ value = <<~EOH
39
+ #{message.map { |m| "layer #{m}" }.join("\n")}
40
+ EOH
41
+ value.chomp
42
+ }.join("\n")
43
+ end
44
+
35
45
  private
36
46
 
37
47
  def validate_config_of_button_lonely
@@ -101,6 +101,8 @@ module ProconBypassMan
101
101
  def reset!
102
102
  @prefix_keys_for_changing_layer = []
103
103
  self.mode_plugins = {}
104
+ # プロセスを一度起動するとsetting_pathは変わらない、という想定なので適当に扱う. resetでは初期化しない
105
+ # self.setting_path = nil
104
106
  self.macro_plugins = {}
105
107
  self.layers = {
106
108
  up: Layer.new,
@@ -5,6 +5,7 @@ class ProconBypassMan::Bypass
5
5
 
6
6
  class BypassValue < Struct.new(:binary, :sent)
7
7
  def to_text
8
+ return unless binary
8
9
  "#{binary.unpack.first} #{'x' unless sent}"
9
10
  end
10
11
  end
@@ -31,16 +32,16 @@ class ProconBypassMan::Bypass
31
32
  self.bypass_value.binary = ProconBypassMan::Domains::InboundProconBinary.new(binary: input)
32
33
  rescue IO::EAGAINWaitReadable
33
34
  monitor.record(:eagain_wait_readable_on_read)
34
- sleep(0.001)
35
- retry
36
35
  end
37
36
 
38
- begin
39
- self.procon.write_nonblock(input)
40
- self.bypass_value.sent = true
41
- rescue IO::EAGAINWaitReadable
42
- monitor.record(:eagain_wait_readable_on_write)
43
- break
37
+ if input
38
+ begin
39
+ self.procon.write_nonblock(input)
40
+ self.bypass_value.sent = true
41
+ rescue IO::EAGAINWaitReadable
42
+ monitor.record(:eagain_wait_readable_on_write)
43
+ break
44
+ end
44
45
  end
45
46
  end
46
47
 
@@ -28,18 +28,11 @@ class ProconBypassMan::BypassCommand
28
28
  monitor2 = ProconBypassMan::IOMonitor.new(label: "procon -> switch")
29
29
  ProconBypassMan.logger.info "Thread1を起動します"
30
30
  t1 = Thread.new do
31
- timer = ProconBypassMan::SafeTimeout.new(timeout: Time.now + 10)
32
31
  bypass = ProconBypassMan::Bypass.new(gadget: @gadget, procon: @procon, monitor: monitor1)
33
32
  loop do
34
33
  break if $will_terminate_token
35
- timer.throw_if_timeout!
36
34
  bypass.send_gadget_to_procon!
37
- sleep(0.005)
38
- rescue ProconBypassMan::SafeTimeout::Timeout
39
- ProconBypassMan.logger.info "10秒経過したのでThread1を終了します"
40
- monitor1.shutdown
41
- puts "10秒経過したのでThread1を終了します"
42
- break
35
+ sleep(0.02)
43
36
  rescue Errno::EIO, Errno::ENODEV, Errno::EPROTO, IOError, Errno::ESHUTDOWN => e
44
37
  ProconBypassMan::SendErrorCommand.execute(error: "Switchとの切断されました.終了処理を開始します. #{e.full_message}")
45
38
  Process.kill "TERM", Process.ppid
@@ -80,7 +73,7 @@ class ProconBypassMan::BypassCommand
80
73
  [t1, t2].each(&:join)
81
74
  @gadget&.close
82
75
  @procon&.close
83
- exit 1
76
+ exit 1 # child processなのでexitしていい
84
77
  end
85
78
  end
86
79
  end
@@ -1,16 +1,28 @@
1
1
  class ProconBypassMan::ConnectDeviceCommand
2
+ class NotFoundProconError < StandardError; end
3
+
2
4
  # @return [void]
3
5
  def self.execute!
4
- gadget, procon = ProconBypassMan::DeviceConnector.connect
5
- rescue ProconBypassMan::DeviceConnector::NotFoundProconError => e
6
- ProconBypassMan.logger.error e
7
- gadget&.close
8
- procon&.close
9
- raise ProconBypassMan::NotFoundProconError
10
- rescue ProconBypassMan::SafeTimeout::Timeout
11
- ProconBypassMan.logger.error "デバイスとの通信でタイムアウトが起きて接続ができませんでした。"
12
- gadget&.close
13
- procon&.close
14
- raise ::ProconBypassMan::EternalConnectionError
6
+ unless has_required_files?
7
+ raise ProconBypassMan::NotFoundRequiredFilesError, "there is not /sys/kernel/config/usb_gadget/procon"
8
+ end
9
+
10
+ begin
11
+ gadget, procon = ProconBypassMan::DeviceConnector.connect
12
+ rescue ProconBypassMan::DeviceConnector::NotFoundProconError => e
13
+ ProconBypassMan.logger.error e
14
+ gadget&.close
15
+ procon&.close
16
+ raise ProconBypassMan::ConnectDeviceCommand::NotFoundProconError
17
+ rescue ProconBypassMan::SafeTimeout::Timeout
18
+ ProconBypassMan.logger.error "デバイスとの通信でタイムアウトが起きて接続ができませんでした。"
19
+ gadget&.close
20
+ procon&.close
21
+ raise ProconBypassMan::EternalConnectionError
22
+ end
23
+ end
24
+
25
+ def self.has_required_files?
26
+ Dir.exist?("/sys/kernel/config/usb_gadget/procon")
15
27
  end
16
28
  end
@@ -38,10 +38,19 @@ class ProconBypassMan::Configuration
38
38
  def device_id
39
39
  ENV["DEBUG_DEVICE_ID"] || ProconBypassMan::WriteDeviceIdCommand.execute
40
40
  end
41
+
42
+ # @return [Boolean]
43
+ def never_exit_accidentally
44
+ config.never_exit_accidentally
45
+ end
46
+
47
+ def fallback_setting_path
48
+ "/tmp/procon_bypass_man_fallback_setting.yaml"
49
+ end
41
50
  end
42
51
 
43
52
  attr_accessor :enable_critical_error_logging
44
- attr_writer :verbose_bypass_log, :raw_setting, :enable_reporting_pressed_buttons
53
+ attr_writer :verbose_bypass_log, :raw_setting, :enable_reporting_pressed_buttons, :never_exit_accidentally
45
54
 
46
55
  def root=(path)
47
56
  @root = path
@@ -158,4 +167,9 @@ class ProconBypassMan::Configuration
158
167
  def enable_reporting_pressed_buttons
159
168
  @enable_reporting_pressed_buttons ||= false
160
169
  end
170
+
171
+ # @return [Boolean]
172
+ def never_exit_accidentally
173
+ @never_exit_accidentally || false
174
+ end
161
175
  end
@@ -263,46 +263,19 @@ class ProconBypassMan::DeviceConnector
263
263
  @procon
264
264
  end
265
265
 
266
- def is_available_device?(path)
267
- return false if !File.exist?(path)
268
-
269
- system('echo > /sys/kernel/config/usb_gadget/procon/UDC')
270
- system('ls /sys/class/udc > /sys/kernel/config/usb_gadget/procon/UDC')
271
- sleep 0.5
272
-
273
- file = File.open(path, "w+")
274
- begin
275
- file.read_nonblock(64)
276
- rescue EOFError
277
- file.close
278
- return false
279
- rescue IO::EAGAINWaitReadable
280
- file.close
281
- return true
282
- end
283
- end
284
-
285
- def to_bin(string)
286
- string.unpack "H*"
287
- end
288
-
289
266
  def init_devices
290
267
  if @initialized_devices
291
268
  return
292
269
  end
293
270
 
294
- case
295
- when is_available_device?(PROCON_PATH)
296
- ProconBypassMan.logger.info "proconのデバイスファイルは#{PROCON_PATH}を使います"
297
- @procon = File.open(PROCON_PATH, "w+b")
298
- @gadget = File.open('/dev/hidg0', "w+b")
299
- when is_available_device?(PROCON2_PATH)
300
- ProconBypassMan.logger.info "proconのデバイスファイルは#{PROCON2_PATH}を使います"
301
- @procon = File.open(PROCON2_PATH, "w+b")
302
- @gadget = File.open('/dev/hidg0', "w+b")
271
+ if path = ProconBypassMan::DeviceProconFinder.find
272
+ @procon = File.open(path, "w+b")
273
+ ProconBypassMan.logger.info "proconのデバイスファイルは#{path}を使います"
303
274
  else
304
- raise NotFoundProconError, "/dev/hidraw0, /dev/hidraw1の両方見つかりませんでした"
275
+ raise(ProconBypassMan::DeviceConnector::NotFoundProconError)
305
276
  end
277
+ @gadget = File.open('/dev/hidg0', "w+b")
278
+
306
279
  system('echo > /sys/kernel/config/usb_gadget/procon/UDC')
307
280
  system('ls /sys/class/udc > /sys/kernel/config/usb_gadget/procon/UDC')
308
281
  sleep 0.5
@@ -0,0 +1,65 @@
1
+ class ProconBypassMan::DeviceProconFinder
2
+ HID_NAME = "Nintendo Co., Ltd. Pro Controller"
3
+
4
+ def self.find
5
+ new.find
6
+ end
7
+
8
+ # @return [String, NilClass]
9
+ def find
10
+ find_device_path
11
+ end
12
+
13
+ private
14
+
15
+ # @return [String , NilClass]
16
+ def find_device_path
17
+ if(line = device_from_shell) && (hidraw_name = line.match(/(hidraw\d+)\s+/)[1])
18
+ "/dev/#{hidraw_name}"
19
+ end
20
+ end
21
+
22
+ # @return [String , NilClass]
23
+ def device_from_shell
24
+ shell_output.split("\n").detect { |o| o.include?(HID_NAME) }
25
+ end
26
+
27
+ # @return [String]
28
+ def shell_output
29
+ `bash -c '#{get_list_shell}'`
30
+ end
31
+
32
+ def get_list_shell
33
+ <<~SHELL
34
+ #!/bin/bash
35
+
36
+ FILES=/dev/hidraw*
37
+ for f in $FILES
38
+ do
39
+ FILE=${f##*/}
40
+ DEVICE="$(cat /sys/class/hidraw/${FILE}/device/uevent | grep HID_NAME | cut -d '=' -f2)"
41
+ printf "%s %s\n" $FILE "$DEVICE"
42
+ done
43
+ SHELL
44
+ end
45
+
46
+ # これいる?
47
+ def is_available_device?(path)
48
+ return false if !File.exist?(path)
49
+
50
+ system('echo > /sys/kernel/config/usb_gadget/procon/UDC')
51
+ system('ls /sys/class/udc > /sys/kernel/config/usb_gadget/procon/UDC')
52
+ sleep 0.5
53
+
54
+ file = File.open(path, "w+")
55
+ begin
56
+ file.read_nonblock(64)
57
+ rescue EOFError
58
+ file.close
59
+ return false
60
+ rescue IO::EAGAINWaitReadable
61
+ file.close
62
+ return true
63
+ end
64
+ end
65
+ end
@@ -0,0 +1,12 @@
1
+ module ProconBypassMan
2
+ module NeverExitAccidentally
3
+ def exit_if_allow(status)
4
+ if ProconBypassMan.never_exit_accidentally
5
+ eternal_sleep
6
+ else
7
+ yield if block_given?
8
+ exit(status)
9
+ end
10
+ end
11
+ end
12
+ end
@@ -10,6 +10,7 @@ module ProconBypassMan
10
10
  private
11
11
 
12
12
  def before_action_callback
13
+ ProconBypassMan::ReportStartRebootJob.perform
13
14
  be_processed
14
15
  end
15
16
 
@@ -6,6 +6,13 @@ module ProconBypassMan
6
6
  require "pbmenv"
7
7
  ProconBypassMan.logger.info "execute RestorePbmSettingAction!"
8
8
  setting = args.dig("setting") or raise(ProconBypassMan::RemotePbmAction::NeedPbmVersionError, "settingが必要です, #{args.inspect}")
9
+
10
+ # 復元に失敗したら戻せるように退避する
11
+ FileUtils.copy(
12
+ ProconBypassMan::ButtonsSettingConfiguration.instance.setting_path,
13
+ ProconBypassMan.fallback_setting_path,
14
+ )
15
+
9
16
  ProconBypassMan::YamlWriter.write(
10
17
  path: ProconBypassMan::ButtonsSettingConfiguration.instance.setting_path,
11
18
  content: setting,
@@ -27,7 +27,7 @@ class ProconBypassMan::Runner
27
27
  loop do
28
28
  $will_terminate_token = false
29
29
  # NOTE メインプロセスではThreadをいくつか起動しているので念のためパフォーマンスを優先するためにforkしていく
30
- main_loop_pid = Kernel.fork { ProconBypassMan::BypassCommand.new(gadget: @gadget, procon: @procon).execute }
30
+ child_pid = Kernel.fork { ProconBypassMan::BypassCommand.new(gadget: @gadget, procon: @procon).execute }
31
31
 
32
32
  begin
33
33
  # TODO 小プロセスが消滅した時に、メインプロセスは生き続けてしまい、何もできなくなる問題がある
@@ -37,25 +37,25 @@ class ProconBypassMan::Runner
37
37
  end
38
38
  rescue InterruptForRestart
39
39
  $will_terminate_token = true
40
- Process.kill("TERM", main_loop_pid)
40
+ Process.kill("TERM", child_pid)
41
41
  Process.wait
42
42
  ProconBypassMan::PrintMessageCommand.execute(text: "Reloading config file")
43
43
  begin
44
44
  ProconBypassMan::ButtonsSettingConfiguration::Loader.reload_setting
45
45
  ProconBypassMan::SendReloadConfigEventCommand.execute
46
- rescue ProconBypassMan::CouldNotLoadConfigError
46
+ rescue ProconBypassMan::CouldNotLoadConfigError => error
47
47
  ProconBypassMan::SendErrorCommand.execute(error: "設定ファイルが不正です。再読み込みができませんでした")
48
+ ProconBypassMan::ReportErrorReloadConfigJob.perform_async(error.message)
48
49
  end
49
50
  ProconBypassMan::PrintMessageCommand.execute(text: "バイパス処理を再開します")
50
51
  rescue Interrupt
51
52
  $will_terminate_token = true
52
- Process.kill("TERM", main_loop_pid)
53
+ Process.kill("TERM", child_pid)
53
54
  Process.wait
55
+ ProconBypassMan::PrintMessageCommand.execute(text: "処理を終了します")
54
56
  @gadget&.close
55
57
  @procon&.close
56
- FileUtils.rm_rf(ProconBypassMan.pid_path)
57
- FileUtils.rm_rf(ProconBypassMan.digest_path)
58
- exit 1
58
+ break
59
59
  end
60
60
  end
61
61
  end
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module ProconBypassMan
4
- VERSION = "0.1.19.1"
4
+ VERSION = "0.1.20"
5
5
  end
@@ -27,7 +27,9 @@ require_relative "procon_bypass_man/background"
27
27
  require_relative "procon_bypass_man/commands"
28
28
  require_relative "procon_bypass_man/bypass"
29
29
  require_relative "procon_bypass_man/domains"
30
+ require_relative "procon_bypass_man/never_exit_accidentally"
30
31
  require_relative "procon_bypass_man/device_connector"
32
+ require_relative "procon_bypass_man/device_procon_finder"
31
33
  require_relative "procon_bypass_man/device_status"
32
34
  require_relative "procon_bypass_man/runner"
33
35
  require_relative "procon_bypass_man/processor"
@@ -48,10 +50,11 @@ Thread.abort_on_exception = true
48
50
 
49
51
  module ProconBypassMan
50
52
  extend ProconBypassMan::Configuration::ClassMethods
53
+ extend ProconBypassMan::NeverExitAccidentally
51
54
 
52
55
  class CouldNotLoadConfigError < StandardError; end
53
- class NotFoundProconError < StandardError; end
54
56
  class ConnectionError < StandardError; end
57
+ class NotFoundRequiredFilesError < StandardError; end
55
58
  class FirstConnectionError < ConnectionError; end
56
59
  class EternalConnectionError < ConnectionError; end
57
60
 
@@ -62,22 +65,31 @@ module ProconBypassMan
62
65
  ProconBypassMan::Websocket::PbmJobClient.start!
63
66
 
64
67
  ProconBypassMan::PrintMessageCommand.execute(text: "PBMを起動しています")
65
- ProconBypassMan::ButtonsSettingConfiguration::Loader.load(setting_path: setting_path)
66
68
  initialize_pbm
69
+ ProconBypassMan::ButtonsSettingConfiguration::Loader.load(setting_path: setting_path)
67
70
  gadget, procon = ProconBypassMan::ConnectDeviceCommand.execute!
68
- Runner.new(gadget: gadget, procon: procon).run
69
- rescue ProconBypassMan::CouldNotLoadConfigError
70
- ProconBypassMan::SendErrorCommand.execute(error: "設定ファイルが不正です。設定ファイルの読み込みに失敗しました")
71
- ProconBypassMan::DeviceStatus.change_to_setting_syntax_error_and_shutdown!
71
+ Runner.new(gadget: gadget, procon: procon).run # ここでblockingする
72
72
  FileUtils.rm_rf(ProconBypassMan.pid_path)
73
73
  FileUtils.rm_rf(ProconBypassMan.digest_path)
74
- exit 1
75
- rescue ProconBypassMan::NotFoundProconError
76
- ProconBypassMan::SendErrorCommand.execute(error: "プロコンが見つかりませんでした。終了します。")
77
- ProconBypassMan::DeviceStatus.change_to_procon_not_found_error!
74
+ rescue ProconBypassMan::NotFoundRequiredFilesError
75
+ ProconBypassMan::SendErrorCommand.execute(error: "/sys/kernel/config/usb_gadget/proconディレクトリがありませんでした。処理を終了します。")
78
76
  FileUtils.rm_rf(ProconBypassMan.pid_path)
79
77
  FileUtils.rm_rf(ProconBypassMan.digest_path)
80
- exit 1
78
+ exit 1 # 前提条件を満たしていないので絶対に落とす
79
+ rescue ProconBypassMan::CouldNotLoadConfigError
80
+ ProconBypassMan::SendErrorCommand.execute(error: "設定ファイルが不正です。設定ファイルの読み込みに失敗しました")
81
+ ProconBypassMan::DeviceStatus.change_to_setting_syntax_error_and_shutdown!
82
+ ProconBypassMan.exit_if_allow(1) do
83
+ FileUtils.rm_rf(ProconBypassMan.pid_path)
84
+ FileUtils.rm_rf(ProconBypassMan.digest_path)
85
+ end
86
+ rescue ProconBypassMan::ConnectDeviceCommand::NotFoundProconError
87
+ ProconBypassMan::SendErrorCommand.execute(error: "プロコンが見つかりませんでした。")
88
+ ProconBypassMan::DeviceStatus.change_to_procon_not_found_error!
89
+ ProconBypassMan.exit_if_allow(1) do
90
+ FileUtils.rm_rf(ProconBypassMan.pid_path)
91
+ FileUtils.rm_rf(ProconBypassMan.digest_path)
92
+ end
81
93
  rescue ProconBypassMan::ConnectionError
82
94
  begin
83
95
  raise
@@ -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.19.1'
8
+ gem 'procon_bypass_man', '0.1.20'
9
9
  end
10
10
 
11
11
  ProconBypassMan.configure do |config|
@@ -15,6 +15,8 @@ ProconBypassMan.configure do |config|
15
15
  # webからProconBypassManを操作できるwebサービス
16
16
  # config.api_servers = ['https://pbm-cloud.herokuapp.com']
17
17
  config.enable_critical_error_logging = true
18
+ # pbm-cloudで使う場合はnever_exitにtrueをセットしてください. trueがセットされている場合、不慮の事故が発生してもプロセスが終了しなくなります
19
+ config.never_exit_accidentally = true
18
20
  end
19
21
 
20
22
  ProconBypassMan.run(setting_path: "/usr/share/pbm/current/setting.yml")
@@ -1,28 +1,19 @@
1
1
  version: 1.0
2
2
  setting: |-
3
- install_macro_plugin ProconBypassMan::Plugin::Splatoon2::Macro::FastReturn
4
- install_macro_plugin ProconBypassMan::Plugin::Splatoon2::Macro::JumpToUpKey
5
- install_macro_plugin ProconBypassMan::Plugin::Splatoon2::Macro::JumpToRightKey
6
- install_macro_plugin ProconBypassMan::Plugin::Splatoon2::Macro::JumpToLeftKey
7
- install_mode_plugin ProconBypassMan::Plugin::Splatoon2::Mode::Guruguru
8
-
9
3
  prefix_keys_for_changing_layer [:zr, :zl, :l]
10
4
 
11
- layer :up, mode: :manual do
5
+ layer :up do
12
6
  flip :zr, if_pressed: :zr, force_neutral: :zl
13
- flip :zl, if_pressed: [:y, :b, :zl]
14
7
  flip :a, if_pressed: [:a]
15
8
  flip :down, if_pressed: :down
16
- macro ProconBypassMan::Plugin::Splatoon2::Macro::FastReturn, if_pressed: [:y, :b, :down]
17
- macro ProconBypassMan::Plugin::Splatoon2::Macro::JumpToUpKey, if_pressed: [:y, :b, :up]
18
- macro ProconBypassMan::Plugin::Splatoon2::Macro::JumpToRightKey, if_pressed: [:y, :b, :right]
19
- macro ProconBypassMan::Plugin::Splatoon2::Macro::JumpToLeftKey, if_pressed: [:y, :b, :left]
20
9
  remap :l, to: :zr
21
10
  end
22
- layer :right, mode: ProconBypassMan::Plugin::Splatoon2::Mode::Guruguru
11
+
12
+ layer :right do
13
+ end
14
+
23
15
  layer :left do
24
- remap :l, to: :zr
25
16
  end
17
+
26
18
  layer :down do
27
- remap :l, to: :zr
28
19
  end
data/sig/main.rbs CHANGED
@@ -185,10 +185,13 @@ class ProconBypassMan::Configuration
185
185
  def cache: () -> ProconBypassMan::OnMemoryCache
186
186
 
187
187
  def config: () -> ProconBypassMan::Configuration
188
+
189
+ def never_exit_accidentally: () -> bool
188
190
  end
189
191
 
190
192
  attr_reader api_server: untyped
191
193
  attr_reader api_servers: untyped
194
+ attr_writer never_exit_accidentally: bool
192
195
 
193
196
  attr_accessor enable_critical_error_logging: bool
194
197
 
@@ -226,6 +229,8 @@ class ProconBypassMan::Configuration
226
229
  def raw_setting: () -> untyped
227
230
 
228
231
  def verbose_bypass_log: () -> bool
232
+
233
+ def never_exit_accidentally: () -> bool
229
234
  end
230
235
 
231
236
 
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.19.1
4
+ version: 0.1.20
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-09 00:00:00.000000000 Z
11
+ date: 2022-02-13 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: pbmenv
@@ -97,10 +97,12 @@ files:
97
97
  - lib/procon_bypass_man/background/jobs/concerns/job_runnable.rb
98
98
  - lib/procon_bypass_man/background/jobs/report_boot_job.rb
99
99
  - lib/procon_bypass_man/background/jobs/report_error_job.rb
100
+ - lib/procon_bypass_man/background/jobs/report_error_reload_config_job.rb
100
101
  - lib/procon_bypass_man/background/jobs/report_event_base_job.rb
101
102
  - lib/procon_bypass_man/background/jobs/report_load_config_job.rb
102
103
  - lib/procon_bypass_man/background/jobs/report_pressed_buttons_job.rb
103
104
  - lib/procon_bypass_man/background/jobs/report_reload_config_job.rb
105
+ - lib/procon_bypass_man/background/jobs/report_start_reboot_job.rb
104
106
  - lib/procon_bypass_man/background/jobs/sync_device_stats_job.rb
105
107
  - lib/procon_bypass_man/buttons_setting_configuration.rb
106
108
  - lib/procon_bypass_man/buttons_setting_configuration/layer.rb
@@ -120,6 +122,7 @@ files:
120
122
  - lib/procon_bypass_man/commands/write_session_id_command.rb
121
123
  - lib/procon_bypass_man/configuration.rb
122
124
  - lib/procon_bypass_man/device_connector.rb
125
+ - lib/procon_bypass_man/device_procon_finder.rb
123
126
  - lib/procon_bypass_man/device_status.rb
124
127
  - lib/procon_bypass_man/domains.rb
125
128
  - lib/procon_bypass_man/domains/binary/base.rb
@@ -128,6 +131,7 @@ files:
128
131
  - lib/procon_bypass_man/domains/binary/inbound_procon_binary.rb
129
132
  - lib/procon_bypass_man/domains/binary/processing_procon_binary.rb
130
133
  - lib/procon_bypass_man/io_monitor.rb
134
+ - lib/procon_bypass_man/never_exit_accidentally.rb
131
135
  - lib/procon_bypass_man/plugin/splatoon2/macro/fast_return.rb
132
136
  - lib/procon_bypass_man/plugin/splatoon2/macro/jump_to_left_key.rb
133
137
  - lib/procon_bypass_man/plugin/splatoon2/macro/jump_to_right_key.rb