procon_bypass_man 0.1.20 → 0.1.21
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 +24 -8
- data/.github/workflows/ruby.yml +1 -1
- data/.rspec +1 -0
- data/CHANGELOG.md +24 -1
- data/Gemfile.lock +3 -3
- data/docs/getting_started.md +38 -5
- data/docs/setting/splatoon2_macro_dasei_cancel.md +73 -0
- data/lib/procon_bypass_man/background/jobs/report_completed_upgrade_pbm_job.rb +10 -0
- data/lib/procon_bypass_man/background.rb +1 -0
- data/lib/procon_bypass_man/buttons_setting_configuration/layer.rb +28 -5
- data/lib/procon_bypass_man/buttons_setting_configuration.rb +1 -1
- data/lib/procon_bypass_man/commands/bypass_command.rb +21 -2
- data/lib/procon_bypass_man/commands/connect_device_command.rb +11 -21
- data/lib/procon_bypass_man/commands/print_boot_message_command.rb +6 -0
- data/lib/procon_bypass_man/configuration.rb +15 -0
- data/lib/procon_bypass_man/device_connector.rb +6 -9
- data/lib/procon_bypass_man/device_procon_finder.rb +0 -20
- data/lib/procon_bypass_man/domains/binary/processing_procon_binary.rb +1 -1
- data/lib/procon_bypass_man/domains/bypass_mode.rb +29 -0
- data/lib/procon_bypass_man/domains.rb +1 -0
- data/lib/procon_bypass_man/plugin/splatoon2/macro/dasei_cancel.rb +21 -0
- data/lib/procon_bypass_man/plugin/splatoon2/macro/fast_return.rb +4 -0
- data/lib/procon_bypass_man/plugin/splatoon2/macro/jump_to_left_key.rb +4 -0
- data/lib/procon_bypass_man/plugin/splatoon2/macro/jump_to_right_key.rb +4 -0
- data/lib/procon_bypass_man/plugin/splatoon2/macro/jump_to_up_key.rb +4 -0
- data/lib/procon_bypass_man/plugin/splatoon2/macro/sokuwari_for_splash_bomb.rb +4 -0
- data/lib/procon_bypass_man/plugin/splatoon2/mode/guruguru.rb +4 -0
- data/lib/procon_bypass_man/plugins.rb +1 -0
- data/lib/procon_bypass_man/procon/button_collection.rb +0 -8
- data/lib/procon_bypass_man/procon/macro.rb +48 -23
- data/lib/procon_bypass_man/procon/macro_builder.rb +31 -21
- data/lib/procon_bypass_man/procon/macro_registry.rb +7 -2
- data/lib/procon_bypass_man/procon/user_operation.rb +1 -1
- data/lib/procon_bypass_man/procon/value_objects/analog_stick.rb +9 -5
- data/lib/procon_bypass_man/procon.rb +32 -12
- data/lib/procon_bypass_man/remote_pbm_action/change_pbm_version_action.rb +4 -1
- data/lib/procon_bypass_man/scheduler.rb +1 -1
- data/lib/procon_bypass_man/support/analog_stick_hypotenuse_tilting_power_scaler.rb +59 -0
- data/lib/procon_bypass_man/{never_exit_accidentally.rb → support/never_exit_accidentally.rb} +0 -0
- data/lib/procon_bypass_man/usb_device_controller.rb +53 -0
- data/lib/procon_bypass_man/version.rb +1 -1
- data/lib/procon_bypass_man/websocket/forever.rb +47 -0
- data/lib/procon_bypass_man/websocket/pbm_job_client.rb +14 -7
- data/lib/procon_bypass_man/websocket/watchdog.rb +19 -0
- data/lib/procon_bypass_man.rb +8 -7
- data/procon_bypass_man.gemspec +1 -1
- data/project_template/app.rb +11 -1
- data/project_template/systemd_units/pbm.service +1 -1
- data/sig/main.rbs +20 -0
- metadata +13 -5
@@ -3,6 +3,10 @@ module ProconBypassMan
|
|
3
3
|
module Splatoon2
|
4
4
|
module Mode
|
5
5
|
module Guruguru
|
6
|
+
def self.description
|
7
|
+
'適当に動きます'
|
8
|
+
end
|
9
|
+
|
6
10
|
def self.binaries
|
7
11
|
[ "309481408000362d684658750968f71cfe2c0e51000001480053f71ffedf0d4b000a013d00caf6ecfd4c0d480003011c00000000000000000000000000000000",
|
8
12
|
"30978140800037dd6748687509fdf6adfded0d6d0081005d00eef68dfdef0d6d00830059001bf791fd140e720090005400000000000000000000000000000000",
|
@@ -4,6 +4,7 @@ require_relative "plugin/splatoon2/macro/jump_to_right_key"
|
|
4
4
|
require_relative "plugin/splatoon2/macro/jump_to_up_key"
|
5
5
|
require_relative "plugin/splatoon2/macro/jump_to_left_key"
|
6
6
|
require_relative "plugin/splatoon2/macro/sokuwari_for_splash_bomb"
|
7
|
+
require_relative "plugin/splatoon2/macro/dasei_cancel"
|
7
8
|
require_relative "plugin/splatoon2/mode/guruguru"
|
8
9
|
|
9
10
|
module ProconBypassMan
|
@@ -37,12 +37,4 @@ class ProconBypassMan::Procon::ButtonCollection
|
|
37
37
|
BUTTONS = ProconBypassMan::Procon::ButtonCollection::BUTTONS_MAP.keys.freeze
|
38
38
|
|
39
39
|
LEFT_ANALOG_STICK = { byte_position: 6..8 }
|
40
|
-
|
41
|
-
# @param [Array<Symbol>] buttons
|
42
|
-
# @return [Array<Symbol>]
|
43
|
-
def self.normalize(buttons)
|
44
|
-
buttons.select { |x|
|
45
|
-
!!ProconBypassMan::Procon::ButtonCollection::BUTTONS_MAP[x]
|
46
|
-
}
|
47
|
-
end
|
48
40
|
end
|
@@ -1,13 +1,51 @@
|
|
1
1
|
class ProconBypassMan::Procon::Macro
|
2
|
-
class
|
2
|
+
class BaseNestedStep
|
3
3
|
def initialize(value)
|
4
4
|
@hash = value
|
5
|
+
end
|
6
|
+
|
7
|
+
private
|
8
|
+
|
9
|
+
def incr_step_index!
|
10
|
+
if step_index
|
11
|
+
@hash[:step_index] += 1
|
12
|
+
else
|
13
|
+
@hash[:step_index] = 0
|
14
|
+
end
|
15
|
+
end
|
16
|
+
|
17
|
+
def current_step
|
18
|
+
@hash[:steps][step_index]
|
19
|
+
end
|
20
|
+
end
|
21
|
+
|
22
|
+
class OnetimeNestedStep < BaseNestedStep
|
23
|
+
def over?
|
24
|
+
current_step.nil?
|
25
|
+
end
|
26
|
+
|
27
|
+
def next_step
|
28
|
+
step = current_step
|
29
|
+
incr_step_index!
|
30
|
+
step
|
31
|
+
end
|
32
|
+
|
33
|
+
private
|
34
|
+
|
35
|
+
def step_index
|
36
|
+
@hash[:step_index] ||= 0
|
37
|
+
end
|
38
|
+
end
|
39
|
+
|
40
|
+
class NestedStep < BaseNestedStep
|
41
|
+
def initialize(value)
|
42
|
+
super
|
5
43
|
unless @hash[:end_at]
|
6
44
|
@hash[:end_at] = (Time.now + @hash[:continue_for]).round(4)
|
7
45
|
end
|
8
46
|
end
|
9
47
|
|
10
|
-
def
|
48
|
+
def over?
|
11
49
|
(@hash[:end_at] < Time.now).tap do |result|
|
12
50
|
if result
|
13
51
|
ProconBypassMan.logger.debug { "[Macro] nested step is finished(#{@hash})" }
|
@@ -17,8 +55,6 @@ class ProconBypassMan::Procon::Macro
|
|
17
55
|
|
18
56
|
def next_step
|
19
57
|
incr_step_index!
|
20
|
-
|
21
|
-
debug_incr_called_count!
|
22
58
|
if step = current_step
|
23
59
|
return step
|
24
60
|
else
|
@@ -29,30 +65,13 @@ class ProconBypassMan::Procon::Macro
|
|
29
65
|
|
30
66
|
private
|
31
67
|
|
32
|
-
def current_step
|
33
|
-
@hash[:steps][step_index]
|
34
|
-
end
|
35
|
-
|
36
68
|
def step_index
|
37
69
|
@hash[:step_index]
|
38
70
|
end
|
39
71
|
|
40
|
-
def incr_step_index!
|
41
|
-
if step_index
|
42
|
-
@hash[:step_index] += 1
|
43
|
-
else
|
44
|
-
@hash[:step_index] = 0
|
45
|
-
end
|
46
|
-
end
|
47
|
-
|
48
72
|
def reset_step_index!
|
49
73
|
@hash[:step_index] = 0
|
50
74
|
end
|
51
|
-
|
52
|
-
def debug_incr_called_count!
|
53
|
-
@hash[:debug_called_count] ||= 0
|
54
|
-
@hash[:debug_called_count] += 1
|
55
|
-
end
|
56
75
|
end
|
57
76
|
|
58
77
|
attr_accessor :name, :steps
|
@@ -69,8 +88,14 @@ class ProconBypassMan::Procon::Macro
|
|
69
88
|
end
|
70
89
|
|
71
90
|
if step.is_a?(Hash)
|
72
|
-
nested_step =
|
73
|
-
|
91
|
+
nested_step =
|
92
|
+
if step[:continue_for]
|
93
|
+
NestedStep.new(step)
|
94
|
+
else
|
95
|
+
OnetimeNestedStep.new(step)
|
96
|
+
end
|
97
|
+
|
98
|
+
if nested_step.over?
|
74
99
|
steps.shift # NestedStepを破棄する
|
75
100
|
return next_step
|
76
101
|
else
|
@@ -56,7 +56,7 @@ class ProconBypassMan::Procon::MacroBuilder
|
|
56
56
|
|
57
57
|
# @return [Arary<Symbol>]
|
58
58
|
def build
|
59
|
-
steps = @steps.
|
59
|
+
steps = @steps.flat_map { |step|
|
60
60
|
if is_reserved?(step: step) || v1_format?(step: step)
|
61
61
|
step.to_sym
|
62
62
|
elsif value = build_if_v2_format?(step: step)
|
@@ -65,7 +65,8 @@ class ProconBypassMan::Procon::MacroBuilder
|
|
65
65
|
nil
|
66
66
|
end
|
67
67
|
}
|
68
|
-
|
68
|
+
|
69
|
+
steps.compact
|
69
70
|
end
|
70
71
|
|
71
72
|
private
|
@@ -81,31 +82,40 @@ class ProconBypassMan::Procon::MacroBuilder
|
|
81
82
|
end
|
82
83
|
|
83
84
|
def build_if_v2_format?(step: )
|
84
|
-
# 時間指定なし
|
85
|
-
if(match = step.match(%r!\Atoggle_(\w+)\z!)) && (button_candidate = match[1]) && is_button(button_candidate)
|
86
|
-
button = button_candidate
|
87
|
-
return [button.to_sym, :none]
|
88
|
-
end
|
89
|
-
|
90
|
-
# 時間指定あり
|
91
|
-
if %r!^(pressing_|toggle_)! =~ step && (subjects = step.scan(%r!pressing_[^_]+|toggle_[^_]+!)) && (match = step.match(%r!_for_([\d_]+)(sec)?\z!))
|
92
|
-
sec = match[1]
|
93
|
-
return [
|
94
|
-
{ continue_for: to_num(sec),
|
95
|
-
steps: SubjectMerger.merge(subjects.map { |x| Subject.new(x) }),
|
96
|
-
}
|
97
|
-
]
|
98
|
-
end
|
99
|
-
|
100
85
|
# no-op command
|
101
86
|
if(match = step.match(%r!wait_for_([\d_]+)(sec)?\z!))
|
102
87
|
sec = match[1]
|
103
88
|
return [
|
104
|
-
{ continue_for:
|
89
|
+
{ continue_for: to_f(sec),
|
105
90
|
steps: [:none],
|
106
91
|
}
|
107
92
|
]
|
108
93
|
end
|
94
|
+
|
95
|
+
if %r!^(pressing_|toggle_)! =~ step && (subjects = step.scan(%r!pressing_[^_]+|toggle_[^_]+!)) && (match = step.match(%r!_for_([\d_]+)(sec)?\z!))
|
96
|
+
if sec = match[1]
|
97
|
+
return {
|
98
|
+
continue_for: to_f(sec),
|
99
|
+
steps: SubjectMerger.merge(subjects.map { |x| Subject.new(x) }).select { |x|
|
100
|
+
if x.is_a?(Array)
|
101
|
+
x.select { |y| is_button(y) || RESERVED_WORD_NONE == y }
|
102
|
+
else
|
103
|
+
is_button(x) || RESERVED_WORD_NONE == x
|
104
|
+
end
|
105
|
+
},
|
106
|
+
}
|
107
|
+
end
|
108
|
+
end
|
109
|
+
|
110
|
+
if %r!^(pressing_|toggle_)! =~ step && (subjects = step.scan(%r!pressing_[^_]+|toggle_[^_]+!))
|
111
|
+
return SubjectMerger.merge(subjects.map { |x| Subject.new(x) }).select { |x|
|
112
|
+
if x.is_a?(Array)
|
113
|
+
x.select { |y| is_button(y) || RESERVED_WORD_NONE == y }
|
114
|
+
else
|
115
|
+
is_button(x) || RESERVED_WORD_NONE == x
|
116
|
+
end
|
117
|
+
}
|
118
|
+
end
|
109
119
|
end
|
110
120
|
|
111
121
|
# @return [Boolean]
|
@@ -113,11 +123,11 @@ class ProconBypassMan::Procon::MacroBuilder
|
|
113
123
|
!!ProconBypassMan::Procon::ButtonCollection::BUTTONS_MAP[step.to_sym]
|
114
124
|
end
|
115
125
|
|
116
|
-
def
|
126
|
+
def to_f(value)
|
117
127
|
if value.include?("_")
|
118
128
|
value.sub("_", ".").to_f
|
119
129
|
else
|
120
|
-
value.
|
130
|
+
value.to_f
|
121
131
|
end
|
122
132
|
end
|
123
133
|
end
|
@@ -13,9 +13,14 @@ class ProconBypassMan::Procon::MacroRegistry
|
|
13
13
|
}
|
14
14
|
end
|
15
15
|
|
16
|
+
# @return [ProconBypassMan::Procon::Macro]
|
16
17
|
def self.load(name)
|
17
|
-
steps = PRESETS[name] || plugins[name]
|
18
|
-
|
18
|
+
if(steps = PRESETS[name] || plugins[name]&.call)
|
19
|
+
return ProconBypassMan::Procon::Macro.new(name: name, steps: steps.dup)
|
20
|
+
else
|
21
|
+
warn "installされていないマクロ(#{name})を使うことはできません"
|
22
|
+
return self.load(:null)
|
23
|
+
end
|
19
24
|
end
|
20
25
|
|
21
26
|
def self.reset!
|
@@ -62,7 +62,7 @@ class ProconBypassMan::Procon::UserOperation
|
|
62
62
|
# @param [Symbol] button
|
63
63
|
# @return [Boolean]
|
64
64
|
def pressing_button?(button)
|
65
|
-
|
65
|
+
pressing_all_buttons?([button])
|
66
66
|
end
|
67
67
|
|
68
68
|
# @param [Array<Symbol>] buttons
|
@@ -1,6 +1,6 @@
|
|
1
1
|
class ProconBypassMan::Procon::AnalogStick
|
2
2
|
attr_accessor :neutral_position
|
3
|
-
|
3
|
+
attr_writer :bin_x, :bin_y
|
4
4
|
|
5
5
|
def initialize(binary: )
|
6
6
|
@neutral_position = ProconBypassMan::ButtonsSettingConfiguration.instance.neutral_position
|
@@ -13,18 +13,22 @@ class ProconBypassMan::Procon::AnalogStick
|
|
13
13
|
end
|
14
14
|
|
15
15
|
def abs_x
|
16
|
-
bin_x.to_i(2)
|
16
|
+
@bin_x.to_i(2)
|
17
17
|
end
|
18
18
|
|
19
19
|
def abs_y
|
20
|
-
bin_y.to_i(2)
|
20
|
+
@bin_y.to_i(2)
|
21
21
|
end
|
22
22
|
|
23
23
|
def relative_x
|
24
|
-
bin_x.to_i(2) - neutral_position.x
|
24
|
+
@bin_x.to_i(2) - neutral_position.x
|
25
25
|
end
|
26
26
|
|
27
27
|
def relative_y
|
28
|
-
bin_y.to_i(2) - neutral_position.y
|
28
|
+
@bin_y.to_i(2) - neutral_position.y
|
29
|
+
end
|
30
|
+
|
31
|
+
def relative_hypotenuse
|
32
|
+
Math.sqrt((relative_x**2) + (relative_y**2)).floor(6)
|
29
33
|
end
|
30
34
|
end
|
@@ -19,6 +19,7 @@ class ProconBypassMan::Procon
|
|
19
19
|
ongoing_macro: MacroRegistry.load(:null),
|
20
20
|
ongoing_mode: ModeRegistry.load(:manual),
|
21
21
|
}
|
22
|
+
@@left_stick_tilting_power_scaler = ProconBypassMan::AnalogStickTiltingPowerScaler.new
|
22
23
|
end
|
23
24
|
reset!
|
24
25
|
|
@@ -38,6 +39,7 @@ class ProconBypassMan::Procon
|
|
38
39
|
ProconBypassMan::ButtonsSettingConfiguration.instance.layers[current_layer_key]
|
39
40
|
end
|
40
41
|
|
42
|
+
# 内部ステータスを書き換えるフェーズ
|
41
43
|
def apply!
|
42
44
|
layer_changer = ProconBypassMan::Procon::LayerChanger.new(binary: user_operation.binary)
|
43
45
|
if layer_changer.change_layer?
|
@@ -46,10 +48,38 @@ class ProconBypassMan::Procon
|
|
46
48
|
return
|
47
49
|
end
|
48
50
|
|
49
|
-
|
51
|
+
analog_stick = ProconBypassMan::Procon::AnalogStick.new(binary: user_operation.binary.raw)
|
52
|
+
dumped_tilting_power = @@left_stick_tilting_power_scaler.add_sample(analog_stick.relative_hypotenuse)
|
53
|
+
|
54
|
+
enable_all_macro = true
|
55
|
+
enable_macro_map = Hash.new {|h,k| h[k] = true }
|
56
|
+
current_layer.disable_macros.each do |disable_macro|
|
57
|
+
if (disable_macro[:if_pressed] == [true] || user_operation.pressing_all_buttons?(disable_macro[:if_pressed]))
|
58
|
+
if disable_macro[:name] == :all
|
59
|
+
enable_all_macro = false
|
60
|
+
else
|
61
|
+
enable_macro_map[disable_macro[:name]] = false
|
62
|
+
end
|
63
|
+
end
|
64
|
+
end
|
65
|
+
|
66
|
+
if ongoing_macro.finished? && enable_all_macro
|
50
67
|
current_layer.macros.each do |macro_name, options|
|
68
|
+
next unless enable_macro_map[macro_name]
|
69
|
+
|
70
|
+
if(if_tilted_left_stick_value = options[:if_tilted_left_stick])
|
71
|
+
threshold = (if_tilted_left_stick_value.is_a?(Hash) && if_tilted_left_stick_value[:threshold]) || ProconBypassMan::AnalogStickTiltingPowerScaler::DEFAULT_THRESHOLD
|
72
|
+
if dumped_tilting_power&.tilting?(threshold: threshold, current_position_x: analog_stick.relative_x, current_position_y: analog_stick.relative_y) && user_operation.pressing_all_buttons?(options[:if_pressed])
|
73
|
+
@@status[:ongoing_macro] = MacroRegistry.load(macro_name)
|
74
|
+
break
|
75
|
+
end
|
76
|
+
|
77
|
+
next
|
78
|
+
end
|
79
|
+
|
51
80
|
if user_operation.pressing_all_buttons?(options[:if_pressed])
|
52
81
|
@@status[:ongoing_macro] = MacroRegistry.load(macro_name)
|
82
|
+
break
|
53
83
|
end
|
54
84
|
end
|
55
85
|
end
|
@@ -88,7 +118,7 @@ class ProconBypassMan::Procon
|
|
88
118
|
status
|
89
119
|
end
|
90
120
|
|
91
|
-
# @return [
|
121
|
+
# @return [String]
|
92
122
|
def to_binary
|
93
123
|
if ongoing_mode.name != :manual
|
94
124
|
return user_operation.binary.raw
|
@@ -143,14 +173,4 @@ class ProconBypassMan::Procon
|
|
143
173
|
|
144
174
|
user_operation.binary.raw
|
145
175
|
end
|
146
|
-
|
147
|
-
private
|
148
|
-
|
149
|
-
def method_missing(name)
|
150
|
-
if name.to_s =~ /\Apressed_[a-z]+\?\z/
|
151
|
-
user_operation.public_send(name)
|
152
|
-
else
|
153
|
-
super
|
154
|
-
end
|
155
|
-
end
|
156
176
|
end
|
@@ -6,8 +6,11 @@ module ProconBypassMan
|
|
6
6
|
require "pbmenv"
|
7
7
|
ProconBypassMan.logger.info "execute ChangePbmVersionAction!"
|
8
8
|
pbm_version = args["pbm_version"] or raise(ProconBypassMan::RemotePbmAction::NeedPbmVersionError, "pbm_versionが必要です, #{args.inspect}")
|
9
|
-
Pbmenv.
|
9
|
+
Pbmenv.uninstall(pbm_version) # 途中でシャットダウンしてしまった、とか状態が途中の状態かもしれないので一旦消す
|
10
|
+
Pbmenv.install(pbm_version, enable_pbm_cloud: true)
|
10
11
|
Pbmenv.use(pbm_version)
|
12
|
+
ProconBypassMan.logger.info "#{pbm_version}へアップグレードしました"
|
13
|
+
ProconBypassMan::ReportCompletedUpgradePbmJob.perform
|
11
14
|
`reboot` # symlinkの参照先が変わるのでrebootする必要がある
|
12
15
|
end
|
13
16
|
|
@@ -0,0 +1,59 @@
|
|
1
|
+
class ProconBypassMan::AnalogStickTiltingPowerScaler
|
2
|
+
DEFAULT_THRESHOLD = 500
|
3
|
+
|
4
|
+
class PowerChunk
|
5
|
+
def initialize(list)
|
6
|
+
@list = list
|
7
|
+
end
|
8
|
+
|
9
|
+
def moving_power
|
10
|
+
max = @list.max
|
11
|
+
min = @list.min
|
12
|
+
moving_power = (max - min).abs
|
13
|
+
end
|
14
|
+
|
15
|
+
def tilting?(threshold: DEFAULT_THRESHOLD, current_position_x: , current_position_y: )
|
16
|
+
# スティックがニュートラルな時
|
17
|
+
if (-200..200).include?(current_position_x) && (-200..200).include?(current_position_y)
|
18
|
+
return false
|
19
|
+
end
|
20
|
+
|
21
|
+
moving_power >= threshold
|
22
|
+
end
|
23
|
+
end
|
24
|
+
|
25
|
+
def initialize
|
26
|
+
@map = {}
|
27
|
+
end
|
28
|
+
|
29
|
+
# @return [NilClass, Chunk] ローテトしたらvalueを返す
|
30
|
+
def add_sample(value)
|
31
|
+
rotated = nil
|
32
|
+
current_key = key
|
33
|
+
if @map[current_key].nil?
|
34
|
+
rotated = rotate
|
35
|
+
@map = { current_key => [] } # renew or initialize
|
36
|
+
end
|
37
|
+
|
38
|
+
@map[current_key] << value
|
39
|
+
rotated
|
40
|
+
end
|
41
|
+
|
42
|
+
private
|
43
|
+
|
44
|
+
# 0.1sec刻みで進行する
|
45
|
+
def key
|
46
|
+
time = Time.now
|
47
|
+
m1 = time.strftime('%L')[0]
|
48
|
+
[time.to_i, m1].join.to_i
|
49
|
+
end
|
50
|
+
|
51
|
+
def rotate
|
52
|
+
list = @map.values.first
|
53
|
+
if list
|
54
|
+
return PowerChunk.new(list)
|
55
|
+
else
|
56
|
+
return nil
|
57
|
+
end
|
58
|
+
end
|
59
|
+
end
|
data/lib/procon_bypass_man/{never_exit_accidentally.rb → support/never_exit_accidentally.rb}
RENAMED
File without changes
|
@@ -0,0 +1,53 @@
|
|
1
|
+
class ProconBypassMan::UsbDeviceController
|
2
|
+
class << self
|
3
|
+
def reset
|
4
|
+
system('echo > /sys/kernel/config/usb_gadget/procon/UDC')
|
5
|
+
system('ls /sys/class/udc > /sys/kernel/config/usb_gadget/procon/UDC')
|
6
|
+
sleep 0.5
|
7
|
+
end
|
8
|
+
|
9
|
+
def init
|
10
|
+
return if initialized?
|
11
|
+
|
12
|
+
shell = <<~EOH
|
13
|
+
#!/bin/bash
|
14
|
+
|
15
|
+
cd /sys/kernel/config/usb_gadget/
|
16
|
+
mkdir -p procon
|
17
|
+
cd procon
|
18
|
+
echo 0x057e > idVendor
|
19
|
+
echo 0x2009 > idProduct
|
20
|
+
echo 0x0200 > bcdDevice
|
21
|
+
echo 0x0200 > bcdUSB
|
22
|
+
echo 0x00 > bDeviceClass
|
23
|
+
echo 0x00 > bDeviceSubClass
|
24
|
+
echo 0x00 > bDeviceProtocol
|
25
|
+
|
26
|
+
mkdir -p strings/0x409
|
27
|
+
echo "000000000001" > strings/0x409/serialnumber
|
28
|
+
echo "Nintendo Co., Ltd." > strings/0x409/manufacturer
|
29
|
+
echo "Pro Controller" > strings/0x409/product
|
30
|
+
|
31
|
+
mkdir -p configs/c.1/strings/0x409
|
32
|
+
echo "Nintendo Switch Pro Controller" > configs/c.1/strings/0x409/configuration
|
33
|
+
echo 500 > configs/c.1/MaxPower
|
34
|
+
echo 0xa0 > configs/c.1/bmAttributes
|
35
|
+
|
36
|
+
mkdir -p functions/hid.usb0
|
37
|
+
echo 0 > functions/hid.usb0/protocol
|
38
|
+
echo 0 > functions/hid.usb0/subclass
|
39
|
+
echo 64 > functions/hid.usb0/report_length
|
40
|
+
echo 050115000904A1018530050105091901290A150025017501950A5500650081020509190B290E150025017501950481027501950281030B01000100A1000B300001000B310001000B320001000B35000100150027FFFF0000751095048102C00B39000100150025073500463B0165147504950181020509190F2912150025017501950481027508953481030600FF852109017508953F8103858109027508953F8103850109037508953F9183851009047508953F9183858009057508953F9183858209067508953F9183C0 | xxd -r -ps > functions/hid.usb0/report_desc
|
41
|
+
|
42
|
+
ln -s functions/hid.usb0 configs/c.1/
|
43
|
+
ls /sys/class/udc > UDC
|
44
|
+
EOH
|
45
|
+
|
46
|
+
`bash -c '#{shell}'`
|
47
|
+
end
|
48
|
+
|
49
|
+
def initialized?
|
50
|
+
Dir.exist?("/sys/kernel/config/usb_gadget/procon")
|
51
|
+
end
|
52
|
+
end
|
53
|
+
end
|
@@ -0,0 +1,47 @@
|
|
1
|
+
module ProconBypassMan
|
2
|
+
module Websocket
|
3
|
+
class Forever
|
4
|
+
# 動作確認方法
|
5
|
+
# - 10秒ごとにrefreshするのでタイムアウトは起きない
|
6
|
+
# - ProconBypassMan::Websocket::Forever.run { loop { puts(:hi); sleep(10); ProconBypassMan::Websocket::Watchdog.active! } }
|
7
|
+
# - タイムアウトが起きること
|
8
|
+
# - ProconBypassMan::Websocket::Forever.run { puts(:hi); sleep(3000); }
|
9
|
+
# - ブロックを1回評価するとThreadが死ぬので100秒後にタイムアウトが起きること
|
10
|
+
# - ProconBypassMan::Websocket::Forever.run { puts(:hi); sleep(10); ProconBypassMan::Websocket::Watchdog.active! }
|
11
|
+
def self.run(&block)
|
12
|
+
loop do
|
13
|
+
new.run(&block)
|
14
|
+
end
|
15
|
+
end
|
16
|
+
|
17
|
+
def run(&block)
|
18
|
+
raise("need a block") unless block_given?
|
19
|
+
|
20
|
+
ws_thread = work_one(callable: block)
|
21
|
+
wait_and_kill_if_outdated(ws_thread)
|
22
|
+
end
|
23
|
+
|
24
|
+
# @return [Thread]
|
25
|
+
def work_one(callable: )
|
26
|
+
Thread.start do
|
27
|
+
callable.call
|
28
|
+
rescue => e
|
29
|
+
ProconBypassMan.logger.error("websocket client with forever: #{e.full_message}")
|
30
|
+
end
|
31
|
+
end
|
32
|
+
|
33
|
+
def wait_and_kill_if_outdated(thread)
|
34
|
+
loop do
|
35
|
+
if Watchdog.outdated?
|
36
|
+
Watchdog.active!
|
37
|
+
ProconBypassMan.logger.error("watchdog timeout!!")
|
38
|
+
thread.kill
|
39
|
+
return
|
40
|
+
end
|
41
|
+
|
42
|
+
sleep(10)
|
43
|
+
end
|
44
|
+
end
|
45
|
+
end
|
46
|
+
end
|
47
|
+
end
|
@@ -7,11 +7,7 @@ module ProconBypassMan
|
|
7
7
|
return unless ProconBypassMan.config.enable_ws?
|
8
8
|
|
9
9
|
Thread.start do
|
10
|
-
|
11
|
-
run
|
12
|
-
rescue
|
13
|
-
retry
|
14
|
-
end
|
10
|
+
Forever.run { run }
|
15
11
|
end
|
16
12
|
end
|
17
13
|
|
@@ -24,14 +20,16 @@ module ProconBypassMan
|
|
24
20
|
)
|
25
21
|
|
26
22
|
client.connected {
|
27
|
-
ProconBypassMan.logger.info('successfully connected in ProconBypassMan::Websocket::PbmJobClient')
|
23
|
+
ProconBypassMan.logger.info('websocket client: successfully connected in ProconBypassMan::Websocket::PbmJobClient')
|
28
24
|
}
|
29
25
|
client.subscribed { |msg|
|
26
|
+
ProconBypassMan.logger.info('websocket client: subscribed')
|
30
27
|
puts({ event: :subscribed, msg: msg })
|
31
28
|
ProconBypassMan::SyncDeviceStatsJob.perform(ProconBypassMan::DeviceStatus.current)
|
32
29
|
}
|
33
30
|
|
34
31
|
client.received do |data|
|
32
|
+
ProconBypassMan.logger.info('websocket client: received!!')
|
35
33
|
ProconBypassMan.logger.info(data)
|
36
34
|
|
37
35
|
dispatch(data: data, client: client)
|
@@ -40,13 +38,22 @@ module ProconBypassMan
|
|
40
38
|
end
|
41
39
|
|
42
40
|
client.disconnected {
|
41
|
+
ProconBypassMan.logger.info('websocket client: disconnected!!')
|
43
42
|
puts :disconnected
|
44
43
|
client.reconnect!
|
45
44
|
sleep 2
|
46
45
|
}
|
47
|
-
client.errored { |msg|
|
46
|
+
client.errored { |msg|
|
47
|
+
ProconBypassMan.logger.error("websocket client: errored!!, #{msg}")
|
48
|
+
puts :errored
|
49
|
+
client.reconnect!
|
50
|
+
sleep 2
|
51
|
+
}
|
48
52
|
client.pinged { |msg|
|
53
|
+
Watchdog.active!
|
54
|
+
|
49
55
|
ProconBypassMan.cache.fetch key: 'ws_pinged', expires_in: 10 do
|
56
|
+
ProconBypassMan.logger.info('websocket client: pinged!!')
|
50
57
|
ProconBypassMan.logger.info(msg)
|
51
58
|
end
|
52
59
|
}
|