Skip to content

Commit

Permalink
Merge da72a29 into f73f597
Browse files Browse the repository at this point in the history
  • Loading branch information
ochaochaocha3 committed Jul 26, 2018
2 parents f73f597 + da72a29 commit 6155bb5
Show file tree
Hide file tree
Showing 6 changed files with 214 additions and 48 deletions.
8 changes: 3 additions & 5 deletions .travis.yml
Original file line number Diff line number Diff line change
Expand Up @@ -3,11 +3,9 @@ language: ruby
cache: bundler
bundler_args: --deployment
rvm:
- 2.2.9
- 2.3.1
- 2.3.6
- 2.4.3
- 2.5.0
- 2.3.7
- 2.4.4
- 2.5.1
before_install:
# https://github.com/travis-ci/travis-ci/issues/8978#issuecomment-354036443
- gem update --system
Expand Down
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ RGRB は Ruby で実装されている汎用 IRC ボットです。プラグイ

* Linux または OSX
* 現在のところ Windows には未対応。
* Ruby 2.2.2 以降
* Ruby 2.3 以降

インストール
------------
Expand Down
42 changes: 42 additions & 0 deletions lib/rgrb/plugin/bcdice/errors.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
# vim: fileencoding=utf-8

module RGRB
module Plugin
module Bcdice
# ダイスボットが見つからないことを示すエラー
class DiceBotNotFound < StandardError
# @return [String] ゲームタイプ
attr_reader :game_type

# エラーを初期化する
# @param [String] game_type ゲームタイプ
def initialize(game_type)
super("ゲームシステム「#{game_type}」は見つかりませんでした")

@game_type = game_type
end
end

# 無効なコマンドエラー
class InvalidCommandError < StandardError
# @return [String] 指定されたコマンド
attr_reader :command
# @return [String] ゲームタイプ
attr_reader :game_type
# @return [String] ゲームシステム名
attr_reader :game_name

# エラーを初期化する
# @param [String] command 指定されたコマンド
# @param [DiceBot] dice_bot ダイスボット
def initialize(command, dice_bot)
super("コマンド「#{command}」は無効です")

@command = command
@game_type = dice_bot.gameType
@game_name = dice_bot.gameName
end
end
end
end
end
79 changes: 79 additions & 0 deletions lib/rgrb/plugin/bcdice/generator.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,79 @@
# vim: fileencoding=utf-8

require 'rgrb/plugin/bcdice/constants'
require 'rgrb/plugin/bcdice/errors'

require 'BCDice/src/cgiDiceBot'
require 'BCDice/src/diceBot/DiceBotLoader'
require 'BCDice/src/diceBot/DiceBotLoaderList'

module RGRB
module Plugin
# BCDice のラッパープラグイン
module Bcdice
# BCDice の呼び出し結果
BcdiceResult = Struct.new(:error, :message_lines, :game_type, :game_name)

# Bcdice の出力テキスト生成器
class Generator
# 生成器を初期化する
def initialize
@bcdice = CgiDiceBot.new
end

# BCDice でダイスを振った結果を返す
# @param [String] command ダイスコマンド
# @param [String] specified_game_type 指定されたゲームタイプ
# @return [BcdiceResult]
# @raise [DiceBotNotFound] ダイスボットが見つからなかった場合
# @raise [InvalidCommandError] 無効なコマンドが指定された場合
def bcdice(command, specified_game_type = nil)
# ゲームタイプが指定されていなかったら DiceBot にする
game_type = specified_game_type || 'DiceBot'
# ダイスボットを探す
dice_bot = find_dice_bot(game_type)
# ダイスボットが見つからなかった場合は中断する
raise DiceBotNotFound, game_type unless dice_bot

result, _ = @bcdice.roll(command, game_type)
# 結果が返ってこなかった場合は中断する
raise InvalidCommandError.new(command, dice_bot) if result.empty?

# 結果の行の配列
message_lines = result.lstrip.split(' : ', 2)[1].lines

# 結果を返す
BcdiceResult.new(command,
message_lines,
dice_bot.gameType,
dice_bot.gameName)
end

# git submodule で組み込んでいる BCDice のバージョンを返す
# @return [String]
def bcdice_version
bcdice_path = File.expand_path('../../../../vendor/BCDice', __dir__)
commit_id = Dir.chdir(bcdice_path) do
`git show -s --format=%H`.strip
end

"BCDice Commit ID: #{commit_id}"
end

private

# ダイスボットを探す
# @param [String] game_type ゲームタイプ
# @return [DiceBot]
def find_dice_bot(game_type)
if game_type == 'DiceBot'
DiceBot.new
else
DiceBotLoaderList.find(game_type)&.loadDiceBot ||
DiceBotLoader.loadUnknownGame(game_type)
end
end
end
end
end
end
72 changes: 30 additions & 42 deletions lib/rgrb/plugin/bcdice/irc_adapter.rb
Original file line number Diff line number Diff line change
@@ -1,16 +1,18 @@
# vim: fileencoding=utf-8

require 'cinch'

require 'rgrb/plugin/util/notice_multi_lines'
require 'rgrb/plugin/bcdice/constants'
require 'rgrb/plugin/bcdice/errors'
require 'rgrb/plugin/bcdice/generator'

require 'BCDice/src/cgiDiceBot'
require 'BCDice/src/diceBot/DiceBotLoader'
require 'BCDice/src/diceBot/DiceBotLoaderList'

module RGRB
module Plugin
# BCDice のラッパープラグイン
module Bcdice
# Bcdice の IRC アダプター
class IrcAdapter
Expand All @@ -25,7 +27,7 @@ class IrcAdapter
def initialize(*args)
super

@bcdice = CgiDiceBot.new
@generator = Generator.new
@header = 'BCDice'
end

Expand All @@ -40,42 +42,18 @@ def bcdice(m, command, specified_game_title)
# 共通のヘッダ
header_common = "#{@header}[#{m.user.nick}]"

# ゲームタイトルが指定されていなかったら DiceBot にする
game_title = specified_game_title || 'DiceBot'
# ダイスボットを探す
dice_bot = DiceBotLoaderList.find(game_title)&.loadDiceBot ||
DiceBotLoader.loadUnknownGame(game_title)

unless dice_bot
# ダイスボットが見つからなかった場合は中断する
message = "#{header_common}: " \
"ゲームシステム「#{game_title}」は見つかりませんでした"

log_notice(m.target, message)
m.target.send(message, true)

return
end
result =
begin
@generator.bcdice(command, specified_game_title)
rescue => e
notice_bcdice_error(m.target, header_common, e)
return
end

# ゲームシステム名を含むヘッダ
header = "#{header_common}<#{dice_bot.gameName}>: "

result, _ = @bcdice.roll(command, game_title)

if result.empty?
# 結果が返ってこなかった場合は中断する
message = "#{header}コマンド「#{command}」は無効です"

log_notice(m.target, message)
m.target.send(message, true)
header = "#{header_common}<#{result.game_name}>: "

return
end

# 結果の行の配列
message_lines = result.lstrip.split(' : ', 2)[1].lines

notice_multi_lines(message_lines, m.target, header)
notice_multi_lines(result.message_lines, m.target, header)
end

# git submodule で組み込んでいる BCDice のバージョンを出力する
Expand All @@ -84,17 +62,27 @@ def bcdice(m, command, specified_game_title)
def version(m)
log_incoming(m)

message = 'BCDice Commit ID: '
message += Dir.chdir(File.expand_path(
'../../../../vendor/BCDice',
File.dirname(__FILE__)
)) do |path|
`git show -s --format=%H`.strip
end
message = @generator.bcdice_version

log_notice(m.target, message)
m.target.send(message, true)
end

private

# BCDice 関連のエラーを NOTICE する
# @param [Cinch::Target] target 送信先
# @param [String] header_common 共通のヘッダ
# @param [StandardError] error エラー
# @return [void]
def notice_bcdice_error(target, header_common, error)
header = error.respond_to?(:game_name) ?
"#{header_common}<#{error.game_name}>" : header_common
message = "#{header}: #{error.message}"

log_notice(target, message)
target.send(message, true)
end
end
end
end
Expand Down
59 changes: 59 additions & 0 deletions spec/rgrb/plugin/bcdice/generator_spec.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
# vim: fileencoding=utf-8

require_relative '../../../spec_helper'

require 'rgrb/plugin/bcdice/generator'
require 'rgrb/plugin/bcdice/errors'

describe RGRB::Plugin::Bcdice::Generator do
let(:generator) { described_class.new }

describe '#bcdice_version' do
it 'BCDice のバージョンを出力する' do
expect(generator.bcdice_version).to(
match(/\ABCDice Commit ID: [0-9a-f]{40}\z/)
)
end
end

describe '#bcdice' do
context('ゲームシステムなし') do
context('無効なコマンド') do
it '無効なコマンドのエラーが発生する' do
expect { generator.bcdice('not_found') }.to raise_error(
RGRB::Plugin::Bcdice::InvalidCommandError,
'コマンド「not_found」は無効です'
)
end
end

context('2d6') do
subject { generator.bcdice('2d6') }

it 'ゲームシステムとして DiceBot が選ばれる' do
expect(subject.game_type).to eq('DiceBot')
expect(subject.game_name).to eq('DiceBot')
end

it '2d6 の結果が返る' do
expect(subject.message_lines[0].start_with?('(2D6) > ')).to be(true)
end
end
end

context('ソード・ワールド2.0、k20') do
context('k20') do
subject { generator.bcdice('k20', 'SwordWorld2_0') }

it 'ゲームシステムとして「ソード・ワールド2.0」が選ばれる' do
expect(subject.game_type).to eq('SwordWorld2.0')
expect(subject.game_name).to eq('ソードワールド2.0')
end

it 'k20 の結果が返る' do
expect(subject.message_lines[0].start_with?('KeyNo.20c')).to be(true)
end
end
end
end
end

0 comments on commit 6155bb5

Please sign in to comment.