procon_bypass_man 0.1.8 → 0.1.9
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/.ruby-version +1 -1
- data/CHANGELOG.md +7 -1
- data/Gemfile +4 -0
- data/Gemfile.lock +52 -2
- data/README.md +11 -0
- data/Steepfile +39 -0
- data/bin/report_receive_server.rb +11 -0
- data/docs/setup_raspi.mitamae.rb +12 -0
- data/lib/procon_bypass_man/analog_stick_position.rb +14 -0
- data/lib/procon_bypass_man/boot_message.rb +40 -0
- data/lib/procon_bypass_man/bypass.rb +20 -7
- data/lib/procon_bypass_man/configuration/layer.rb +33 -3
- data/lib/procon_bypass_man/configuration.rb +22 -8
- data/lib/procon_bypass_man/device_connector.rb +10 -27
- data/lib/procon_bypass_man/error_reporter.rb +44 -0
- data/lib/procon_bypass_man/io_monitor.rb +7 -4
- data/lib/procon_bypass_man/on_memory_cache.rb +34 -0
- data/lib/procon_bypass_man/procon/analog_stick_cap.rb +88 -0
- data/lib/procon_bypass_man/procon/button_collection.rb +14 -6
- data/lib/procon_bypass_man/procon/debug_dumper.rb +17 -0
- data/lib/procon_bypass_man/procon/mode_registry.rb +2 -2
- data/lib/procon_bypass_man/procon/press_button_aware.rb +13 -0
- data/lib/procon_bypass_man/procon/pressed_button_helper.rb +0 -10
- data/lib/procon_bypass_man/procon/user_operation.rb +10 -3
- data/lib/procon_bypass_man/procon.rb +15 -1
- data/lib/procon_bypass_man/reporter.rb +42 -0
- data/lib/procon_bypass_man/runner.rb +34 -46
- data/lib/procon_bypass_man/uptime.rb +1 -1
- data/lib/procon_bypass_man/version.rb +1 -1
- data/lib/procon_bypass_man.rb +43 -2
- data/project_template/app.rb +3 -1
- data/sig/README.rb +4 -0
- data/sig/main.rbs +467 -0
- metadata +15 -3
@@ -0,0 +1,34 @@
|
|
1
|
+
class ProconBypassMan::OnMemoryCache
|
2
|
+
class CacheValue
|
3
|
+
attr_accessor :expired_at, :value
|
4
|
+
|
5
|
+
def initialize(expired_at: , value: )
|
6
|
+
self.expired_at = expired_at
|
7
|
+
self.value = value
|
8
|
+
end
|
9
|
+
end
|
10
|
+
|
11
|
+
def initialize
|
12
|
+
@table = {}
|
13
|
+
end
|
14
|
+
|
15
|
+
# @param [Integer] expires_in 秒数
|
16
|
+
# @param [String] key
|
17
|
+
def fetch(key: , expires_in: , &block)
|
18
|
+
now = Time.now
|
19
|
+
if @table[key].nil?
|
20
|
+
value = block.call
|
21
|
+
value_object = CacheValue.new(expired_at: now + expires_in, value: value)
|
22
|
+
@table[key] = value_object
|
23
|
+
return value
|
24
|
+
end
|
25
|
+
|
26
|
+
if @table[key].expired_at < now
|
27
|
+
value = block.call
|
28
|
+
@table[key] = CacheValue.new(expired_at: now + expires_in, value: value)
|
29
|
+
return value
|
30
|
+
else
|
31
|
+
return @table[key].value
|
32
|
+
end
|
33
|
+
end
|
34
|
+
end
|
@@ -0,0 +1,88 @@
|
|
1
|
+
class ProconBypassMan::Procon::AnalogStickCap
|
2
|
+
class Position
|
3
|
+
attr_accessor :x, :y
|
4
|
+
|
5
|
+
def initialize(x:, y:)
|
6
|
+
@x = x.to_i
|
7
|
+
@y = y.to_i
|
8
|
+
end
|
9
|
+
|
10
|
+
def to_binary
|
11
|
+
analog_stick_data = [
|
12
|
+
(@x & "0xff".to_i(16)),
|
13
|
+
((@y << 4) & "0xf0".to_i(16)) | ((@x >> 8) & "0x0f".to_i(16)),
|
14
|
+
(@y >> 4) & "0xff".to_i(16),
|
15
|
+
]
|
16
|
+
hex = analog_stick_data.map{ |x| x.to_s(16).rjust(2, "0") }.join
|
17
|
+
[hex].pack("H*")
|
18
|
+
end
|
19
|
+
end
|
20
|
+
|
21
|
+
attr_accessor :bin_x, :bin_y
|
22
|
+
attr_accessor :neutral_position
|
23
|
+
|
24
|
+
def initialize(binary)
|
25
|
+
@neutral_position = ProconBypassMan::Configuration.instance.neutral_position
|
26
|
+
@binary = binary
|
27
|
+
|
28
|
+
byte6 = binary[6].unpack("H*").first.to_i(16).to_s(2).rjust(8, "0")
|
29
|
+
byte7 = binary[7].unpack("H*").first.to_i(16).to_s(2).rjust(8, "0")
|
30
|
+
byte8 = binary[8].unpack("H*").first.to_i(16).to_s(2).rjust(8, "0")
|
31
|
+
|
32
|
+
self.bin_x = "#{byte7[4..7]}#{byte6}"
|
33
|
+
self.bin_y = "#{byte8}#{byte7[0..3]}"
|
34
|
+
end
|
35
|
+
|
36
|
+
# @return [ProconBypassMan::Procon::AnalogStickCap::Position]
|
37
|
+
def capped_position(cap_hypotenuse: )
|
38
|
+
if hypotenuse > cap_hypotenuse
|
39
|
+
relative_capped_x = cap_hypotenuse * Math.cos(rad * Math::PI / 180).abs
|
40
|
+
relative_capped_y = cap_hypotenuse * Math.sin(rad * Math::PI / 180).abs
|
41
|
+
relative_capped_x = -(relative_capped_x.abs) if relative_x.negative?
|
42
|
+
relative_capped_y = -(relative_capped_y.abs) if relative_y.negative?
|
43
|
+
return Position.new(
|
44
|
+
x: relative_capped_x + neutral_position.x,
|
45
|
+
y: relative_capped_y + neutral_position.y,
|
46
|
+
)
|
47
|
+
else
|
48
|
+
return position
|
49
|
+
end
|
50
|
+
end
|
51
|
+
|
52
|
+
# @return [ProconBypassMan::Procon::AnalogStickCap::Position]
|
53
|
+
def position
|
54
|
+
Position.new(x: abs_x, y: abs_y)
|
55
|
+
end
|
56
|
+
|
57
|
+
# 0, 0からのx
|
58
|
+
def abs_x
|
59
|
+
bin_x.to_i(2)
|
60
|
+
end
|
61
|
+
|
62
|
+
# 0, 0からのy
|
63
|
+
def abs_y
|
64
|
+
bin_y.to_i(2)
|
65
|
+
end
|
66
|
+
|
67
|
+
def relative_x
|
68
|
+
bin_x.to_i(2) - neutral_position.x
|
69
|
+
end
|
70
|
+
|
71
|
+
def relative_y
|
72
|
+
bin_y.to_i(2) - neutral_position.y
|
73
|
+
end
|
74
|
+
|
75
|
+
# @deprecated
|
76
|
+
def x; relative_x; end
|
77
|
+
def y; relative_y; end
|
78
|
+
|
79
|
+
def rad
|
80
|
+
(
|
81
|
+
Math.atan(y / x.to_f) * 180 / Math::PI
|
82
|
+
).floor(6)
|
83
|
+
end
|
84
|
+
|
85
|
+
def hypotenuse
|
86
|
+
Math.sqrt(x**2 + y**2).floor(6)
|
87
|
+
end
|
88
|
+
end
|
@@ -8,15 +8,20 @@ class ProconBypassMan::Procon::ButtonCollection
|
|
8
8
|
end
|
9
9
|
end
|
10
10
|
|
11
|
+
# https://github.com/dekuNukem/Nintendo_Switch_Reverse_Engineering/blob/ac8093c84194b3232acb675ac1accce9bcb456a3/bluetooth_hid_notes.md
|
12
|
+
#0) Input report ID
|
13
|
+
#1) Timer. Increments very fast. Can be used to estimate excess Bluetooth latency.
|
14
|
+
#2 high nibble) Battery level. 8=full, 6=medium, 4=low, 2=critical, 0=empty. LSB=Charging.
|
15
|
+
#2 low nibble) Connection info. (con_info >> 1) & 3 - 3=JC, 0=Pro/ChrGrip. con_info & 1 - 1=Switch/USB powered.
|
11
16
|
#3) ZR R SR(right) SL(right) A B X Y
|
12
17
|
#4) Grip (none) Cap Home ThumbL ThumbR + -
|
13
18
|
#5) ZL L SL(left) SR(left) Left Right Up Down
|
14
|
-
#6) analog[0]
|
15
|
-
#7) analog[1]
|
16
|
-
#8) analog[2]
|
17
|
-
#9) analog[3]
|
18
|
-
#a) analog[4]
|
19
|
-
#b) analog[5]
|
19
|
+
#6) analog[0] Left analog stick data
|
20
|
+
#7) analog[1] Left analog stick data
|
21
|
+
#8) analog[2] Left analog stick data
|
22
|
+
#9) analog[3] Right analog stick data
|
23
|
+
#a) analog[4] Right analog stick data
|
24
|
+
#b) analog[5] Right analog stick data
|
20
25
|
BYTES_MAP = {
|
21
26
|
0 => nil,
|
22
27
|
1 => nil,
|
@@ -24,6 +29,9 @@ class ProconBypassMan::Procon::ButtonCollection
|
|
24
29
|
3 => [:zr, :r, :sr, :sl, :a, :b, :x, :y],
|
25
30
|
4 => [:grip, :_undefined_key, :cap, :home, :thumbl, :thumbr, :plus, :minus],
|
26
31
|
5 => [:zl, :l, :sl, :sr, :left, :right, :up, :down],
|
32
|
+
6 => [],
|
33
|
+
7 => [],
|
34
|
+
8 => [],
|
27
35
|
}.freeze
|
28
36
|
|
29
37
|
BUTTONS_MAP = BYTES_MAP.reduce({}) { |acc, value|
|
@@ -0,0 +1,17 @@
|
|
1
|
+
class ProconBypassMan::Procon::DebugDumper
|
2
|
+
def initialize(binary: )
|
3
|
+
@binary = binary
|
4
|
+
# ProconBypassMan.logger.debug { "<<< patched #{@binary.unpack("H*")}" }
|
5
|
+
end
|
6
|
+
|
7
|
+
def dump_analog_sticks
|
8
|
+
byte6 = @binary[6].unpack("H*").first.to_i(16).to_s(2).rjust(8, "0")
|
9
|
+
byte7 = @binary[7].unpack("H*").first.to_i(16).to_s(2).rjust(8, "0")
|
10
|
+
byte8 = @binary[8].unpack("H*").first.to_i(16).to_s(2).rjust(8, "0")
|
11
|
+
|
12
|
+
x = "#{byte7[4..7]}#{byte6}"
|
13
|
+
y = "#{byte8}#{byte7[0..3]}"
|
14
|
+
ProconBypassMan.logger.debug "x: #{x}, val: #{x.to_i(2)}"
|
15
|
+
ProconBypassMan.logger.debug "y: #{y}, val: #{y.to_i(2)}"
|
16
|
+
end
|
17
|
+
end
|
@@ -23,10 +23,10 @@ class ProconBypassMan::Procon::ModeRegistry
|
|
23
23
|
}
|
24
24
|
|
25
25
|
def self.install_plugin(klass)
|
26
|
-
if plugins[klass.name]
|
26
|
+
if plugins[klass.name.to_sym]
|
27
27
|
raise "すでに登録済みです"
|
28
28
|
end
|
29
|
-
plugins[klass.name] = klass.binaries
|
29
|
+
plugins[klass.name.to_sym] = klass.binaries
|
30
30
|
end
|
31
31
|
|
32
32
|
def self.load(name)
|
@@ -0,0 +1,13 @@
|
|
1
|
+
class ProconBypassMan::PpressButtonAware
|
2
|
+
def initialize(binary)
|
3
|
+
@binary = binary
|
4
|
+
end
|
5
|
+
|
6
|
+
def pressed_button?(button)
|
7
|
+
@binary[
|
8
|
+
::ProconBypassMan::Procon::ButtonCollection.load(button).byte_position
|
9
|
+
].unpack("H*").first.to_i(16).to_s(2).reverse[
|
10
|
+
::ProconBypassMan::Procon::ButtonCollection.load(button).bit_position
|
11
|
+
] == '1'
|
12
|
+
end
|
13
|
+
end
|
@@ -1,14 +1,4 @@
|
|
1
1
|
module ProconBypassMan::Procon::PushedButtonHelper
|
2
|
-
module Static
|
3
|
-
def pressed_button?(button)
|
4
|
-
binary[
|
5
|
-
::ProconBypassMan::Procon::ButtonCollection.load(button).byte_position
|
6
|
-
].unpack("H*").first.to_i(16).to_s(2).reverse[
|
7
|
-
::ProconBypassMan::Procon::ButtonCollection.load(button).bit_position
|
8
|
-
] == '1'
|
9
|
-
end
|
10
|
-
end
|
11
|
-
|
12
2
|
module Dynamic
|
13
3
|
@@compiled = false
|
14
4
|
def compile_if_not_compile_yet!
|
@@ -1,7 +1,6 @@
|
|
1
1
|
class ProconBypassMan::Procon
|
2
2
|
class UserOperation
|
3
3
|
include LayerChangeable
|
4
|
-
include PushedButtonHelper::Static
|
5
4
|
extend PushedButtonHelper::Dynamic
|
6
5
|
|
7
6
|
attr_reader :binary
|
@@ -33,13 +32,17 @@ class ProconBypassMan::Procon
|
|
33
32
|
|
34
33
|
def unpress_button(button)
|
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
|
|
39
|
+
def apply_left_analog_stick_cap(cap: )
|
40
|
+
binary[6..8] = ProconBypassMan::Procon::AnalogStickCap.new(binary).capped_position(cap_hypotenuse: cap).to_binary
|
41
|
+
end
|
42
|
+
|
40
43
|
def press_button(button)
|
41
44
|
byte_position = ButtonCollection.load(button).byte_position
|
42
|
-
value = binary[byte_position].unpack("H*").first.to_i(16) + 2**ButtonCollection.load(button).bit_position
|
45
|
+
value = binary[byte_position].unpack("H*").first.to_i(16) + (2**ButtonCollection.load(button).bit_position)
|
43
46
|
binary[byte_position] = ["%02X" % value.to_s].pack("H*")
|
44
47
|
end
|
45
48
|
|
@@ -68,5 +71,9 @@ class ProconBypassMan::Procon
|
|
68
71
|
binary[11] = tb[11]
|
69
72
|
self.binary
|
70
73
|
end
|
74
|
+
|
75
|
+
def pressed_button?(button)
|
76
|
+
ProconBypassMan::PpressButtonAware.new(binary).pressed_button?(button)
|
77
|
+
end
|
71
78
|
end
|
72
79
|
end
|
@@ -7,6 +7,7 @@ class ProconBypassMan::Procon
|
|
7
7
|
require "procon_bypass_man/procon/pressed_button_helper"
|
8
8
|
require "procon_bypass_man/procon/user_operation"
|
9
9
|
require "procon_bypass_man/procon/flip_cache"
|
10
|
+
require "procon_bypass_man/procon/press_button_aware"
|
10
11
|
|
11
12
|
attr_accessor :user_operation
|
12
13
|
|
@@ -94,6 +95,15 @@ class ProconBypassMan::Procon
|
|
94
95
|
return user_operation.binary
|
95
96
|
end
|
96
97
|
|
98
|
+
current_layer.left_analog_stick_caps.each do |button, options|
|
99
|
+
if button.nil? || button.all? { |b| user_operation.pressed_button?(b) }
|
100
|
+
options[:force_neutral]&.each do |force_neutral_button|
|
101
|
+
user_operation.pressed_button?(force_neutral_button) && user_operation.unpress_button(force_neutral_button)
|
102
|
+
end
|
103
|
+
user_operation.apply_left_analog_stick_cap(cap: options[:cap])
|
104
|
+
end
|
105
|
+
end
|
106
|
+
|
97
107
|
current_layer.flip_buttons.each do |button, options|
|
98
108
|
# 何もしないで常に連打
|
99
109
|
if !options[:if_pressed] && status[button]
|
@@ -123,7 +133,11 @@ class ProconBypassMan::Procon
|
|
123
133
|
end
|
124
134
|
end
|
125
135
|
|
126
|
-
user_operation.binary
|
136
|
+
b = user_operation.binary
|
137
|
+
ProconBypassMan.cache.fetch key: 'user_operation.binary', expires_in: 60 do
|
138
|
+
ProconBypassMan::Procon::DebugDumper.new(binary: b).dump_analog_sticks
|
139
|
+
end
|
140
|
+
b
|
127
141
|
end
|
128
142
|
|
129
143
|
private
|
@@ -0,0 +1,42 @@
|
|
1
|
+
require "net/http"
|
2
|
+
require "json"
|
3
|
+
|
4
|
+
class ProconBypassMan::Reporter
|
5
|
+
PATH = "/api/reports" # POST
|
6
|
+
|
7
|
+
class Client
|
8
|
+
def initialize
|
9
|
+
@server = ProconBypassMan.api_server
|
10
|
+
@hostname = `hostname`.chomp
|
11
|
+
end
|
12
|
+
|
13
|
+
def post(body: )
|
14
|
+
# TODO ここでvalidationする
|
15
|
+
if @server.nil?
|
16
|
+
ProconBypassMan.logger.info('送信先が未設定なのでスキップしました')
|
17
|
+
return
|
18
|
+
end
|
19
|
+
|
20
|
+
uri = URI.parse("#{@server}#{PATH}")
|
21
|
+
http = Net::HTTP.new(uri.host, uri.port)
|
22
|
+
http.use_ssl = uri.scheme === "https"
|
23
|
+
response = http.post(
|
24
|
+
uri.path,
|
25
|
+
{ report: body.to_json, hostname: @hostname }.to_json,
|
26
|
+
{ "Content-Type" => "application/json" },
|
27
|
+
)
|
28
|
+
unless response.code == /^20/
|
29
|
+
ProconBypassMan.logger.error(response.body)
|
30
|
+
end
|
31
|
+
rescue => e
|
32
|
+
puts e
|
33
|
+
ProconBypassMan.logger.error(e)
|
34
|
+
end
|
35
|
+
end
|
36
|
+
|
37
|
+
def self.report(body: )
|
38
|
+
Client.new.post(body: body)
|
39
|
+
rescue => e
|
40
|
+
ProconBypassMan.logger.error(e)
|
41
|
+
end
|
42
|
+
end
|
@@ -1,14 +1,10 @@
|
|
1
1
|
require_relative "io_monitor"
|
2
2
|
require_relative "uptime"
|
3
|
+
require_relative "boot_message"
|
3
4
|
|
4
5
|
class ProconBypassMan::Runner
|
5
6
|
class InterruptForRestart < StandardError; end
|
6
7
|
|
7
|
-
def initialize
|
8
|
-
$will_interval_0_0_0_5 = 0
|
9
|
-
$will_interval_1_6 = 0
|
10
|
-
end
|
11
|
-
|
12
8
|
def run
|
13
9
|
first_negotiation
|
14
10
|
print_booted_message
|
@@ -61,13 +57,6 @@ class ProconBypassMan::Runner
|
|
61
57
|
private
|
62
58
|
|
63
59
|
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
60
|
ProconBypassMan::IOMonitor.start!
|
72
61
|
# gadget => procon
|
73
62
|
# 遅くていい
|
@@ -75,17 +64,27 @@ class ProconBypassMan::Runner
|
|
75
64
|
monitor2 = ProconBypassMan::IOMonitor.new(label: "procon -> switch")
|
76
65
|
ProconBypassMan.logger.info "Thread1を起動します"
|
77
66
|
t1 = Thread.new do
|
67
|
+
timer = ProconBypassMan::Timer.new(timeout: Time.now + 10)
|
78
68
|
bypass = ProconBypassMan::Bypass.new(gadget: @gadget, procon: @procon, monitor: monitor1)
|
79
|
-
|
80
|
-
|
81
|
-
|
82
|
-
|
83
|
-
|
84
|
-
|
85
|
-
|
86
|
-
|
87
|
-
|
69
|
+
loop do
|
70
|
+
break if $will_terminate_token
|
71
|
+
timer.throw_if_timeout!
|
72
|
+
bypass.send_gadget_to_procon!
|
73
|
+
sleep(0.005)
|
74
|
+
rescue ProconBypassMan::Timer::Timeout
|
75
|
+
ProconBypassMan.logger.info "10秒経過したのでThread1を終了します"
|
76
|
+
puts "10秒経過したのでThread1を終了します"
|
77
|
+
break
|
78
|
+
rescue Errno::EIO, Errno::ENODEV, Errno::EPROTO, IOError => e
|
79
|
+
ProconBypassMan.logger.error "Proconが切断されました.終了処理を開始します"
|
80
|
+
Process.kill "TERM", Process.ppid
|
81
|
+
rescue Errno::ETIMEDOUT => e
|
82
|
+
# TODO まれにこれが発生する. 再接続したい
|
83
|
+
ProconBypassMan::ErrorReporter.report(body: e)
|
84
|
+
ProconBypassMan.logger.error "Switchとの切断されました.終了処理を開始します"
|
85
|
+
Process.kill "TERM", Process.ppid
|
88
86
|
end
|
87
|
+
ProconBypassMan.logger.info "Thread1を終了します"
|
89
88
|
end
|
90
89
|
|
91
90
|
# procon => gadget
|
@@ -93,19 +92,17 @@ class ProconBypassMan::Runner
|
|
93
92
|
ProconBypassMan.logger.info "Thread2を起動します"
|
94
93
|
t2 = Thread.new do
|
95
94
|
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を終了します"
|
95
|
+
loop do
|
96
|
+
break if $will_terminate_token
|
97
|
+
bypass.send_procon_to_gadget!
|
98
|
+
rescue EOFError => e
|
99
|
+
ProconBypassMan.logger.error "Proconと通信ができませんでした.終了処理を開始します"
|
100
|
+
Process.kill "TERM", Process.ppid
|
101
|
+
rescue Errno::EIO, Errno::ENODEV, Errno::EPROTO, IOError => e
|
102
|
+
ProconBypassMan.logger.error "Proconが切断されました。終了処理を開始します"
|
103
|
+
Process.kill "TERM", Process.ppid
|
108
104
|
end
|
105
|
+
ProconBypassMan.logger.info "Thread2を終了します"
|
109
106
|
end
|
110
107
|
|
111
108
|
self_read, self_write = IO.pipe
|
@@ -155,18 +152,9 @@ class ProconBypassMan::Runner
|
|
155
152
|
|
156
153
|
# @return [void]
|
157
154
|
def print_booted_message
|
158
|
-
|
159
|
-
|
160
|
-
|
161
|
-
|
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
|
155
|
+
message = ProconBypassMan::BootMessage.new
|
156
|
+
ProconBypassMan.logger.info(message.to_s)
|
157
|
+
Thread.new { ProconBypassMan::Reporter.report(body: message.to_hash) }
|
158
|
+
puts message.to_s
|
171
159
|
end
|
172
160
|
end
|
data/lib/procon_bypass_man.rb
CHANGED
@@ -3,6 +3,7 @@ require 'yaml'
|
|
3
3
|
require "fileutils"
|
4
4
|
|
5
5
|
require_relative "procon_bypass_man/version"
|
6
|
+
require_relative "procon_bypass_man/analog_stick_position"
|
6
7
|
require_relative "procon_bypass_man/timer"
|
7
8
|
require_relative "procon_bypass_man/bypass"
|
8
9
|
require_relative "procon_bypass_man/device_connector"
|
@@ -10,11 +11,16 @@ require_relative "procon_bypass_man/runner"
|
|
10
11
|
require_relative "procon_bypass_man/processor"
|
11
12
|
require_relative "procon_bypass_man/configuration"
|
12
13
|
require_relative "procon_bypass_man/procon"
|
14
|
+
require_relative "procon_bypass_man/procon/debug_dumper"
|
15
|
+
require_relative "procon_bypass_man/procon/analog_stick_cap"
|
16
|
+
require_relative "procon_bypass_man/reporter"
|
17
|
+
require_relative "procon_bypass_man/error_reporter"
|
18
|
+
require_relative "procon_bypass_man/on_memory_cache"
|
13
19
|
|
14
20
|
STDOUT.sync = true
|
15
21
|
Thread.abort_on_exception = true
|
16
22
|
|
17
|
-
# new feature from ruby3.0
|
23
|
+
# new feature from ruby3.0
|
18
24
|
if GC.respond_to?(:auto_compact)
|
19
25
|
GC.auto_compact = true
|
20
26
|
end
|
@@ -38,6 +44,8 @@ module ProconBypassMan
|
|
38
44
|
end
|
39
45
|
|
40
46
|
def self.run(setting_path: nil, &block)
|
47
|
+
ProconBypassMan.logger.info "PBMを起動しています"
|
48
|
+
puts "PBMを起動しています"
|
41
49
|
configure(setting_path: setting_path, &block)
|
42
50
|
File.write(pid_path, $$)
|
43
51
|
Runner.new.run
|
@@ -61,14 +69,31 @@ module ProconBypassMan
|
|
61
69
|
@@logger = logger
|
62
70
|
end
|
63
71
|
|
72
|
+
# @return [Logger]
|
64
73
|
def self.logger
|
65
|
-
if
|
74
|
+
if ENV["PBM_ENV"] == 'test'
|
75
|
+
return Logger.new($stdout)
|
76
|
+
end
|
77
|
+
|
78
|
+
if defined?(@@logger) && @@logger.is_a?(Logger)
|
66
79
|
@@logger
|
67
80
|
else
|
68
81
|
Logger.new(nil)
|
69
82
|
end
|
70
83
|
end
|
71
84
|
|
85
|
+
def self.enable_critical_error_logging!
|
86
|
+
@@enable_critical_error_logging = true
|
87
|
+
end
|
88
|
+
|
89
|
+
def self.error_logger
|
90
|
+
if defined?(@@enable_critical_error_logging)
|
91
|
+
@@error_logger ||= Logger.new("#{ProconBypassMan.root}/error.log", 5, 1024 * 1024 * 10)
|
92
|
+
else
|
93
|
+
Logger.new(nil)
|
94
|
+
end
|
95
|
+
end
|
96
|
+
|
72
97
|
def self.pid_path
|
73
98
|
@@pid_path ||= File.expand_path("#{root}/pbm_pid", __dir__).freeze
|
74
99
|
end
|
@@ -93,6 +118,22 @@ module ProconBypassMan
|
|
93
118
|
@@root = path
|
94
119
|
end
|
95
120
|
|
121
|
+
def self.api_server=(api_server)
|
122
|
+
@@api_server = api_server
|
123
|
+
end
|
124
|
+
|
125
|
+
def self.api_server
|
126
|
+
if defined?(@@api_server)
|
127
|
+
@@api_server
|
128
|
+
else
|
129
|
+
nil
|
130
|
+
end
|
131
|
+
end
|
132
|
+
|
133
|
+
def self.cache
|
134
|
+
@@cache_table ||= ProconBypassMan::OnMemoryCache.new
|
135
|
+
end
|
136
|
+
|
96
137
|
def self.digest_path
|
97
138
|
"#{root}/.setting_yaml_digest"
|
98
139
|
end
|
data/project_template/app.rb
CHANGED
@@ -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.
|
8
|
+
gem 'procon_bypass_man', '0.1.9'
|
9
9
|
gem 'procon_bypass_man-splatoon2', github: 'splaplapla/procon_bypass_man-splatoon2', tag: "0.1.1"
|
10
10
|
end
|
11
11
|
|
@@ -13,6 +13,8 @@ ProconBypassMan.tap do |pbm|
|
|
13
13
|
pbm.root = File.expand_path(__dir__)
|
14
14
|
pbm.logger = Logger.new("#{ProconBypassMan.root}/app.log", 5, 1024 * 1024 * 10)
|
15
15
|
pbm.logger.level = :debug
|
16
|
+
# pbm.api_server = 'https://...'
|
17
|
+
pbm.enable_critical_error_logging!
|
16
18
|
end
|
17
19
|
|
18
20
|
ProconBypassMan.run(setting_path: "/usr/share/pbm/current/setting.yml")
|
data/sig/README.rb
ADDED