procon_bypass_man 0.1.23 → 0.2.2
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 +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
|