procon_bypass_man 0.1.16.1 → 0.1.19.1
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 +86 -11
- data/.github/workflows/release.yml +2 -2
- data/.rubocop.yml +2 -0
- data/CHANGELOG.md +18 -0
- data/Gemfile +1 -0
- data/Gemfile.lock +7 -3
- data/README.md +25 -17
- data/Steepfile +31 -17
- data/docs/getting_started.md +60 -0
- data/docs/setting/left-analogstick-cap.md +60 -0
- data/docs/setting/splatoon2_macro_sokuwari_bubble.md +52 -0
- data/docs/setting/splatoon2_recommended_setting.md +40 -0
- data/docs/upgrade_pbm.md +56 -0
- data/lib/ext/module.rb +16 -0
- data/lib/procon_bypass_man/buttons_setting_configuration/layer.rb +33 -7
- data/lib/procon_bypass_man/buttons_setting_configuration/loader.rb +4 -1
- data/lib/procon_bypass_man/buttons_setting_configuration/validator.rb +36 -0
- data/lib/procon_bypass_man/buttons_setting_configuration.rb +34 -21
- data/lib/procon_bypass_man/commands/bypass_command.rb +2 -2
- data/lib/procon_bypass_man/domains/binary/base.rb +14 -0
- data/lib/procon_bypass_man/domains/binary/inbound_procon_binary.rb +0 -14
- data/lib/procon_bypass_man/domains/binary/processing_procon_binary.rb +2 -16
- data/lib/procon_bypass_man/plugin/splatoon2/macro/fast_return.rb +1 -1
- data/lib/procon_bypass_man/plugin/splatoon2/macro/jump_to_left_key.rb +1 -1
- data/lib/procon_bypass_man/plugin/splatoon2/macro/jump_to_right_key.rb +1 -1
- data/lib/procon_bypass_man/plugin/splatoon2/macro/jump_to_up_key.rb +1 -1
- data/lib/procon_bypass_man/plugin/splatoon2/macro/sokuwari_for_splash_bomb.rb +22 -0
- data/lib/procon_bypass_man/plugin/splatoon2/version.rb +1 -1
- data/lib/procon_bypass_man/plugins.rb +1 -0
- data/lib/procon_bypass_man/procon/button.rb +1 -1
- data/lib/procon_bypass_man/procon/button_collection.rb +8 -0
- data/lib/procon_bypass_man/procon/macro.rb +89 -0
- data/lib/procon_bypass_man/procon/macro_builder.rb +123 -0
- data/lib/procon_bypass_man/procon/macro_registry.rb +9 -27
- data/lib/procon_bypass_man/procon/mode_registry.rb +4 -4
- data/lib/procon_bypass_man/procon/press_button_aware.rb +6 -5
- data/lib/procon_bypass_man/procon/user_operation.rb +16 -2
- data/lib/procon_bypass_man/procon/value_objects/analog_stick.rb +1 -1
- data/lib/procon_bypass_man/procon.rb +6 -4
- data/lib/procon_bypass_man/remote_pbm_action/restore_pbm_setting.rb +3 -3
- data/lib/procon_bypass_man/support/compress_array.rb +5 -0
- data/lib/procon_bypass_man/support/http_client.rb +4 -0
- data/lib/procon_bypass_man/support/on_memory_cache.rb +3 -1
- data/lib/procon_bypass_man/support/server_pool.rb +4 -0
- data/lib/procon_bypass_man/support/yaml_writer.rb +16 -0
- data/lib/procon_bypass_man/version.rb +1 -1
- data/lib/procon_bypass_man/websocket/pbm_job_client.rb +13 -2
- data/lib/procon_bypass_man.rb +2 -0
- data/procon_bypass_man.gemspec +1 -1
- data/project_template/app.rb +3 -2
- data/project_template/setting.yml +4 -11
- data/sig/main.rbs +213 -42
- data/sig/on_memory_cache.rbs +16 -0
- metadata +16 -5
@@ -0,0 +1,123 @@
|
|
1
|
+
class ProconBypassMan::Procon::MacroBuilder
|
2
|
+
class SubjectMerger
|
3
|
+
def self.merge(subjects)
|
4
|
+
if subjects.size == 1
|
5
|
+
return subjects.first.to_steps
|
6
|
+
end
|
7
|
+
|
8
|
+
base = subjects.first
|
9
|
+
remain = subjects[1..-1]
|
10
|
+
remain.map { |x| base.to_steps.zip(x.to_steps) }.first
|
11
|
+
end
|
12
|
+
end
|
13
|
+
|
14
|
+
class Subject
|
15
|
+
def initialize(value)
|
16
|
+
@button =
|
17
|
+
if match = value.match(/_(\w+)\z/)
|
18
|
+
match[1]
|
19
|
+
else
|
20
|
+
:unknown
|
21
|
+
end
|
22
|
+
@type =
|
23
|
+
if value.start_with?("toggle_")
|
24
|
+
:toggle
|
25
|
+
else
|
26
|
+
:pressing
|
27
|
+
end
|
28
|
+
end
|
29
|
+
|
30
|
+
def toggle?
|
31
|
+
@type == :toggle
|
32
|
+
end
|
33
|
+
|
34
|
+
def pressing?
|
35
|
+
not toggle?
|
36
|
+
end
|
37
|
+
|
38
|
+
def to_steps
|
39
|
+
case @type
|
40
|
+
when :toggle
|
41
|
+
[@button.to_sym, :none]
|
42
|
+
when :pressing
|
43
|
+
[@button.to_sym, @button.to_sym]
|
44
|
+
end
|
45
|
+
end
|
46
|
+
end
|
47
|
+
|
48
|
+
RESERVED_WORD_NONE = :none
|
49
|
+
RESERVED_WORDS = {
|
50
|
+
RESERVED_WORD_NONE => true,
|
51
|
+
}
|
52
|
+
|
53
|
+
def initialize(steps)
|
54
|
+
@steps = steps.map(&:to_s)
|
55
|
+
end
|
56
|
+
|
57
|
+
# @return [Arary<Symbol>]
|
58
|
+
def build
|
59
|
+
steps = @steps.map { |step|
|
60
|
+
if is_reserved?(step: step) || v1_format?(step: step)
|
61
|
+
step.to_sym
|
62
|
+
elsif value = build_if_v2_format?(step: step)
|
63
|
+
value
|
64
|
+
else
|
65
|
+
nil
|
66
|
+
end
|
67
|
+
}
|
68
|
+
steps.compact.flatten
|
69
|
+
end
|
70
|
+
|
71
|
+
private
|
72
|
+
|
73
|
+
def is_reserved?(step: )
|
74
|
+
RESERVED_WORDS[step.to_sym]
|
75
|
+
end
|
76
|
+
|
77
|
+
def v1_format?(step: )
|
78
|
+
if is_button(step)
|
79
|
+
step
|
80
|
+
end
|
81
|
+
end
|
82
|
+
|
83
|
+
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
|
+
# no-op command
|
101
|
+
if(match = step.match(%r!wait_for_([\d_]+)(sec)?\z!))
|
102
|
+
sec = match[1]
|
103
|
+
return [
|
104
|
+
{ continue_for: to_num(sec),
|
105
|
+
steps: [:none],
|
106
|
+
}
|
107
|
+
]
|
108
|
+
end
|
109
|
+
end
|
110
|
+
|
111
|
+
# @return [Boolean]
|
112
|
+
def is_button(step)
|
113
|
+
!!ProconBypassMan::Procon::ButtonCollection::BUTTONS_MAP[step.to_sym]
|
114
|
+
end
|
115
|
+
|
116
|
+
def to_num(value)
|
117
|
+
if value.include?("_")
|
118
|
+
value.sub("_", ".").to_f
|
119
|
+
else
|
120
|
+
value.to_i
|
121
|
+
end
|
122
|
+
end
|
123
|
+
end
|
@@ -1,39 +1,21 @@
|
|
1
1
|
class ProconBypassMan::Procon::MacroRegistry
|
2
|
-
class Macro
|
3
|
-
attr_accessor :name, :steps
|
4
|
-
|
5
|
-
def initialize(name: , steps: )
|
6
|
-
self.name = name
|
7
|
-
self.steps = steps
|
8
|
-
end
|
9
|
-
|
10
|
-
def next_step
|
11
|
-
steps.shift
|
12
|
-
end
|
13
|
-
|
14
|
-
def finished?
|
15
|
-
steps.empty?
|
16
|
-
end
|
17
|
-
|
18
|
-
def ongoing?
|
19
|
-
!finished?
|
20
|
-
end
|
21
|
-
end
|
22
|
-
|
23
2
|
PRESETS = {
|
24
3
|
null: [],
|
25
4
|
}
|
26
5
|
|
27
|
-
def self.install_plugin(klass)
|
28
|
-
if plugins[klass.
|
29
|
-
raise "
|
6
|
+
def self.install_plugin(klass, steps: nil)
|
7
|
+
if plugins[klass.to_s.to_sym]
|
8
|
+
raise "#{klass} macro is already registered"
|
30
9
|
end
|
31
|
-
|
10
|
+
|
11
|
+
plugins[klass.to_s.to_sym] = ->{
|
12
|
+
ProconBypassMan::Procon::MacroBuilder.new(steps || klass.steps).build
|
13
|
+
}
|
32
14
|
end
|
33
15
|
|
34
16
|
def self.load(name)
|
35
|
-
steps = PRESETS[name] || plugins[name] || raise("unknown macro")
|
36
|
-
Macro.new(name: name, steps: steps.dup)
|
17
|
+
steps = PRESETS[name] || plugins[name].call || raise("unknown macro")
|
18
|
+
ProconBypassMan::Procon::Macro.new(name: name, steps: steps.dup)
|
37
19
|
end
|
38
20
|
|
39
21
|
def self.reset!
|
@@ -23,14 +23,14 @@ class ProconBypassMan::Procon::ModeRegistry
|
|
23
23
|
}
|
24
24
|
|
25
25
|
def self.install_plugin(klass)
|
26
|
-
if plugins[klass.
|
27
|
-
raise "
|
26
|
+
if plugins[klass.to_s.to_sym]
|
27
|
+
raise "#{klass} mode is already registered"
|
28
28
|
end
|
29
|
-
plugins[klass.
|
29
|
+
plugins[klass.to_s.to_sym] = ->{ klass.binaries }
|
30
30
|
end
|
31
31
|
|
32
32
|
def self.load(name)
|
33
|
-
b = PRESETS[name] || plugins[name] || raise("unknown mode")
|
33
|
+
b = PRESETS[name] || plugins[name]&.call || raise("#{name} is unknown mode")
|
34
34
|
Mode.new(name: name, binaries: b.dup)
|
35
35
|
end
|
36
36
|
|
@@ -1,14 +1,15 @@
|
|
1
1
|
class ProconBypassMan::PressButtonAware
|
2
|
+
BIT_ON = '1'.freeze
|
3
|
+
|
2
4
|
def initialize(binary)
|
3
5
|
@binary = binary
|
4
6
|
end
|
5
7
|
|
8
|
+
# @param [Symbol]
|
9
|
+
# @return [Boolean]
|
6
10
|
def pressing_button?(button)
|
7
11
|
button_obj = ProconBypassMan::Procon::Button.new(button)
|
8
|
-
@binary[
|
9
|
-
|
10
|
-
].unpack("H*").first.to_i(16).to_s(2).reverse[
|
11
|
-
button_obj.bit_position
|
12
|
-
] == '1'
|
12
|
+
byte = @binary[button_obj.byte_position].unpack("C").first.to_s(2).reverse
|
13
|
+
byte[button_obj.bit_position] == BIT_ON
|
13
14
|
end
|
14
15
|
end
|
@@ -33,9 +33,23 @@ class ProconBypassMan::Procon::UserOperation
|
|
33
33
|
binary.write_as_press_button(button)
|
34
34
|
end
|
35
35
|
|
36
|
-
# @param [Symbol] button
|
36
|
+
# @param [Symbol, Array<Symbol>] button
|
37
37
|
def press_button_only(button)
|
38
|
-
|
38
|
+
if button.is_a?(Array)
|
39
|
+
binary.set_no_action!
|
40
|
+
button.uniq.each do |b|
|
41
|
+
unless ProconBypassMan::Procon::MacroBuilder::RESERVED_WORD_NONE == b
|
42
|
+
binary.write_as_press_button(b)
|
43
|
+
end
|
44
|
+
end
|
45
|
+
return
|
46
|
+
end
|
47
|
+
|
48
|
+
if ProconBypassMan::Procon::MacroBuilder::RESERVED_WORD_NONE == button
|
49
|
+
binary.set_no_action!
|
50
|
+
else
|
51
|
+
binary.write_as_press_button_only(button)
|
52
|
+
end
|
39
53
|
end
|
40
54
|
|
41
55
|
# @return [void]
|
@@ -5,7 +5,7 @@ class ProconBypassMan::Procon::AnalogStick
|
|
5
5
|
def initialize(binary: )
|
6
6
|
@neutral_position = ProconBypassMan::ButtonsSettingConfiguration.instance.neutral_position
|
7
7
|
bytes = binary[ProconBypassMan::Procon::ButtonCollection::LEFT_ANALOG_STICK.fetch(:byte_position)]
|
8
|
-
byte6, byte7, byte8 = bytes.each_char.map { |x| x.unpack("
|
8
|
+
byte6, byte7, byte8 = bytes.each_char.map { |x| x.unpack("C").first.to_s(2).rjust(8, "0") }
|
9
9
|
|
10
10
|
self.bin_x = "#{byte7[4..7]}#{byte6}"
|
11
11
|
self.bin_y = "#{byte8}#{byte7[0..3]}"
|
@@ -1,7 +1,9 @@
|
|
1
1
|
class ProconBypassMan::Procon
|
2
2
|
require "procon_bypass_man/procon/consts"
|
3
3
|
require "procon_bypass_man/procon/mode_registry"
|
4
|
+
require "procon_bypass_man/procon/macro"
|
4
5
|
require "procon_bypass_man/procon/macro_registry"
|
6
|
+
require "procon_bypass_man/procon/macro_builder"
|
5
7
|
require "procon_bypass_man/procon/layer_changer"
|
6
8
|
require "procon_bypass_man/procon/button_collection"
|
7
9
|
require "procon_bypass_man/procon/user_operation"
|
@@ -102,12 +104,12 @@ class ProconBypassMan::Procon
|
|
102
104
|
user_operation.unpress_button(button)
|
103
105
|
end
|
104
106
|
|
105
|
-
current_layer.left_analog_stick_caps.each do |
|
106
|
-
if
|
107
|
-
|
107
|
+
current_layer.left_analog_stick_caps.each do |config|
|
108
|
+
if config[:if_pressed].nil? || user_operation.pressing_all_buttons?(config[:if_pressed])
|
109
|
+
config[:force_neutral]&.each do |force_neutral_button|
|
108
110
|
user_operation.unpress_button(force_neutral_button)
|
109
111
|
end
|
110
|
-
user_operation.apply_left_analog_stick_cap(cap:
|
112
|
+
user_operation.apply_left_analog_stick_cap(cap: config[:cap])
|
111
113
|
end
|
112
114
|
end
|
113
115
|
|
@@ -6,9 +6,9 @@ module ProconBypassMan
|
|
6
6
|
require "pbmenv"
|
7
7
|
ProconBypassMan.logger.info "execute RestorePbmSettingAction!"
|
8
8
|
setting = args.dig("setting") or raise(ProconBypassMan::RemotePbmAction::NeedPbmVersionError, "settingが必要です, #{args.inspect}")
|
9
|
-
|
10
|
-
ProconBypassMan::ButtonsSettingConfiguration.instance.setting_path,
|
11
|
-
setting
|
9
|
+
ProconBypassMan::YamlWriter.write(
|
10
|
+
path: ProconBypassMan::ButtonsSettingConfiguration.instance.setting_path,
|
11
|
+
content: setting,
|
12
12
|
)
|
13
13
|
ProconBypassMan.hot_reload!
|
14
14
|
end
|
@@ -32,7 +32,9 @@ module ProconBypassMan
|
|
32
32
|
}
|
33
33
|
|
34
34
|
client.received do |data|
|
35
|
-
|
35
|
+
ProconBypassMan.logger.info(data)
|
36
|
+
|
37
|
+
dispatch(data: data, client: client)
|
36
38
|
rescue => e
|
37
39
|
ProconBypassMan::SendErrorCommand.execute(error: e)
|
38
40
|
end
|
@@ -51,11 +53,20 @@ module ProconBypassMan
|
|
51
53
|
end
|
52
54
|
end
|
53
55
|
|
56
|
+
# @param [Hash] data
|
57
|
+
def self.dispatch(data: , client: )
|
58
|
+
pbm_job_hash = data.dig("message")
|
59
|
+
if pbm_job_hash['action'] == "ping"
|
60
|
+
client.perform('pong', { device_id: ProconBypassMan.device_id, message: 'hello from pbm' })
|
61
|
+
else
|
62
|
+
validate_and_run(data: data)
|
63
|
+
end
|
64
|
+
end
|
65
|
+
|
54
66
|
# @raise [ProconBypassMan::RemotePbmActionObject::ValidationError]
|
55
67
|
# @param [Hash] data
|
56
68
|
# @return [Void]
|
57
69
|
def self.validate_and_run(data: )
|
58
|
-
ProconBypassMan.logger.debug { data }
|
59
70
|
pbm_job_hash = data.dig("message")
|
60
71
|
begin
|
61
72
|
pbm_job_object = ProconBypassMan::RemotePbmActionObject.new(action: pbm_job_hash["action"],
|
data/lib/procon_bypass_man.rb
CHANGED
@@ -7,11 +7,13 @@ require "securerandom"
|
|
7
7
|
require 'em/pure_ruby'
|
8
8
|
require "action_cable_client"
|
9
9
|
require "ext/em_pure_ruby"
|
10
|
+
require "ext/module"
|
10
11
|
|
11
12
|
require_relative "procon_bypass_man/version"
|
12
13
|
require_relative "procon_bypass_man/remote_pbm_action"
|
13
14
|
require_relative "procon_bypass_man/support/signal_handler"
|
14
15
|
require_relative "procon_bypass_man/support/callbacks"
|
16
|
+
require_relative "procon_bypass_man/support/yaml_writer"
|
15
17
|
require_relative "procon_bypass_man/support/safe_timeout"
|
16
18
|
require_relative "procon_bypass_man/support/compress_array"
|
17
19
|
require_relative "procon_bypass_man/support/uptime"
|
data/procon_bypass_man.gemspec
CHANGED
@@ -8,7 +8,7 @@ Gem::Specification.new do |spec|
|
|
8
8
|
spec.authors = ["jiikko"]
|
9
9
|
spec.email = ["n905i.1214@gmail.com"]
|
10
10
|
|
11
|
-
spec.summary = "
|
11
|
+
spec.summary = "A programmable converter for Nintendo Switch Pro Controller"
|
12
12
|
spec.description = spec.summary
|
13
13
|
spec.homepage = "https://github.com/splaplapla/procon_bypass_man"
|
14
14
|
spec.license = "MIT"
|
data/project_template/app.rb
CHANGED
@@ -5,14 +5,15 @@ 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.19.1'
|
9
9
|
end
|
10
10
|
|
11
11
|
ProconBypassMan.configure do |config|
|
12
12
|
config.root = File.expand_path(__dir__)
|
13
13
|
config.logger = Logger.new("#{ProconBypassMan.root}/app.log", 5, 1024 * 1024 * 10)
|
14
14
|
config.logger.level = :debug
|
15
|
-
#
|
15
|
+
# webからProconBypassManを操作できるwebサービス
|
16
|
+
# config.api_servers = ['https://pbm-cloud.herokuapp.com']
|
16
17
|
config.enable_critical_error_logging = true
|
17
18
|
end
|
18
19
|
|
@@ -1,35 +1,28 @@
|
|
1
1
|
version: 1.0
|
2
2
|
setting: |-
|
3
|
-
|
4
|
-
guruguru = ProconBypassMan::Plugin::Splatoon2::Mode::Guruguru
|
5
|
-
|
6
|
-
install_macro_plugin fast_return
|
3
|
+
install_macro_plugin ProconBypassMan::Plugin::Splatoon2::Macro::FastReturn
|
7
4
|
install_macro_plugin ProconBypassMan::Plugin::Splatoon2::Macro::JumpToUpKey
|
8
5
|
install_macro_plugin ProconBypassMan::Plugin::Splatoon2::Macro::JumpToRightKey
|
9
6
|
install_macro_plugin ProconBypassMan::Plugin::Splatoon2::Macro::JumpToLeftKey
|
10
|
-
install_mode_plugin
|
7
|
+
install_mode_plugin ProconBypassMan::Plugin::Splatoon2::Mode::Guruguru
|
11
8
|
|
12
9
|
prefix_keys_for_changing_layer [:zr, :zl, :l]
|
13
10
|
|
14
11
|
layer :up, mode: :manual do
|
15
|
-
# flip :zr, if_pressed: :zr, force_neutral: :zl
|
16
12
|
flip :zr, if_pressed: :zr, force_neutral: :zl
|
17
13
|
flip :zl, if_pressed: [:y, :b, :zl]
|
18
14
|
flip :a, if_pressed: [:a]
|
19
15
|
flip :down, if_pressed: :down
|
20
|
-
macro
|
16
|
+
macro ProconBypassMan::Plugin::Splatoon2::Macro::FastReturn, if_pressed: [:y, :b, :down]
|
21
17
|
macro ProconBypassMan::Plugin::Splatoon2::Macro::JumpToUpKey, if_pressed: [:y, :b, :up]
|
22
18
|
macro ProconBypassMan::Plugin::Splatoon2::Macro::JumpToRightKey, if_pressed: [:y, :b, :right]
|
23
19
|
macro ProconBypassMan::Plugin::Splatoon2::Macro::JumpToLeftKey, if_pressed: [:y, :b, :left]
|
24
20
|
remap :l, to: :zr
|
25
21
|
end
|
26
|
-
layer :right, mode:
|
22
|
+
layer :right, mode: ProconBypassMan::Plugin::Splatoon2::Mode::Guruguru
|
27
23
|
layer :left do
|
28
|
-
# flip :zr, if_pressed: :zr, force_neutral: :zl
|
29
24
|
remap :l, to: :zr
|
30
25
|
end
|
31
26
|
layer :down do
|
32
|
-
# flip :zl
|
33
|
-
# flip :zr, if_pressed: :zr, force_neutral: :zl, flip_interval: "1F"
|
34
27
|
remap :l, to: :zr
|
35
28
|
end
|