Skip to content

Commit

Permalink
Merge 69a0fd4 into edcfacb
Browse files Browse the repository at this point in the history
  • Loading branch information
koi-chan committed Jul 21, 2019
2 parents edcfacb + 69a0fd4 commit 6fc0559
Show file tree
Hide file tree
Showing 14 changed files with 210 additions and 43 deletions.
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -4,4 +4,5 @@
!doc/plugins
/vendor/
/data/cre_twitter_citation/last_cited.txt
/data/dice_roll/*
!.editorconfig
3 changes: 3 additions & 0 deletions Gemfile
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,9 @@ gem 'mail', '~> 2.7'

group :irc do
gem 'cinch'

# DiceRollプラグインで使用する
gem 'gdbm'
end

group :discord do
Expand Down
4 changes: 3 additions & 1 deletion Gemfile.lock
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,7 @@ GEM
equalizer (0.0.11)
event_emitter (0.2.6)
ffi (1.11.1)
gdbm (2.0.0)
guess_html_encoding (0.0.11)
hashdiff (0.4.0)
http (3.3.0)
Expand Down Expand Up @@ -161,6 +162,7 @@ DEPENDENCIES
coveralls
d1lcs
discordrb
gdbm
guess_html_encoding
http (> 0.9)
lumberjack (~> 1.0)
Expand All @@ -176,4 +178,4 @@ DEPENDENCIES
yard (~> 0.8)

BUNDLED WITH
2.0.1
2.0.2
Empty file added data/dice_roll/.keep
Empty file.
47 changes: 47 additions & 0 deletions doc/plugins/dice_roll.md
Original file line number Diff line number Diff line change
Expand Up @@ -65,6 +65,53 @@ _XX_ には 1~20 桁の数字を指定します。ただし、途中に 0 を
> foo -> d66 = [5,6] = 56
```

### シークレットロール

#### 書式

```
.sroll 2d6
.sroll d66
.sroll-open
```

#### 説明

上記のどちらのコマンドも、`.roll``.sroll` に置き換えることで、シークレットロールに出来ます。

チャンネルでシークレットロールコマンドを発言すると、トークでダイス結果を本人だけに知らせます。
トークでシークレットロールコマンドを発言すると、シークレットロールを開けるまで誰にも結果は分かりません。

どちらも、シークレットロールを開けるコマンドは、シークレットロールコマンドを発言したチャンネル(もしくはトーク)だけで有効です。

####

```
(#channel) .sroll 2d6
(#channel) > foo: シークレットロールを保存しました
(talk) > チャンネル #channel でのシークレットロール: foo -> 2d6 = [2,4] = 6
(#channel) .sroll d66
(#channel) > foo: シークレットロールを保存しました
(talk) > チャンネル #channel でのシークレットロール: foo -> d66 = [1,5] = 15
(#channel) .sroll-open
(#channel) > #channel のシークレットロール: 2 件
(#channel) > foo -> 2d6 = [2,4] = 6
(#channel) > foo -> d66 = [1,5] = 15
(#channel) > シークレットロールここまで
(talk) .sroll d66
(talk) > シークレットロールを保存しました
(talk) .sroll 2d6
(talk) > シークレットロールを保存しました
(talk) .sroll-open
(talk) > foo のシークレットロール: 2 件
(talk) > foo -> d66 = [6,5] = 65
(talk) > foo -> 2d6 = [1,2] = 3
(talk) > シークレットロールここまで
```


設定
----

Expand Down
9 changes: 7 additions & 2 deletions lib/rgrb/config.rb
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,9 @@
module RGRB
# RGRB の設定を表すクラス
class Config
# 設定 ID
# @return [String]
attr_reader :id
# IRC ボットの設定のハッシュ
# @return [Hash]
attr_reader :irc_bot
Expand Down Expand Up @@ -45,14 +48,16 @@ def load_yaml_file(config_id, root_path)
config_data.merge!(child_config_data)
end

new(config_data)
new(config_id, config_data)
end
end

# 新しい RGRB::Config インスタンスを返す
# @param [String] id 設定 ID
# @param [Hash] config_data 設定データのハッシュ
# @return [RGRB::Config]
def initialize(config_data)
def initialize(id, config_data)
@id = id
@irc_bot = config_data['IRCBot']
@discord_bot = config_data['DiscordBot']
@plugins = config_data['Plugins'] || []
Expand Down
3 changes: 2 additions & 1 deletion lib/rgrb/exec/irc_bot.rb
Original file line number Diff line number Diff line change
Expand Up @@ -100,7 +100,8 @@ def extract_plugin_options(

plugin_options[adapter] = {
root_path: root_path,
plugin: plugin_config
plugin: plugin_config,
config_id: config.id
}

logger.warn(
Expand Down
1 change: 1 addition & 0 deletions lib/rgrb/plugin/configurable_adapter.rb
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ def prepare_generator
generator_class = Object.const_get(class_name_tree.join('::'))
@generator = generator_class.new

@generator.config_id = config[:config_id]
@generator.root_path = config[:root_path]

# プラグインをロガーとして使えるよう、設定に含める
Expand Down
5 changes: 3 additions & 2 deletions lib/rgrb/plugin/configurable_generator.rb
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,9 @@ module RGRB
module Plugin
# 設定できる出力テキスト生成器のモジュール
module ConfigurableGenerator
# 設定 ID
# @return [String]
attr_accessor :config_id
# RGRB のルートパス
# @return [String]
# @note root_path を設定すると、それに合わせて
Expand All @@ -21,8 +24,6 @@ module ConfigurableGenerator
def initialize
class_name_tree = self.class.name.split('::')
@plugin_name_underscore = class_name_tree[-2].underscore

self.root_path = File.expand_path('../../..', __dir__)
end

# RGRB のルートパスを設定する
Expand Down
62 changes: 62 additions & 0 deletions lib/rgrb/plugin/dice_roll/generator.rb
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,9 @@
require 'rgrb/plugin/configurable_generator'
require 'rgrb/plugin/dice_roll/dice_roll_result'

require 'gdbm'
require 'json'

module RGRB
module Plugin
# ダイスロールを行うプラグイン
Expand All @@ -15,7 +18,20 @@ class Generator
EXCESS_DICE_MESSAGE = "ダイスが机から落ちてしまいましたの☆"

def initialize
super
@random = Random.new
@mutex_secret_dice = Mutex.new
end

# プラグインの設定を行う
# @return [self]
def configure(config_data)
super

@db_dir = "#{@data_path}/#{@config_id}"
prepare_db_dir

@db_secret_dice = "#{@db_dir}/secret_dice"
end

# 基本的なダイスロールの結果を返す
Expand Down Expand Up @@ -52,6 +68,32 @@ def dxx_dice_ja(rolls_ja)
dxx_dice("#{ja_to_i(rolls_ja)}")
end

# シークレットロールの結果をデータベースに保存する
# @param [String] target ダイスコマンド実行元(チャンネル名・ニックネーム)
# @param [String] message ダイスロール実行結果
# @return [void]
def save_secret_roll(target, message)
@mutex_secret_dice.synchronize do
GDBM.open(@db_secret_dice) do |db|
store = db.has_key?(target) ? JSON.parse(db[target]) : []
store << message
db[target] = JSON.generate(store)
end
end
end

# @param [String] target
# @return [Array, nil]
def open_dice(target)
@mutex_secret_dice.synchronize do
GDBM.open(@db_secret_dice) do |db|
if db.has_key?(target)
JSON.parse(db.delete(target))
end
end
end
end

# ダイスロールの結果を返す
# @param [Integer] rolls ダイスの個数
# @param [Integer] sides ダイスの最大値
Expand All @@ -70,9 +112,29 @@ def dxx_roll(rolls)
values
end

# 日本語ダイスコマンドを数字に変換する
# Trpg::Detatoko プラグインにて呼び出しているので public メソッド
# @param [String] japanese 日本語(ア段)
# @return [String]
def ja_to_i(japanese)
japanese.tr('あかさたなはまやらわ', '1234567890').to_i
end

private

# データベースディレクトリを準備する
# @return [void]
def prepare_db_dir
unless FileTest.exist?(@db_dir)
# 存在しなければ、ディレクトリを作成する
Dir.mkdir(@db_dir)
else
unless FileTest.directory?(@db_dir)
# ディレクトリ以外のファイルが存在したらエラー
raise RuntimeError
end
end
end
end
end
end
Expand Down
96 changes: 78 additions & 18 deletions lib/rgrb/plugin/dice_roll/irc_adapter.rb
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
require 'rgrb/plugin/configurable_adapter'
require 'rgrb/plugin/dice_roll/constants'
require 'rgrb/plugin/dice_roll/generator'
require 'rgrb/plugin/util/logging'
require 'rgrb/plugin/util/notice_multi_lines'

module RGRB
module Plugin
Expand All @@ -13,12 +13,15 @@ module DiceRoll
class IrcAdapter
include Cinch::Plugin
include ConfigurableAdapter
include Util::Logging
include Util::NoticeMultiLines

set(plugin_name: 'DiceRoll')
self.prefix = /\.roll[\s ]+/
match(/(#{NUMS_RE})d(#{NUMS_RE})/io, method: :basic_dice)
match(/d(#{NUM_RE}+)/io, method: :dxx_dice)
match(/(#{NUMS_RE})d(#{NUMS_RE})/io, method: :basic_dice_secret, prefix: /\.sroll[\s ]+/)
match(/d(#{NUM_RE}+)/io, method: :dxx_dice_secret, prefix: /\.sroll[\s ]+/)
match('-open', method: :open_dice, prefix: '.sroll')

match(/(#{KANA_NUMS_RE})の(#{KANA_NUMS_RE})/io, method: :basic_dice_ja, :prefix => '。')
match(/の(#{KANA_NUM_RE}+)/io, method: :dxx_dice_ja, :prefix => '。')
Expand All @@ -27,8 +30,7 @@ def initialize(*args)
super

config_data = config[:plugin]
@jadice = true
@jadice = false if config_data['JaDice'] == false
@jadice = config_data['JaDice'] == false ? false : true

prepare_generator
end
Expand All @@ -37,38 +39,96 @@ def initialize(*args)
# @return [void]
def basic_dice(m, n_dice, max)
log_incoming(m)
result = @generator.basic_dice(n_dice.to_i, max.to_i)
message = "#{m.user.nick} -> #{result}"
m.target.send(message, true)
log_notice(m.target, message)
send_result(m, @generator.basic_dice(n_dice.to_i, max.to_i))
end

# 基本的なダイスロールの結果を返す
# シークレットロール
# @return [void]
def basic_dice_secret(m, n_dice, max)
log_incoming(m)
send_result(m, @generator.basic_dice(n_dice.to_i, max.to_i), true)
end

# 日本語版の basic_dice
# @return [void]
def basic_dice_ja(m, n_dice, max)
log_incoming(m)
return unless @jadice

result = @generator.basic_dice_ja(n_dice, max)
message = "#{m.user.nick} -> #{result}"
m.target.send(message, true)
log_notice(m.target, message)
send_result(m, @generator.basic_dice_ja(n_dice, max))
end

# d66 など、出目をそのままつなげるダイスロールの結果を返す
# @return [void]
def dxx_dice(m, rolls)
log_incoming(m)
result = @generator.dxx_dice(rolls)
message = "#{m.user.nick} -> #{result}"
m.target.send(message, true)
log_notice(m.target, message)
send_result(m, @generator.dxx_dice(rolls))
end

# d66 など、出目をそのままつなげるダイスロールの結果を返す
# シークレットロール
# @return [void]
def dxx_dice_secret(m, rolls)
log_incoming(m)
send_result(m, @generator.dxx_dice(rolls), true)
end

# 日本語版の dxx_dice
# @return [void]
def dxx_dice_ja(m, rolls)
log_incoming(m)
return unless @jadice

result = @generator.dxx_dice_ja(rolls)
message = "#{m.user.nick} -> #{result}"
send_result(m, @generator.dxx_dice_ja(rolls))
end

# シークレットロールを表示する
# @param [Cinch::Message] m
# @return [void]
def open_dice(m)
result = @generator.open_dice(m.target.name)
messages = if result.nil?
["#{m.target.name} にはシークレットロール結果がありません"]
else
[
"#{m.target.name} のシークレットロール: #{result.size} 件",
result,
"シークレットロールここまで"
].flatten
end
notice_multi_lines(messages, m.target)
end

private

# ダイスロール結果を整形して IRC に送信する
# @param [Cinch::Message] m
# @param [String] result ダイスロール結果
# @param [Boolean] secret シークレットダイスか?
# @option secret true シークレットダイス
# @option secret false オープンダイス
# @return [void]
def send_result(m, result, secret = false)
result = "#{m.user.nick} -> #{result}"

message = if secret
@generator.save_secret_roll(m.target.name, result)

case(m.target.class.to_s)
when('Cinch::Channel')
message = "チャンネル #{m.target.name} でのシークレットロール: #{result}"
m.user.send(message, true)
log_notice(m.user, message)

"#{m.user.nick}: シークレットロールを保存しました"
when('Cinch::User')
'シークレットロールを保存しました'
end
else
result
end

m.target.send(message, true)
log_notice(m.target, message)
end
Expand Down
Loading

0 comments on commit 6fc0559

Please sign in to comment.