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.
Files changed (37) hide show
  1. checksums.yaml +4 -4
  2. data/.circleci/config.yml +3 -2
  3. data/.github/workflows/ruby.yml +5 -4
  4. data/.ruby-version +1 -1
  5. data/CHANGELOG.md +7 -1
  6. data/Gemfile +4 -0
  7. data/Gemfile.lock +52 -2
  8. data/README.md +11 -0
  9. data/Steepfile +39 -0
  10. data/bin/report_receive_server.rb +11 -0
  11. data/docs/setup_raspi.mitamae.rb +12 -0
  12. data/lib/procon_bypass_man/analog_stick_position.rb +14 -0
  13. data/lib/procon_bypass_man/boot_message.rb +40 -0
  14. data/lib/procon_bypass_man/bypass.rb +20 -7
  15. data/lib/procon_bypass_man/configuration/layer.rb +33 -3
  16. data/lib/procon_bypass_man/configuration.rb +22 -8
  17. data/lib/procon_bypass_man/device_connector.rb +10 -27
  18. data/lib/procon_bypass_man/error_reporter.rb +44 -0
  19. data/lib/procon_bypass_man/io_monitor.rb +7 -4
  20. data/lib/procon_bypass_man/on_memory_cache.rb +34 -0
  21. data/lib/procon_bypass_man/procon/analog_stick_cap.rb +88 -0
  22. data/lib/procon_bypass_man/procon/button_collection.rb +14 -6
  23. data/lib/procon_bypass_man/procon/debug_dumper.rb +17 -0
  24. data/lib/procon_bypass_man/procon/mode_registry.rb +2 -2
  25. data/lib/procon_bypass_man/procon/press_button_aware.rb +13 -0
  26. data/lib/procon_bypass_man/procon/pressed_button_helper.rb +0 -10
  27. data/lib/procon_bypass_man/procon/user_operation.rb +10 -3
  28. data/lib/procon_bypass_man/procon.rb +15 -1
  29. data/lib/procon_bypass_man/reporter.rb +42 -0
  30. data/lib/procon_bypass_man/runner.rb +34 -46
  31. data/lib/procon_bypass_man/uptime.rb +1 -1
  32. data/lib/procon_bypass_man/version.rb +1 -1
  33. data/lib/procon_bypass_man.rb +43 -2
  34. data/project_template/app.rb +3 -1
  35. data/sig/README.rb +4 -0
  36. data/sig/main.rbs +467 -0
  37. 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
- begin
80
- loop do
81
- break if $will_terminate_token
82
- bypass.send_gadget_to_procon!
83
- rescue Errno::EIO, Errno::ENODEV, Errno::EPROTO, IOError => e
84
- ProconBypassMan.logger.error "Proconが切断されました.終了処理を開始します"
85
- Process.kill "TERM", Process.ppid
86
- end
87
- ProconBypassMan.logger.info "Thread1を終了します"
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
- begin
97
- loop do
98
- break if $will_terminate_token
99
- bypass.send_procon_to_gadget!
100
- rescue EOFError => e
101
- ProconBypassMan.logger.error "Proconと通信ができませんでした.終了処理を開始します"
102
- Process.kill "TERM", Process.ppid
103
- rescue Errno::EIO, Errno::ENODEV, Errno::EPROTO, IOError => e
104
- ProconBypassMan.logger.error "Proconが切断されました。終了処理を開始します"
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
- booted_message = <<~EOF
159
- ----
160
- RUBY_VERSION: #{RUBY_VERSION}
161
- ProconBypassMan: #{ProconBypassMan::VERSION}
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
@@ -7,7 +7,7 @@ module ProconBypassMan
7
7
  return Time.now.to_i - boot_time.to_i
8
8
  rescue => e
9
9
  ProconBypassMan.logger.error(e)
10
- return "error!"
10
+ return -1
11
11
  end
12
12
  end
13
13
  end
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module ProconBypassMan
4
- VERSION = "0.1.8"
4
+ VERSION = "0.1.9"
5
5
  end
@@ -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's
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 defined?(@@logger)
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
@@ -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'
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
@@ -0,0 +1,4 @@
1
+ # SIG
2
+ ```
3
+ bundle exec rbs prototype rb lib/**/*.rb > sig/main.rbs
4
+ ```