procon_bypass_man 0.1.8 → 0.1.12
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 +4 -4
- data/.circleci/config.yml +3 -2
- data/.github/workflows/ruby.yml +5 -4
- data/.gitignore +5 -0
- data/.rubocop.yml +2 -0
- data/.ruby-version +1 -1
- data/CHANGELOG.md +18 -1
- data/Gemfile +4 -0
- data/Gemfile.lock +53 -2
- data/README.md +14 -8
- data/Steepfile +39 -0
- data/bin/console +4 -0
- data/bin/dev_api_server.rb +18 -0
- data/docs/setup_raspi.mitamae.rb +12 -0
- data/lib/procon_bypass_man/background/has_server_pool.rb +54 -0
- data/lib/procon_bypass_man/background/http_client.rb +70 -0
- data/lib/procon_bypass_man/background/job_performer.rb +16 -0
- data/lib/procon_bypass_man/background/job_runnable.rb +16 -0
- data/lib/procon_bypass_man/background/job_runner.rb +44 -0
- data/lib/procon_bypass_man/background/jobs/base_job.rb +12 -0
- data/lib/procon_bypass_man/background/jobs/report_boot_job.rb +10 -0
- data/lib/procon_bypass_man/background/jobs/report_error_job.rb +10 -0
- data/lib/procon_bypass_man/background/jobs/report_heartbeat_job.rb +10 -0
- data/lib/procon_bypass_man/background/jobs/report_pressed_buttons_job.rb +18 -0
- data/lib/procon_bypass_man/background/jobs/report_reload_config_job.rb +10 -0
- data/lib/procon_bypass_man/background.rb +10 -0
- data/lib/procon_bypass_man/boot_message.rb +42 -0
- data/lib/procon_bypass_man/{configuration → buttons_setting_configuration}/layer.rb +50 -4
- data/lib/procon_bypass_man/{configuration → buttons_setting_configuration}/loader.rb +12 -11
- data/lib/procon_bypass_man/{configuration → buttons_setting_configuration}/validator.rb +1 -1
- data/lib/procon_bypass_man/buttons_setting_configuration.rb +101 -0
- data/lib/procon_bypass_man/bypass/usb_hid_logger.rb +36 -0
- data/lib/procon_bypass_man/bypass.rb +61 -29
- data/lib/procon_bypass_man/callbacks.rb +70 -0
- data/lib/procon_bypass_man/commands/connect_device_command.rb +11 -0
- data/lib/procon_bypass_man/commands/print_boot_message_command.rb +9 -0
- data/lib/procon_bypass_man/commands/send_error_command.rb +18 -0
- data/lib/procon_bypass_man/commands/send_reload_config_event_command.rb +10 -0
- data/lib/procon_bypass_man/commands/write_device_id_command.rb +11 -0
- data/lib/procon_bypass_man/commands/write_session_id_command.rb +13 -0
- data/lib/procon_bypass_man/commands.rb +6 -0
- data/lib/procon_bypass_man/configuration.rb +92 -67
- data/lib/procon_bypass_man/device_connector.rb +11 -29
- data/lib/procon_bypass_man/io_monitor.rb +16 -8
- data/lib/procon_bypass_man/on_memory_cache.rb +34 -0
- data/lib/procon_bypass_man/procon/analog_stick.rb +31 -0
- data/lib/procon_bypass_man/procon/analog_stick_cap.rb +65 -0
- data/lib/procon_bypass_man/procon/button_collection.rb +15 -6
- data/lib/procon_bypass_man/procon/{data.rb → consts.rb} +1 -1
- data/lib/procon_bypass_man/procon/layer_changer.rb +40 -0
- data/lib/procon_bypass_man/procon/macro_registry.rb +2 -2
- data/lib/procon_bypass_man/procon/mode_registry.rb +4 -4
- data/lib/procon_bypass_man/procon/press_button_aware.rb +13 -0
- data/lib/procon_bypass_man/procon/user_operation.rb +21 -16
- data/lib/procon_bypass_man/procon.rb +23 -9
- data/lib/procon_bypass_man/procon_reader.rb +31 -0
- data/lib/procon_bypass_man/runner.rb +43 -64
- data/lib/procon_bypass_man/uptime.rb +14 -2
- data/lib/procon_bypass_man/version.rb +1 -1
- data/lib/procon_bypass_man.rb +38 -43
- data/project_template/README.md +1 -1
- data/project_template/app.rb +7 -5
- data/project_template/systemd_units/pbm_web.service +11 -0
- data/project_template/web.rb +16 -0
- data/sig/README.rb +4 -0
- data/sig/main.rbs +505 -0
- metadata +42 -11
- data/examples/practical/app.rb +0 -21
- data/examples/practical/setting.yml +0 -24
- data/lib/procon_bypass_man/procon/layer_changeable.rb +0 -28
- data/lib/procon_bypass_man/procon/pressed_button_helper.rb +0 -25
@@ -1,13 +1,14 @@
|
|
1
1
|
class ProconBypassMan::Procon
|
2
2
|
class UserOperation
|
3
|
-
include LayerChangeable
|
4
|
-
include PushedButtonHelper::Static
|
5
|
-
extend PushedButtonHelper::Dynamic
|
6
|
-
|
7
3
|
attr_reader :binary
|
8
4
|
|
5
|
+
::ProconBypassMan::Procon::ButtonCollection::BUTTONS_MAP.each do |button, _value|
|
6
|
+
define_method "pressed_#{button}?" do
|
7
|
+
pressed_button?(button)
|
8
|
+
end
|
9
|
+
end
|
10
|
+
|
9
11
|
def initialize(binary)
|
10
|
-
self.class.compile_if_not_compile_yet!
|
11
12
|
unless binary.encoding.name == ASCII_ENCODING
|
12
13
|
raise "おかしいです"
|
13
14
|
end
|
@@ -17,34 +18,34 @@ class ProconBypassMan::Procon
|
|
17
18
|
ZERO_BIT = ["0"].pack("H*").freeze
|
18
19
|
ASCII_ENCODING = "ASCII-8BIT"
|
19
20
|
|
20
|
-
# @depilicate
|
21
|
-
def binary=(binary)
|
22
|
-
unless binary.encoding.name == ASCII_ENCODING
|
23
|
-
raise "おかしいです"
|
24
|
-
end
|
25
|
-
@binary = binary
|
26
|
-
end
|
27
|
-
|
28
21
|
def set_no_action!
|
29
22
|
binary[3] = ZERO_BIT
|
30
23
|
binary[4] = ZERO_BIT
|
31
24
|
binary[5] = ZERO_BIT
|
32
25
|
end
|
33
26
|
|
27
|
+
def apply_left_analog_stick_cap(cap: )
|
28
|
+
binary[6..8] = ProconBypassMan::Procon::AnalogStickCap.new(binary).capped_position(cap_hypotenuse: cap).to_binary
|
29
|
+
end
|
30
|
+
|
34
31
|
def unpress_button(button)
|
32
|
+
return if not pressed_button?(button)
|
33
|
+
|
35
34
|
byte_position = ButtonCollection.load(button).byte_position
|
36
|
-
value = binary[byte_position].unpack("H*").first.to_i(16) - 2**ButtonCollection.load(button).bit_position
|
35
|
+
value = binary[byte_position].unpack("H*").first.to_i(16) - (2**ButtonCollection.load(button).bit_position)
|
37
36
|
binary[byte_position] = ["%02X" % value.to_s].pack("H*")
|
38
37
|
end
|
39
38
|
|
40
39
|
def press_button(button)
|
40
|
+
return if pressed_button?(button)
|
41
|
+
|
41
42
|
byte_position = ButtonCollection.load(button).byte_position
|
42
|
-
value = binary[byte_position].unpack("H*").first.to_i(16) + 2**ButtonCollection.load(button).bit_position
|
43
|
+
value = binary[byte_position].unpack("H*").first.to_i(16) + (2**ButtonCollection.load(button).bit_position)
|
43
44
|
binary[byte_position] = ["%02X" % value.to_s].pack("H*")
|
44
45
|
end
|
45
46
|
|
46
47
|
def press_button_only(button)
|
47
|
-
[ProconBypassMan::Procon::
|
48
|
+
[ProconBypassMan::Procon::Consts::NO_ACTION.dup].pack("H*").tap do |no_action_binary|
|
48
49
|
ButtonCollection.load(button).byte_position
|
49
50
|
byte_position = ButtonCollection.load(button).byte_position
|
50
51
|
value = 2**ButtonCollection.load(button).bit_position
|
@@ -68,5 +69,9 @@ class ProconBypassMan::Procon
|
|
68
69
|
binary[11] = tb[11]
|
69
70
|
self.binary
|
70
71
|
end
|
72
|
+
|
73
|
+
def pressed_button?(button)
|
74
|
+
ProconBypassMan::PpressButtonAware.new(binary).pressed_button?(button)
|
75
|
+
end
|
71
76
|
end
|
72
77
|
end
|
@@ -1,12 +1,12 @@
|
|
1
1
|
class ProconBypassMan::Procon
|
2
|
-
require "procon_bypass_man/procon/
|
2
|
+
require "procon_bypass_man/procon/consts"
|
3
3
|
require "procon_bypass_man/procon/mode_registry"
|
4
4
|
require "procon_bypass_man/procon/macro_registry"
|
5
|
-
require "procon_bypass_man/procon/
|
5
|
+
require "procon_bypass_man/procon/layer_changer"
|
6
6
|
require "procon_bypass_man/procon/button_collection"
|
7
|
-
require "procon_bypass_man/procon/pressed_button_helper"
|
8
7
|
require "procon_bypass_man/procon/user_operation"
|
9
8
|
require "procon_bypass_man/procon/flip_cache"
|
9
|
+
require "procon_bypass_man/procon/press_button_aware"
|
10
10
|
|
11
11
|
attr_accessor :user_operation
|
12
12
|
|
@@ -30,12 +30,13 @@ class ProconBypassMan::Procon
|
|
30
30
|
def current_layer_key; @@status[:current_layer_key]; end
|
31
31
|
|
32
32
|
def current_layer
|
33
|
-
ProconBypassMan::
|
33
|
+
ProconBypassMan::ButtonsSettingConfiguration.instance.layers[current_layer_key]
|
34
34
|
end
|
35
35
|
|
36
36
|
def apply!
|
37
|
-
|
38
|
-
|
37
|
+
layer_changer = ProconBypassMan::Procon::LayerChanger.new(binary: user_operation.binary)
|
38
|
+
if layer_changer.change_layer?
|
39
|
+
@@status[:current_layer_key] = layer_changer.next_layer_key if layer_changer.pressed_next_layer?
|
39
40
|
user_operation.set_no_action!
|
40
41
|
return
|
41
42
|
end
|
@@ -94,10 +95,23 @@ class ProconBypassMan::Procon
|
|
94
95
|
return user_operation.binary
|
95
96
|
end
|
96
97
|
|
98
|
+
current_layer.disables.each do |button|
|
99
|
+
user_operation.unpress_button(button)
|
100
|
+
end
|
101
|
+
|
102
|
+
current_layer.left_analog_stick_caps.each do |button, options|
|
103
|
+
if button.nil? || button.all? { |b| user_operation.pressed_button?(b) }
|
104
|
+
options[:force_neutral]&.each do |force_neutral_button|
|
105
|
+
user_operation.unpress_button(force_neutral_button)
|
106
|
+
end
|
107
|
+
user_operation.apply_left_analog_stick_cap(cap: options[:cap])
|
108
|
+
end
|
109
|
+
end
|
110
|
+
|
97
111
|
current_layer.flip_buttons.each do |button, options|
|
98
112
|
# 何もしないで常に連打
|
99
113
|
if !options[:if_pressed] && status[button]
|
100
|
-
user_operation.press_button(button)
|
114
|
+
user_operation.press_button(button)
|
101
115
|
next
|
102
116
|
end
|
103
117
|
|
@@ -108,7 +122,7 @@ class ProconBypassMan::Procon
|
|
108
122
|
end
|
109
123
|
|
110
124
|
options[:force_neutral]&.each do |force_neutral_button|
|
111
|
-
user_operation.
|
125
|
+
user_operation.unpress_button(force_neutral_button)
|
112
126
|
end
|
113
127
|
end
|
114
128
|
end
|
@@ -118,7 +132,7 @@ class ProconBypassMan::Procon
|
|
118
132
|
user_operation.unpress_button(from_button)
|
119
133
|
# TODO 2重でpressしないようにしたい
|
120
134
|
to_buttons[:to].each do |to_button|
|
121
|
-
user_operation.press_button(to_button)
|
135
|
+
user_operation.press_button(to_button)
|
122
136
|
end
|
123
137
|
end
|
124
138
|
end
|
@@ -0,0 +1,31 @@
|
|
1
|
+
class ProconBypassMan::ProconReader
|
2
|
+
def initialize(binary: )
|
3
|
+
@binary = binary
|
4
|
+
@analog_stick = ProconBypassMan::Procon::AnalogStick.new(binary: binary)
|
5
|
+
end
|
6
|
+
|
7
|
+
# @return [Array<Symbol>]
|
8
|
+
def pressed
|
9
|
+
aware = ProconBypassMan::PpressButtonAware.new(@binary)
|
10
|
+
pressed_table = ::ProconBypassMan::Procon::ButtonCollection::BUTTONS.reduce({}) do |acc, button|
|
11
|
+
acc[button] = aware.pressed_button?(button)
|
12
|
+
acc
|
13
|
+
end
|
14
|
+
pressed_table.select { |_key, value| value }.keys
|
15
|
+
end
|
16
|
+
|
17
|
+
def left_analog_stick
|
18
|
+
{ x: @analog_stick.relative_x, y: @analog_stick.relative_y }
|
19
|
+
end
|
20
|
+
|
21
|
+
def left_analog_stick_by_abs
|
22
|
+
{ x: @analog_stick.abs_x, y: @analog_stick.abs_y }
|
23
|
+
end
|
24
|
+
|
25
|
+
def to_hash
|
26
|
+
{ left_analog_stick: left_analog_stick,
|
27
|
+
left_analog_stick_by_abs: left_analog_stick_by_abs,
|
28
|
+
buttons: pressed,
|
29
|
+
}
|
30
|
+
end
|
31
|
+
end
|
@@ -1,18 +1,20 @@
|
|
1
1
|
require_relative "io_monitor"
|
2
2
|
require_relative "uptime"
|
3
|
+
require_relative "boot_message"
|
4
|
+
require_relative "background/job_runner"
|
3
5
|
|
4
6
|
class ProconBypassMan::Runner
|
5
7
|
class InterruptForRestart < StandardError; end
|
6
8
|
|
7
|
-
def initialize
|
8
|
-
|
9
|
-
|
9
|
+
def initialize(gadget: , procon: )
|
10
|
+
@gadget = gadget
|
11
|
+
@procon = procon
|
12
|
+
|
13
|
+
ProconBypassMan::PrintBootMessageCommand.execute
|
14
|
+
ProconBypassMan::Background::JobRunner.start!
|
10
15
|
end
|
11
16
|
|
12
17
|
def run
|
13
|
-
first_negotiation
|
14
|
-
print_booted_message
|
15
|
-
|
16
18
|
self_read, self_write = IO.pipe
|
17
19
|
%w(TERM INT USR1 USR2).each do |sig|
|
18
20
|
begin
|
@@ -20,7 +22,7 @@ class ProconBypassMan::Runner
|
|
20
22
|
self_write.puts(sig)
|
21
23
|
end
|
22
24
|
rescue ArgumentError
|
23
|
-
ProconBypassMan.
|
25
|
+
ProconBypassMan::SendErrorCommand.execute(error: "Signal #{sig} not supported")
|
24
26
|
end
|
25
27
|
end
|
26
28
|
|
@@ -39,11 +41,11 @@ class ProconBypassMan::Runner
|
|
39
41
|
Process.wait
|
40
42
|
ProconBypassMan.logger.info("Reloading config file")
|
41
43
|
begin
|
42
|
-
ProconBypassMan::
|
43
|
-
puts "設定ファイルの再読み込みができました"
|
44
|
+
ProconBypassMan::ButtonsSettingConfiguration::Loader.reload_setting
|
44
45
|
rescue ProconBypassMan::CouldNotLoadConfigError
|
45
|
-
ProconBypassMan.
|
46
|
+
ProconBypassMan::SendErrorCommand.execute(error: "設定ファイルが不正です。再読み込みができませんでした")
|
46
47
|
end
|
48
|
+
ProconBypassMan::SendReloadConfigEventCommand.execute
|
47
49
|
ProconBypassMan.logger.info("バイパス処理を再開します")
|
48
50
|
rescue Interrupt
|
49
51
|
$will_terminate_token = true
|
@@ -61,31 +63,36 @@ class ProconBypassMan::Runner
|
|
61
63
|
private
|
62
64
|
|
63
65
|
def main_loop
|
64
|
-
# TODO 接続確立完了をswitchを読み取るようにして、この暫定で接続完了sleepを消す
|
65
|
-
Thread.new do
|
66
|
-
sleep(5)
|
67
|
-
$will_interval_0_0_0_5 = 0.005
|
68
|
-
$will_interval_1_6 = 1.6
|
69
|
-
end
|
70
|
-
|
71
66
|
ProconBypassMan::IOMonitor.start!
|
67
|
+
ProconBypassMan::Background::JobRunner.start!
|
68
|
+
|
72
69
|
# gadget => procon
|
73
70
|
# 遅くていい
|
74
71
|
monitor1 = ProconBypassMan::IOMonitor.new(label: "switch -> procon")
|
75
72
|
monitor2 = ProconBypassMan::IOMonitor.new(label: "procon -> switch")
|
76
73
|
ProconBypassMan.logger.info "Thread1を起動します"
|
77
74
|
t1 = Thread.new do
|
75
|
+
timer = ProconBypassMan::Timer.new(timeout: Time.now + 10)
|
78
76
|
bypass = ProconBypassMan::Bypass.new(gadget: @gadget, procon: @procon, monitor: monitor1)
|
79
|
-
|
80
|
-
|
81
|
-
|
82
|
-
|
83
|
-
|
84
|
-
|
85
|
-
|
86
|
-
|
87
|
-
|
77
|
+
loop do
|
78
|
+
break if $will_terminate_token
|
79
|
+
timer.throw_if_timeout!
|
80
|
+
bypass.send_gadget_to_procon!
|
81
|
+
sleep(0.005)
|
82
|
+
rescue ProconBypassMan::Timer::Timeout
|
83
|
+
ProconBypassMan.logger.info "10秒経過したのでThread1を終了します"
|
84
|
+
monitor1.shutdown
|
85
|
+
puts "10秒経過したのでThread1を終了します"
|
86
|
+
break
|
87
|
+
rescue Errno::EIO, Errno::ENODEV, Errno::EPROTO, IOError => e
|
88
|
+
ProconBypassMan::SendErrorCommand.execute(error: "Switchとの切断されました.終了処理を開始します. #{e.full_message}")
|
89
|
+
Process.kill "TERM", Process.ppid
|
90
|
+
rescue Errno::ETIMEDOUT => e
|
91
|
+
# TODO まれにこれが発生する. 再接続したい
|
92
|
+
ProconBypassMan::SendErrorCommand.execute(error: "Switchと意図せず切断されました.終了処理を開始します. #{e.full_message}")
|
93
|
+
Process.kill "TERM", Process.ppid
|
88
94
|
end
|
95
|
+
ProconBypassMan.logger.info "Thread1を終了します"
|
89
96
|
end
|
90
97
|
|
91
98
|
# procon => gadget
|
@@ -93,19 +100,17 @@ class ProconBypassMan::Runner
|
|
93
100
|
ProconBypassMan.logger.info "Thread2を起動します"
|
94
101
|
t2 = Thread.new do
|
95
102
|
bypass = ProconBypassMan::Bypass.new(gadget: @gadget, procon: @procon, monitor: monitor2)
|
96
|
-
|
97
|
-
|
98
|
-
|
99
|
-
|
100
|
-
|
101
|
-
|
102
|
-
|
103
|
-
|
104
|
-
|
105
|
-
Process.kill "TERM", Process.ppid
|
106
|
-
end
|
107
|
-
ProconBypassMan.logger.info "Thread2を終了します"
|
103
|
+
loop do
|
104
|
+
break if $will_terminate_token
|
105
|
+
bypass.send_procon_to_gadget!
|
106
|
+
rescue EOFError => e
|
107
|
+
ProconBypassMan::SendErrorCommand.execute(error: "Proconが切断されました。終了処理を開始します. #{e.full_message}")
|
108
|
+
Process.kill "TERM", Process.ppid
|
109
|
+
rescue Errno::EIO, Errno::ENODEV, Errno::EPROTO, IOError => e
|
110
|
+
ProconBypassMan::SendErrorCommand.execute(error: "Proconが切断されました。終了処理を開始します2. #{e.full_message}")
|
111
|
+
Process.kill "TERM", Process.ppid
|
108
112
|
end
|
113
|
+
ProconBypassMan.logger.info "Thread2を終了します"
|
109
114
|
end
|
110
115
|
|
111
116
|
self_read, self_write = IO.pipe
|
@@ -134,15 +139,6 @@ class ProconBypassMan::Runner
|
|
134
139
|
end
|
135
140
|
end
|
136
141
|
|
137
|
-
def first_negotiation
|
138
|
-
@gadget, @procon = ProconBypassMan::DeviceConnector.connect
|
139
|
-
rescue ProconBypassMan::Timer::Timeout
|
140
|
-
::ProconBypassMan.logger.error "デバイスとの通信でタイムアウトが起きて接続ができませんでした。"
|
141
|
-
@gadget&.close
|
142
|
-
@procon&.close
|
143
|
-
raise ::ProconBypassMan::EternalConnectionError
|
144
|
-
end
|
145
|
-
|
146
142
|
def handle_signal(sig)
|
147
143
|
ProconBypassMan.logger.info "#{$$}で#{sig}を受け取りました"
|
148
144
|
case sig
|
@@ -152,21 +148,4 @@ class ProconBypassMan::Runner
|
|
152
148
|
raise Interrupt
|
153
149
|
end
|
154
150
|
end
|
155
|
-
|
156
|
-
# @return [void]
|
157
|
-
def print_booted_message
|
158
|
-
booted_message = <<~EOF
|
159
|
-
----
|
160
|
-
RUBY_VERSION: #{RUBY_VERSION}
|
161
|
-
ProconBypassMan: #{ProconBypassMan::VERSION}
|
162
|
-
pid: #{$$}
|
163
|
-
root: #{ProconBypassMan.root}
|
164
|
-
pid_path: #{ProconBypassMan.pid_path}
|
165
|
-
setting_path: #{ProconBypassMan::Configuration.instance.setting_path}
|
166
|
-
uptime from boot: #{ProconBypassMan::Uptime.from_boot} sec
|
167
|
-
----
|
168
|
-
EOF
|
169
|
-
ProconBypassMan.logger.info(booted_message)
|
170
|
-
puts booted_message
|
171
|
-
end
|
172
151
|
end
|
@@ -2,12 +2,24 @@ require "time"
|
|
2
2
|
|
3
3
|
module ProconBypassMan
|
4
4
|
class Uptime
|
5
|
+
# @return [Integer]
|
5
6
|
def self.from_boot
|
6
|
-
|
7
|
+
new(uptime_cmd_result: `uptime -s`.chomp).from_boot
|
8
|
+
end
|
9
|
+
|
10
|
+
# @param [String] uptime_cmd_result
|
11
|
+
def initialize(uptime_cmd_result: )
|
12
|
+
@result = uptime_cmd_result
|
13
|
+
end
|
14
|
+
|
15
|
+
# @return [Integer]
|
16
|
+
def from_boot
|
17
|
+
return -1 if @result == '' # darwin系だとsオプションが使えない
|
18
|
+
boot_time = Time.parse(@result).to_i
|
7
19
|
return Time.now.to_i - boot_time.to_i
|
8
20
|
rescue => e
|
9
21
|
ProconBypassMan.logger.error(e)
|
10
|
-
return
|
22
|
+
return -1
|
11
23
|
end
|
12
24
|
end
|
13
25
|
end
|
data/lib/procon_bypass_man.rb
CHANGED
@@ -1,99 +1,94 @@
|
|
1
1
|
require "logger"
|
2
2
|
require 'yaml'
|
3
|
+
require "json"
|
4
|
+
require "net/http"
|
3
5
|
require "fileutils"
|
6
|
+
require "securerandom"
|
4
7
|
|
5
8
|
require_relative "procon_bypass_man/version"
|
9
|
+
require_relative "procon_bypass_man/callbacks"
|
6
10
|
require_relative "procon_bypass_man/timer"
|
7
11
|
require_relative "procon_bypass_man/bypass"
|
8
12
|
require_relative "procon_bypass_man/device_connector"
|
9
13
|
require_relative "procon_bypass_man/runner"
|
10
14
|
require_relative "procon_bypass_man/processor"
|
11
15
|
require_relative "procon_bypass_man/configuration"
|
16
|
+
require_relative "procon_bypass_man/buttons_setting_configuration"
|
17
|
+
require_relative "procon_bypass_man/procon_reader"
|
12
18
|
require_relative "procon_bypass_man/procon"
|
19
|
+
require_relative "procon_bypass_man/procon/analog_stick"
|
20
|
+
require_relative "procon_bypass_man/procon/analog_stick_cap"
|
21
|
+
require_relative "procon_bypass_man/background"
|
22
|
+
require_relative "procon_bypass_man/commands"
|
23
|
+
require_relative "procon_bypass_man/on_memory_cache"
|
13
24
|
|
14
25
|
STDOUT.sync = true
|
15
26
|
Thread.abort_on_exception = true
|
16
27
|
|
17
|
-
# new feature from ruby3.0's
|
18
|
-
if GC.respond_to?(:auto_compact)
|
19
|
-
GC.auto_compact = true
|
20
|
-
end
|
21
|
-
|
22
28
|
module ProconBypassMan
|
23
|
-
|
29
|
+
extend ProconBypassMan::Configuration::ClassMethods
|
30
|
+
|
24
31
|
class CouldNotLoadConfigError < StandardError; end
|
25
32
|
class FirstConnectionError < StandardError; end
|
26
33
|
class EternalConnectionError < StandardError; end
|
27
34
|
|
28
|
-
def self.
|
35
|
+
def self.buttons_setting_configure(setting_path: nil, &block)
|
29
36
|
unless setting_path
|
30
37
|
logger.warn "setting_pathが未設定です。設定ファイルのライブリロードが使えません。"
|
31
38
|
end
|
32
39
|
|
33
40
|
if block_given?
|
34
|
-
ProconBypassMan::
|
41
|
+
ProconBypassMan::ButtonsSettingConfiguration.instance.instance_eval(&block)
|
35
42
|
else
|
36
|
-
ProconBypassMan::
|
43
|
+
ProconBypassMan::ButtonsSettingConfiguration::Loader.load(setting_path: setting_path)
|
37
44
|
end
|
38
45
|
end
|
39
46
|
|
47
|
+
# @return [void]
|
40
48
|
def self.run(setting_path: nil, &block)
|
41
|
-
|
49
|
+
ProconBypassMan.logger.info "PBMを起動しています"
|
50
|
+
puts "PBMを起動しています"
|
51
|
+
buttons_setting_configure(setting_path: setting_path, &block)
|
52
|
+
initialize_pbm
|
42
53
|
File.write(pid_path, $$)
|
43
|
-
|
54
|
+
ProconBypassMan::WriteSessionIdCommand.execute
|
55
|
+
gadget, procon = ProconBypassMan::ConnectDeviceCommand.execute!
|
56
|
+
Runner.new(gadget: gadget, procon: procon).run
|
44
57
|
rescue CouldNotLoadConfigError
|
45
|
-
ProconBypassMan.
|
46
|
-
puts "設定ファイルが不正です。設定ファイルの読み込みに失敗しました"
|
58
|
+
ProconBypassMan::SendErrorCommand.execute(error: "設定ファイルが不正です。設定ファイルの読み込みに失敗しました")
|
47
59
|
FileUtils.rm_rf(ProconBypassMan.pid_path)
|
48
60
|
FileUtils.rm_rf(ProconBypassMan.digest_path)
|
49
61
|
exit 1
|
50
62
|
rescue EternalConnectionError
|
51
|
-
ProconBypassMan.
|
52
|
-
puts "接続の見込みがないのでsleepしまくります"
|
63
|
+
ProconBypassMan::SendErrorCommand.execute(error: "接続の見込みがないのでsleepしまくります")
|
53
64
|
FileUtils.rm_rf(ProconBypassMan.pid_path)
|
54
65
|
sleep(999999999)
|
55
66
|
rescue FirstConnectionError
|
56
|
-
|
67
|
+
ProconBypassMan::SendErrorCommand.execute(error: "接続を確立できませんでした。やりなおします。")
|
57
68
|
retry
|
58
69
|
end
|
59
70
|
|
60
|
-
def self.
|
61
|
-
@@
|
62
|
-
|
63
|
-
|
64
|
-
def self.logger
|
65
|
-
if defined?(@@logger)
|
66
|
-
@@logger
|
67
|
-
else
|
68
|
-
Logger.new(nil)
|
69
|
-
end
|
71
|
+
def self.configure(&block)
|
72
|
+
@@configuration = ProconBypassMan::Configuration.new
|
73
|
+
@@configuration.instance_eval(&block)
|
74
|
+
@@configuration
|
70
75
|
end
|
71
76
|
|
72
|
-
|
73
|
-
|
77
|
+
# @return [ProconBypassMan::Configuration]
|
78
|
+
def self.config
|
79
|
+
@@configuration ||= ProconBypassMan::Configuration.new
|
74
80
|
end
|
75
81
|
|
82
|
+
# @return [void]
|
76
83
|
def self.reset!
|
77
84
|
ProconBypassMan::Procon::MacroRegistry.reset!
|
78
85
|
ProconBypassMan::Procon::ModeRegistry.reset!
|
79
86
|
ProconBypassMan::Procon.reset!
|
80
|
-
ProconBypassMan::
|
87
|
+
ProconBypassMan::ButtonsSettingConfiguration.instance.reset!
|
81
88
|
ProconBypassMan::IOMonitor.reset!
|
82
89
|
end
|
83
90
|
|
84
|
-
def self.
|
85
|
-
|
86
|
-
@@root
|
87
|
-
else
|
88
|
-
File.expand_path('..', __dir__).freeze
|
89
|
-
end
|
90
|
-
end
|
91
|
-
|
92
|
-
def self.root=(path)
|
93
|
-
@@root = path
|
94
|
-
end
|
95
|
-
|
96
|
-
def self.digest_path
|
97
|
-
"#{root}/.setting_yaml_digest"
|
91
|
+
def self.initialize_pbm
|
92
|
+
ProconBypassMan::WriteDeviceIdCommand.execute
|
98
93
|
end
|
99
94
|
end
|
data/project_template/README.md
CHANGED
@@ -3,6 +3,7 @@ https://github.com/splaplapla/pbmenv で使っているファイルです
|
|
3
3
|
|
4
4
|
## systemd
|
5
5
|
* sudo ln -s /usr/share/pbm/current/systemd_units/pbm.service /etc/systemd/system/pbm.service
|
6
|
+
* sudo ln -s /usr/share/pbm/current/systemd_units/pbm_web.service /etc/systemd/system/pbm_web.service
|
6
7
|
* commands
|
7
8
|
* systemctl daemon-reload
|
8
9
|
* systemctl enable pbm.service
|
@@ -14,4 +15,3 @@ https://github.com/splaplapla/pbmenv で使っているファイルです
|
|
14
15
|
|
15
16
|
### ログ
|
16
17
|
* journalctl -xe -f
|
17
|
-
|
data/project_template/app.rb
CHANGED
@@ -5,14 +5,16 @@ 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.
|
8
|
+
gem 'procon_bypass_man', '0.1.12'
|
9
9
|
gem 'procon_bypass_man-splatoon2', github: 'splaplapla/procon_bypass_man-splatoon2', tag: "0.1.1"
|
10
10
|
end
|
11
11
|
|
12
|
-
ProconBypassMan.
|
13
|
-
|
14
|
-
|
15
|
-
|
12
|
+
ProconBypassMan.configure do |config|
|
13
|
+
config.root = File.expand_path(__dir__)
|
14
|
+
config.logger = Logger.new("#{ProconBypassMan.root}/app.log", 5, 1024 * 1024 * 10)
|
15
|
+
config.logger.level = :debug
|
16
|
+
# config.api_servers = ['https://...']
|
17
|
+
config.enable_critical_error_logging = true
|
16
18
|
end
|
17
19
|
|
18
20
|
ProconBypassMan.run(setting_path: "/usr/share/pbm/current/setting.yml")
|
@@ -0,0 +1,11 @@
|
|
1
|
+
[Unit]
|
2
|
+
Description=PBM WEB
|
3
|
+
|
4
|
+
[Service]
|
5
|
+
Type=simple
|
6
|
+
WorkingDirectory=/home/pi/src/procon_bypass_man_sample
|
7
|
+
ExecStart=/bin/bash -c "/home/pi/.rbenv/versions/3.0.1/bin/ruby /usr/share/pbm/current/web.rb"
|
8
|
+
Restart=always
|
9
|
+
|
10
|
+
[Install]
|
11
|
+
WantedBy=multi-user.target
|
@@ -0,0 +1,16 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
|
3
|
+
require 'bundler/inline'
|
4
|
+
|
5
|
+
gemfile do
|
6
|
+
source 'https://rubygems.org'
|
7
|
+
git_source(:github) {|repo_name| "https://github.com/#{repo_name}" }
|
8
|
+
gem 'procon_bypass_man-web', '0.1.3'
|
9
|
+
end
|
10
|
+
|
11
|
+
ProconBypassMan::Web.configure do |config|
|
12
|
+
config.root = File.expand_path(__dir__)
|
13
|
+
config.logger = Logger.new("#{ProconBypassMan::Web.root}/web.log", 1, 1024 * 1024 * 10)
|
14
|
+
end
|
15
|
+
|
16
|
+
ProconBypassMan::Web::Server.start
|
data/sig/README.rb
ADDED