procon_bypass_man 0.1.16.1 → 0.1.19.1
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 +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
|