procon_bypass_man 0.1.23 → 0.2.2
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 +13 -0
- data/.github/workflows/gitleacks.yml +12 -0
- data/.github/workflows/release.yml +1 -0
- data/.github/workflows/ruby.yml +1 -1
- data/CHANGELOG.md +20 -0
- data/Gemfile +6 -3
- data/Gemfile.lock +3 -3
- data/README.md +2 -2
- data/bin/generate_default_app +10 -0
- data/docs/getting_started.md +52 -7
- data/docs/setup_raspi.md +0 -1
- data/lib/procon_bypass_man/background/jobs/base_job.rb +1 -1
- data/lib/procon_bypass_man/background/jobs/concerns/{job_runnable.rb → job_performable.rb} +1 -1
- data/lib/procon_bypass_man/background.rb +1 -1
- data/lib/procon_bypass_man/buttons_setting_configuration/loader.rb +1 -1
- data/lib/procon_bypass_man/{commands → bypass}/bypass_command.rb +11 -19
- data/lib/procon_bypass_man/bypass/usb_hid_logger.rb +0 -1
- data/lib/procon_bypass_man/bypass.rb +9 -14
- data/lib/procon_bypass_man/commands/print_boot_message_command.rb +1 -2
- data/lib/procon_bypass_man/commands/send_error_command.rb +2 -2
- data/lib/procon_bypass_man/commands.rb +0 -3
- data/lib/procon_bypass_man/configuration.rb +22 -3
- data/lib/procon_bypass_man/device_connection/command.rb +28 -0
- data/lib/procon_bypass_man/{device_connector.rb → device_connection/executor.rb} +51 -38
- data/lib/procon_bypass_man/device_connection/output_report_generator.rb +42 -0
- data/lib/procon_bypass_man/device_connection/output_report_markerable.rb +28 -0
- data/lib/procon_bypass_man/device_connection/output_report_sub_command_table.rb +133 -0
- data/lib/procon_bypass_man/device_connection/output_report_watcher.rb +41 -0
- data/lib/procon_bypass_man/device_connection/pre_bypass.rb +67 -0
- data/lib/procon_bypass_man/device_connection/procon_setting_overrider.rb +78 -0
- data/lib/procon_bypass_man/device_connection/spoofing_output_report_watcher.rb +39 -0
- data/lib/procon_bypass_man/device_connection.rb +16 -0
- data/lib/procon_bypass_man/device_model.rb +17 -0
- data/lib/procon_bypass_man/io_monitor.rb +20 -1
- data/lib/procon_bypass_man/procon/macro_builder.rb +5 -3
- data/lib/procon_bypass_man/procon_display/bypass_hook.rb +11 -0
- data/lib/procon_bypass_man/procon_display/http_request.rb +31 -0
- data/lib/procon_bypass_man/procon_display/http_response.rb +23 -0
- data/lib/procon_bypass_man/procon_display/server.rb +33 -0
- data/lib/procon_bypass_man/procon_display/server_app.rb +17 -0
- data/lib/procon_bypass_man/procon_display/status.rb +20 -0
- data/lib/procon_bypass_man/procon_display.rb +11 -0
- data/lib/procon_bypass_man/{commands → remote_pbm_action/commands}/run_remote_pbm_action_dispatch_command.rb +0 -0
- data/lib/procon_bypass_man/remote_pbm_action/restore_pbm_setting.rb +7 -1
- data/lib/procon_bypass_man/remote_pbm_action.rb +1 -0
- data/lib/procon_bypass_man/runner.rb +4 -7
- data/lib/procon_bypass_man/support/callbacks.rb +68 -34
- data/lib/procon_bypass_man/support/never_exit_accidentally.rb +3 -3
- data/lib/procon_bypass_man/support/usb_device_controller.rb +2 -2
- data/lib/procon_bypass_man/support/yaml_loader.rb +12 -0
- data/lib/procon_bypass_man/version.rb +1 -1
- data/lib/procon_bypass_man/websocket/client.rb +1 -4
- data/lib/procon_bypass_man.rb +66 -41
- data/procon_bypass_man.gemspec +1 -1
- data/project_template/README.md +0 -5
- data/project_template/app.rb +24 -6
- data/project_template/app.rb.erb +64 -0
- data/project_template/lib/app_generator.rb +31 -0
- data/project_template/web.rb +1 -1
- data/sig/main.rbs +3 -3
- data/tmp/.keep +0 -0
- metadata +30 -8
- data/lib/procon_bypass_man/commands/connect_device_command.rb +0 -18
@@ -0,0 +1,11 @@
|
|
1
|
+
module ProconBypassMan::ProconDisplay::BypassHook
|
2
|
+
include ProconBypassMan::Callbacks
|
3
|
+
|
4
|
+
define_callbacks :send_procon_to_gadget
|
5
|
+
|
6
|
+
set_callback :send_procon_to_gadget, :after, :write_procon_display_Status
|
7
|
+
|
8
|
+
def write_procon_display_Status
|
9
|
+
ProconBypassMan::ProconDisplay::Status.instance.current = bypass_value.binary.to_procon_reader.to_hash.dup
|
10
|
+
end
|
11
|
+
end
|
@@ -0,0 +1,31 @@
|
|
1
|
+
module ProconBypassMan::ProconDisplay
|
2
|
+
# NOTE Support GET only
|
3
|
+
class HttpRequest
|
4
|
+
def self.parse(conn)
|
5
|
+
headers = {}
|
6
|
+
loop do
|
7
|
+
line = conn.gets("\n")&.strip
|
8
|
+
break if line.nil? || line.strip.empty?
|
9
|
+
key, value = line.split(/:\s/, 2)
|
10
|
+
headers[key] = value
|
11
|
+
end
|
12
|
+
|
13
|
+
new(headers)
|
14
|
+
end
|
15
|
+
|
16
|
+
def initialize(headers)
|
17
|
+
@headers = headers
|
18
|
+
end
|
19
|
+
|
20
|
+
def path
|
21
|
+
request_method_and_path = @headers.detect { |key, _value| key.start_with?("GET") }.first
|
22
|
+
if request_method_and_path =~ /(?:GET) ([^ ]+)/ && (path = $1)
|
23
|
+
return path
|
24
|
+
end
|
25
|
+
end
|
26
|
+
|
27
|
+
def to_hash
|
28
|
+
{ "PATH" => path }
|
29
|
+
end
|
30
|
+
end
|
31
|
+
end
|
@@ -0,0 +1,23 @@
|
|
1
|
+
module ProconBypassMan::ProconDisplay
|
2
|
+
class HttpResponse
|
3
|
+
def initialize(body, status: , format: "text/json")
|
4
|
+
@body = body&.to_json
|
5
|
+
@status = status
|
6
|
+
@format = format
|
7
|
+
end
|
8
|
+
|
9
|
+
def to_s
|
10
|
+
<<~EOH
|
11
|
+
HTTP/1.1 #{@status}
|
12
|
+
Content-Length: #{@body&.bytes&.size || 0}
|
13
|
+
Content-Type: #{@format}
|
14
|
+
Access-Control-Allow-Origin: *
|
15
|
+
Access-Control-Allow-Methods: GET
|
16
|
+
Access-Control-Allow-Private-Network:true
|
17
|
+
Connection: close
|
18
|
+
|
19
|
+
#{@body}
|
20
|
+
EOH
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
@@ -0,0 +1,33 @@
|
|
1
|
+
require 'socket'
|
2
|
+
|
3
|
+
module ProconBypassMan::ProconDisplay
|
4
|
+
class Server
|
5
|
+
PORT = 9900
|
6
|
+
|
7
|
+
def self.start!
|
8
|
+
Thread.new do
|
9
|
+
new.start_with_foreground
|
10
|
+
end
|
11
|
+
end
|
12
|
+
|
13
|
+
def initialize
|
14
|
+
@server = TCPServer.new('0.0.0.0', PORT)
|
15
|
+
end
|
16
|
+
|
17
|
+
def start_with_foreground
|
18
|
+
loop do
|
19
|
+
conn = @server.accept
|
20
|
+
response = ServerApp.new(
|
21
|
+
HttpRequest.parse(conn).to_hash
|
22
|
+
).call
|
23
|
+
conn.write(response)
|
24
|
+
conn.close
|
25
|
+
end
|
26
|
+
rescue Errno::EADDRINUSE => e
|
27
|
+
ProconBypassMan::SendErrorCommand.execute(error: e)
|
28
|
+
rescue => e
|
29
|
+
ProconBypassMan::SendErrorCommand.execute(error: e)
|
30
|
+
retry
|
31
|
+
end
|
32
|
+
end
|
33
|
+
end
|
@@ -0,0 +1,17 @@
|
|
1
|
+
module ProconBypassMan::ProconDisplay
|
2
|
+
class ServerApp
|
3
|
+
def initialize(env)
|
4
|
+
@env = env
|
5
|
+
end
|
6
|
+
|
7
|
+
def call
|
8
|
+
case @env["PATH"]
|
9
|
+
when "/input"
|
10
|
+
response = ProconBypassMan::ProconDisplay::Status.instance.current
|
11
|
+
HttpResponse.new(response, status: 200).to_s
|
12
|
+
else
|
13
|
+
HttpResponse.new(nil, status: 404).to_s
|
14
|
+
end
|
15
|
+
end
|
16
|
+
end
|
17
|
+
end
|
@@ -0,0 +1,20 @@
|
|
1
|
+
require 'singleton'
|
2
|
+
|
3
|
+
class ProconBypassMan::ProconDisplay::Status
|
4
|
+
include Singleton
|
5
|
+
|
6
|
+
# @return [Hash]
|
7
|
+
def current
|
8
|
+
@current || {}
|
9
|
+
end
|
10
|
+
|
11
|
+
# @return [void]
|
12
|
+
# @param [Hash] value
|
13
|
+
def current=(value)
|
14
|
+
if value.is_a?(Hash)
|
15
|
+
@current = value
|
16
|
+
else
|
17
|
+
@current = nil
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
@@ -0,0 +1,11 @@
|
|
1
|
+
# 入力表示用
|
2
|
+
|
3
|
+
module ProconBypassMan::ProconDisplay
|
4
|
+
end
|
5
|
+
|
6
|
+
require "procon_bypass_man/procon_display/server"
|
7
|
+
require "procon_bypass_man/procon_display/server_app"
|
8
|
+
require "procon_bypass_man/procon_display/status"
|
9
|
+
require "procon_bypass_man/procon_display/http_response"
|
10
|
+
require "procon_bypass_man/procon_display/http_request"
|
11
|
+
require "procon_bypass_man/procon_display/bypass_hook"
|
File without changes
|
@@ -17,7 +17,8 @@ module ProconBypassMan
|
|
17
17
|
path: ProconBypassMan::ButtonsSettingConfiguration.instance.setting_path,
|
18
18
|
content: setting,
|
19
19
|
)
|
20
|
-
|
20
|
+
|
21
|
+
hot_reload!
|
21
22
|
end
|
22
23
|
|
23
24
|
private
|
@@ -29,6 +30,11 @@ module ProconBypassMan
|
|
29
30
|
def after_action_callback
|
30
31
|
be_processed
|
31
32
|
end
|
33
|
+
|
34
|
+
# @return [void]
|
35
|
+
def hot_reload!
|
36
|
+
Process.kill(:USR2, ProconBypassMan.pid)
|
37
|
+
end
|
32
38
|
end
|
33
39
|
end
|
34
40
|
end
|
@@ -6,6 +6,7 @@ module ProconBypassMan
|
|
6
6
|
require "procon_bypass_man/remote_pbm_action/stop_pbm_action"
|
7
7
|
require "procon_bypass_man/remote_pbm_action/restore_pbm_setting.rb"
|
8
8
|
require "procon_bypass_man/remote_pbm_action/commands/update_remote_pbm_action_status_command"
|
9
|
+
require "procon_bypass_man/remote_pbm_action/commands/run_remote_pbm_action_dispatch_command"
|
9
10
|
require "procon_bypass_man/remote_pbm_action/value_objects/remote_pbm_action_object"
|
10
11
|
|
11
12
|
ACTION_CHANGE_PBM_VERSION = "change_pbm_version"
|
@@ -8,8 +8,6 @@ class ProconBypassMan::Runner
|
|
8
8
|
def initialize(gadget: , procon: )
|
9
9
|
@gadget = gadget
|
10
10
|
@procon = procon
|
11
|
-
|
12
|
-
ProconBypassMan::PrintBootMessageCommand.execute
|
13
11
|
end
|
14
12
|
|
15
13
|
def run
|
@@ -30,6 +28,7 @@ class ProconBypassMan::Runner
|
|
30
28
|
$will_terminate_token = false
|
31
29
|
DRb.start_service if defined?(DRb)
|
32
30
|
ProconBypassMan::RemoteMacroReceiver.start!
|
31
|
+
ProconBypassMan::ProconDisplay::Server.start!
|
33
32
|
ProconBypassMan::BypassCommand.new(gadget: @gadget, procon: @procon).execute # ここでblockingする
|
34
33
|
next
|
35
34
|
}
|
@@ -41,9 +40,9 @@ class ProconBypassMan::Runner
|
|
41
40
|
handle_signal(signal)
|
42
41
|
end
|
43
42
|
rescue InterruptForRestart
|
43
|
+
ProconBypassMan::PrintMessageCommand.execute(text: "設定ファイルの再読み込みを開始します")
|
44
44
|
Process.kill("USR2", child_pid)
|
45
45
|
Process.wait
|
46
|
-
ProconBypassMan::PrintMessageCommand.execute(text: "Reloading config file")
|
47
46
|
begin
|
48
47
|
ProconBypassMan::ButtonsSettingConfiguration::Loader.reload_setting
|
49
48
|
ProconBypassMan::SendReloadConfigEventCommand.execute
|
@@ -53,12 +52,10 @@ class ProconBypassMan::Runner
|
|
53
52
|
end
|
54
53
|
ProconBypassMan::PrintMessageCommand.execute(text: "バイパス処理を再開します")
|
55
54
|
rescue Interrupt
|
55
|
+
puts
|
56
|
+
ProconBypassMan::PrintMessageCommand.execute(text: "処理を終了します")
|
56
57
|
Process.kill("TERM", child_pid)
|
57
58
|
Process.wait
|
58
|
-
ProconBypassMan::PrintMessageCommand.execute(text: "処理を終了します")
|
59
|
-
ProconBypassMan::UsbDeviceController.reset
|
60
|
-
@gadget&.close
|
61
|
-
@procon&.close
|
62
59
|
break
|
63
60
|
end
|
64
61
|
end
|
@@ -1,21 +1,15 @@
|
|
1
1
|
module ProconBypassMan
|
2
|
-
module
|
3
|
-
|
4
|
-
attr_accessor :filter, :chain_method
|
5
|
-
def initialize(filter: , chain_method: , block: )
|
6
|
-
@filter = filter
|
7
|
-
@chain_method = chain_method
|
8
|
-
@block = block
|
9
|
-
end
|
10
|
-
end
|
2
|
+
module CallbacksRegisterable
|
3
|
+
attr_accessor :callbacks
|
11
4
|
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
end
|
5
|
+
def register_callback_module(mod)
|
6
|
+
self.callbacks ||= []
|
7
|
+
callbacks << mod
|
8
|
+
self.include(mod)
|
17
9
|
end
|
10
|
+
end
|
18
11
|
|
12
|
+
module Callbacks
|
19
13
|
module ClassMethods
|
20
14
|
def define_callbacks(name)
|
21
15
|
self.singleton_class.attr_accessor "_#{name}_callbacks"
|
@@ -29,8 +23,9 @@ module ProconBypassMan
|
|
29
23
|
end
|
30
24
|
|
31
25
|
def set_callback(kind, filter, chain_method, &block)
|
32
|
-
|
33
|
-
|
26
|
+
self.__callbacks ||= {}
|
27
|
+
self.__callbacks[kind] ||= CallbackChain.new
|
28
|
+
self.__callbacks[kind].append Callback.new(
|
34
29
|
filter: filter,
|
35
30
|
chain_method: chain_method,
|
36
31
|
block: block,
|
@@ -38,33 +33,72 @@ module ProconBypassMan
|
|
38
33
|
end
|
39
34
|
end
|
40
35
|
|
36
|
+
def self.included(mod)
|
37
|
+
mod.singleton_class.attr_accessor :__callbacks
|
38
|
+
mod.extend(ClassMethods)
|
39
|
+
end
|
40
|
+
|
41
|
+
class CallbackChain
|
42
|
+
attr_accessor :callbacks
|
43
|
+
|
44
|
+
def initialize
|
45
|
+
self.callbacks = {}
|
46
|
+
end
|
47
|
+
|
48
|
+
def empty?
|
49
|
+
callbacks.empty?
|
50
|
+
end
|
51
|
+
|
52
|
+
def append(callback)
|
53
|
+
self.callbacks[callback.filter] ||= []
|
54
|
+
self.callbacks[callback.filter] << callback
|
55
|
+
end
|
56
|
+
|
57
|
+
def [](filter)
|
58
|
+
self.callbacks[filter]
|
59
|
+
end
|
60
|
+
end
|
61
|
+
|
62
|
+
class Callback
|
63
|
+
attr_accessor :filter, :chain_method
|
64
|
+
|
65
|
+
def initialize(filter: , chain_method: , block: )
|
66
|
+
@filter = filter
|
67
|
+
@chain_method = chain_method
|
68
|
+
@block = block
|
69
|
+
end
|
70
|
+
end
|
71
|
+
|
41
72
|
# TODO haltしたらcallbackを止める
|
42
|
-
# TODO 複数をチェインできるようにする
|
43
73
|
def run_callbacks(kind, &block)
|
44
|
-
|
45
|
-
|
46
|
-
when :before
|
47
|
-
send chain.chain_method
|
48
|
-
block.call
|
49
|
-
when :after
|
74
|
+
chains = get_callbacks(kind) or raise("unknown callback")
|
75
|
+
if chains.nil? || chains.empty?
|
50
76
|
block.call
|
77
|
+
return
|
78
|
+
end
|
79
|
+
|
80
|
+
chains[:before]&.each do |chain|
|
81
|
+
send chain.chain_method
|
82
|
+
end
|
83
|
+
block.call
|
84
|
+
chains[:after]&.each do |chain|
|
51
85
|
send chain.chain_method
|
52
|
-
else
|
53
|
-
raise("unknown filter")
|
54
86
|
end
|
55
87
|
end
|
56
88
|
|
57
|
-
# def __run_callbacks__(name, &block)
|
58
|
-
# puts "called"
|
59
|
-
# end
|
60
|
-
|
61
89
|
def get_callbacks(kind) # :nodoc:
|
62
|
-
|
63
|
-
|
90
|
+
# classに直接moduleをincludeしている場合
|
91
|
+
if defined?(self.class.__callbacks)
|
92
|
+
return self.class.__callbacks[kind.to_sym]
|
93
|
+
end
|
64
94
|
|
65
|
-
|
66
|
-
|
67
|
-
|
95
|
+
list = self.class.callbacks.flat_map { |callback_mod|
|
96
|
+
callback_mod.__callbacks && callback_mod.__callbacks[kind.to_sym]
|
97
|
+
}.compact
|
98
|
+
table = {}
|
99
|
+
table[:before] = list.flat_map { |x| x[:before] }.compact
|
100
|
+
table[:after] = list.flat_map { |x| x[:after] }.compact
|
101
|
+
table
|
68
102
|
end
|
69
103
|
end
|
70
104
|
end
|
@@ -1,11 +1,11 @@
|
|
1
1
|
module ProconBypassMan
|
2
2
|
module NeverExitAccidentally
|
3
|
-
def
|
3
|
+
def self.exit_if_allow_at_config
|
4
4
|
if ProconBypassMan.never_exit_accidentally
|
5
|
-
eternal_sleep
|
5
|
+
ProconBypassMan.eternal_sleep
|
6
6
|
else
|
7
7
|
yield if block_given?
|
8
|
-
exit
|
8
|
+
exit 1
|
9
9
|
end
|
10
10
|
end
|
11
11
|
end
|
@@ -1,13 +1,13 @@
|
|
1
1
|
class ProconBypassMan::UsbDeviceController
|
2
2
|
class << self
|
3
|
-
def reset
|
3
|
+
def reset(cooldown: 0.5)
|
4
4
|
[ "echo > /sys/kernel/config/usb_gadget/procon/UDC",
|
5
5
|
"ls /sys/class/udc > /sys/kernel/config/usb_gadget/procon/UDC",
|
6
6
|
].each do |shell|
|
7
7
|
system shell
|
8
8
|
ProconBypassMan.logger.debug { "[SHELL] #{shell}" }
|
9
9
|
end
|
10
|
-
sleep
|
10
|
+
sleep cooldown
|
11
11
|
end
|
12
12
|
|
13
13
|
def init
|
@@ -0,0 +1,12 @@
|
|
1
|
+
class ProconBypassMan::YamlLoader
|
2
|
+
# @param [String] path
|
3
|
+
# @return [Hash]
|
4
|
+
def self.load(path: )
|
5
|
+
YAML.load_file(path).tap do |y|
|
6
|
+
# 行末に空白があるとto_yamlしたときに改行コードがエスケープされてしまうのでstrip
|
7
|
+
y.transform_values do |v|
|
8
|
+
v.strip! if v.is_a?(String)
|
9
|
+
end
|
10
|
+
end
|
11
|
+
end
|
12
|
+
end
|
@@ -23,8 +23,7 @@ module ProconBypassMan
|
|
23
23
|
ProconBypassMan.logger.info('websocket client: successfully connected in ProconBypassMan::Websocket::Client')
|
24
24
|
}
|
25
25
|
client.subscribed { |msg|
|
26
|
-
ProconBypassMan.logger.info(
|
27
|
-
puts({ event: :subscribed, msg: msg })
|
26
|
+
ProconBypassMan.logger.info("websocket client: subscribed(#{msg})")
|
28
27
|
ProconBypassMan::SyncDeviceStatsJob.perform(ProconBypassMan::DeviceStatus.current)
|
29
28
|
}
|
30
29
|
|
@@ -39,13 +38,11 @@ module ProconBypassMan
|
|
39
38
|
|
40
39
|
client.disconnected {
|
41
40
|
ProconBypassMan.logger.info('websocket client: disconnected!!')
|
42
|
-
puts :disconnected
|
43
41
|
client.reconnect!
|
44
42
|
sleep 2
|
45
43
|
}
|
46
44
|
client.errored { |msg|
|
47
45
|
ProconBypassMan.logger.error("websocket client: errored!!, #{msg}")
|
48
|
-
puts :errored
|
49
46
|
client.reconnect!
|
50
47
|
sleep 2
|
51
48
|
}
|
data/lib/procon_bypass_man.rb
CHANGED
@@ -14,11 +14,14 @@ require "pbmenv"
|
|
14
14
|
require_relative "procon_bypass_man/version"
|
15
15
|
require_relative "procon_bypass_man/remote_pbm_action"
|
16
16
|
require_relative "procon_bypass_man/remote_macro"
|
17
|
+
|
18
|
+
require_relative "procon_bypass_man/device_connection"
|
17
19
|
require_relative "procon_bypass_man/support/usb_device_controller"
|
18
20
|
require_relative "procon_bypass_man/support/device_procon_finder"
|
19
21
|
require_relative "procon_bypass_man/support/device_mouse_finder"
|
20
22
|
require_relative "procon_bypass_man/support/signal_handler"
|
21
23
|
require_relative "procon_bypass_man/support/callbacks"
|
24
|
+
require_relative "procon_bypass_man/support/yaml_loader"
|
22
25
|
require_relative "procon_bypass_man/support/yaml_writer"
|
23
26
|
require_relative "procon_bypass_man/support/safe_timeout"
|
24
27
|
require_relative "procon_bypass_man/support/compress_array"
|
@@ -33,16 +36,17 @@ require_relative "procon_bypass_man/support/server_pool"
|
|
33
36
|
require_relative "procon_bypass_man/support/analog_stick_hypotenuse_tilting_power_scaler"
|
34
37
|
require_relative "procon_bypass_man/support/never_exit_accidentally"
|
35
38
|
require_relative "procon_bypass_man/support/cycle_sleep"
|
39
|
+
require_relative "procon_bypass_man/procon_display"
|
36
40
|
require_relative "procon_bypass_man/background"
|
37
41
|
require_relative "procon_bypass_man/commands"
|
38
42
|
require_relative "procon_bypass_man/bypass"
|
39
|
-
require_relative "procon_bypass_man/device_connector"
|
40
43
|
require_relative "procon_bypass_man/device_status"
|
41
44
|
require_relative "procon_bypass_man/runner"
|
42
45
|
require_relative "procon_bypass_man/processor"
|
43
46
|
require_relative "procon_bypass_man/configuration"
|
44
47
|
require_relative "procon_bypass_man/buttons_setting_configuration"
|
45
48
|
require_relative "procon_bypass_man/procon"
|
49
|
+
require_relative "procon_bypass_man/device_model"
|
46
50
|
require_relative "procon_bypass_man/procon/button"
|
47
51
|
require_relative "procon_bypass_man/procon/analog_stick_cap"
|
48
52
|
require_relative "procon_bypass_man/procon/analog_stick_manipulator"
|
@@ -61,52 +65,59 @@ module ProconBypassMan
|
|
61
65
|
extend ProconBypassMan::NeverExitAccidentally
|
62
66
|
|
63
67
|
class CouldNotLoadConfigError < StandardError; end
|
64
|
-
class
|
68
|
+
class NotFoundProconError < StandardError; end
|
65
69
|
|
66
70
|
# @return [void]
|
67
71
|
def self.run(setting_path: nil)
|
68
|
-
ProconBypassMan::Scheduler.start!
|
69
|
-
ProconBypassMan::Background::JobRunner.start!
|
70
|
-
ProconBypassMan::Websocket::Client.start!
|
71
|
-
ProconBypassMan::QueueOverProcess.start!
|
72
|
-
|
73
72
|
ProconBypassMan::PrintMessageCommand.execute(text: "PBMを起動しています")
|
74
73
|
initialize_pbm
|
75
|
-
|
76
|
-
|
77
|
-
|
78
|
-
|
79
|
-
|
80
|
-
|
81
|
-
|
82
|
-
|
83
|
-
|
84
|
-
|
85
|
-
|
86
|
-
FileUtils.rm_rf(ProconBypassMan.pid_path)
|
87
|
-
FileUtils.rm_rf(ProconBypassMan.digest_path)
|
88
|
-
ProconBypassMan::QueueOverProcess.shutdown
|
74
|
+
|
75
|
+
begin
|
76
|
+
ProconBypassMan::ButtonsSettingConfiguration::Loader.load(setting_path: setting_path)
|
77
|
+
rescue ProconBypassMan::CouldNotLoadConfigError
|
78
|
+
ProconBypassMan::SendErrorCommand.execute(error: "設定ファイルが不正です。設定ファイルの読み込みに失敗しました")
|
79
|
+
ProconBypassMan::DeviceStatus.change_to_setting_syntax_error_and_shutdown!
|
80
|
+
# TODO シグナルトラップをしていないのでUSR2を送ったときにプロセスが停止している. 明示的にハンドリングするべき.
|
81
|
+
ProconBypassMan::NeverExitAccidentally.exit_if_allow_at_config do
|
82
|
+
terminate_pbm
|
83
|
+
end
|
84
|
+
return
|
89
85
|
end
|
90
|
-
|
91
|
-
|
92
|
-
|
93
|
-
|
94
|
-
|
95
|
-
|
96
|
-
|
97
|
-
ProconBypassMan::
|
86
|
+
|
87
|
+
begin
|
88
|
+
gadget, procon = ProconBypassMan::DeviceConnection::Command.execute!
|
89
|
+
rescue ProconBypassMan::DeviceConnection::NotFoundProconError
|
90
|
+
ProconBypassMan::SendErrorCommand.execute(error: "プロコンが見つかりませんでした。")
|
91
|
+
ProconBypassMan::DeviceStatus.change_to_procon_not_found_error!
|
92
|
+
# TODO シグナルトラップをしていないので以下の状態に、USR2を送ったときにプロセスが停止してしまう
|
93
|
+
ProconBypassMan::NeverExitAccidentally.exit_if_allow_at_config do
|
94
|
+
terminate_pbm
|
95
|
+
end
|
96
|
+
return
|
97
|
+
rescue ProconBypassMan::DeviceConnection::TimeoutError
|
98
|
+
ProconBypassMan::SendErrorCommand.execute(error: "接続の見込みがないのでsleepしまくります")
|
99
|
+
ProconBypassMan::DeviceStatus.change_to_connected_but_sleeping!
|
100
|
+
%w(TERM INT).each do |sig|
|
101
|
+
Kernel.trap(sig) { exit 0 }
|
102
|
+
end
|
103
|
+
Kernel.trap :USR2 do
|
104
|
+
exit 0 # TODO retryする
|
105
|
+
end
|
106
|
+
eternal_sleep
|
107
|
+
return
|
98
108
|
end
|
99
|
-
|
100
|
-
|
101
|
-
|
102
|
-
|
103
|
-
eternal_sleep
|
109
|
+
|
110
|
+
ready_pbm
|
111
|
+
Runner.new(gadget: gadget, procon: procon).run # ここでblockingする
|
112
|
+
terminate_pbm
|
104
113
|
end
|
105
114
|
|
115
|
+
# 実行ファイル(app.rb)から呼び出している
|
116
|
+
# @return [void]
|
106
117
|
def self.configure(&block)
|
107
118
|
@@configuration = ProconBypassMan::Configuration.new
|
108
119
|
@@configuration.instance_eval(&block)
|
109
|
-
|
120
|
+
nil
|
110
121
|
end
|
111
122
|
|
112
123
|
# @return [ProconBypassMan::Configuration]
|
@@ -123,20 +134,34 @@ module ProconBypassMan
|
|
123
134
|
ProconBypassMan::IOMonitor.reset!
|
124
135
|
end
|
125
136
|
|
137
|
+
# @return [void]
|
126
138
|
def self.initialize_pbm
|
139
|
+
ProconBypassMan::Scheduler.start!
|
140
|
+
ProconBypassMan::Background::JobRunner.start!
|
141
|
+
ProconBypassMan::Websocket::Client.start!
|
142
|
+
ProconBypassMan::QueueOverProcess.start!
|
143
|
+
|
127
144
|
ProconBypassMan::WriteDeviceIdCommand.execute
|
128
145
|
ProconBypassMan::WriteSessionIdCommand.execute
|
129
|
-
|
146
|
+
`renice -n -20 -p #{$$}`
|
130
147
|
File.write(pid_path, $$)
|
131
148
|
ProconBypassMan::DeviceStatus.change_to_running!
|
132
149
|
end
|
133
150
|
|
134
|
-
def self.
|
135
|
-
|
151
|
+
def self.ready_pbm
|
152
|
+
ProconBypassMan::PrintBootMessageCommand.execute
|
153
|
+
ProconBypassMan::ReportLoadConfigJob.perform_async(ProconBypassMan.config.raw_setting)
|
154
|
+
end
|
155
|
+
|
156
|
+
# @return [void]
|
157
|
+
def self.terminate_pbm
|
158
|
+
FileUtils.rm_rf(ProconBypassMan.pid_path)
|
159
|
+
FileUtils.rm_rf(ProconBypassMan.digest_path)
|
160
|
+
ProconBypassMan::QueueOverProcess.shutdown
|
136
161
|
end
|
137
162
|
|
138
|
-
# @return [
|
139
|
-
def self.
|
140
|
-
|
163
|
+
# @return [void]
|
164
|
+
def self.eternal_sleep
|
165
|
+
sleep(999999999)
|
141
166
|
end
|
142
167
|
end
|
data/procon_bypass_man.gemspec
CHANGED
@@ -12,7 +12,7 @@ Gem::Specification.new do |spec|
|
|
12
12
|
spec.description = spec.summary
|
13
13
|
spec.homepage = "https://github.com/splaplapla/procon_bypass_man"
|
14
14
|
spec.license = "MIT"
|
15
|
-
spec.required_ruby_version = Gem::Requirement.new(">=
|
15
|
+
spec.required_ruby_version = Gem::Requirement.new(">= 2.5.0")
|
16
16
|
|
17
17
|
spec.metadata["homepage_uri"] = spec.homepage
|
18
18
|
spec.metadata["source_code_uri"] = spec.homepage
|
data/project_template/README.md
CHANGED
@@ -1,6 +1,5 @@
|
|
1
1
|
# Project Template
|
2
2
|
* これらは https://github.com/splaplapla/pbmenv がinstallするときに配備するファイルです
|
3
|
-
* pbm_webはオプショナルです
|
4
3
|
|
5
4
|
## systemdを使ってサービスに登録する方法
|
6
5
|
systemctl enableした後は、次回のOS起動時にserviceも自動起動します
|
@@ -8,13 +7,9 @@ systemctl enableした後は、次回のOS起動時にserviceも自動起動し
|
|
8
7
|
* pbm
|
9
8
|
* sudo systemctl link /usr/share/pbm/current/systemd_units/pbm.service
|
10
9
|
* sudo systemctl enable pbm.service
|
11
|
-
* pbm_web
|
12
|
-
* sudo systemctl link /usr/share/pbm/current/systemd_units/pbm_web.service
|
13
|
-
* sudo systemctl enable pbm_web.service
|
14
10
|
|
15
11
|
## systemdを使ってサービスから解除する方法
|
16
12
|
* sudo systemctl disable pbm.service
|
17
|
-
* sudo systemctl disable pbm_web.service
|
18
13
|
|
19
14
|
### CheatSheet
|
20
15
|
* systemctl daemon-reload
|