bcdice / BCDice

The most popular TRPG dice command engine in Japan
https://bcdice.org
BSD 3-Clause "New" or "Revised" License
140 stars 184 forks source link

メッセージ送信処理を別クラスに分離する #177

Closed ochaochaocha3 closed 4 years ago

ochaochaocha3 commented 4 years ago

メッセージ送信処理について、BCDiceクラスがハブになっており(BCDice#sendMessage など。CardTraderもそれらを使用する)、手を加えにくい。 また、BCDice#sendMessageToOnlySender にはIRCのニックネーム(@nick_e)を含める処理が含まれており、このメソッドはIRCに依存する。 さらに、これらの委譲先は @ircClient であり、IRCボットの分離後は不適切な名前である。

そこで、BCDice#sendMessageを中心とするメッセージ送信処理を担当するオブジェクトを @ircClient 以外に改名して、BCDiceおよびCardTraderの各クラスに所持させる。 また、最終的に @nick_e をBCDiceから取り除き、IRCボットに移動する。

インターフェース案

インターフェース名を「MessageSink」 とする。 各クラスは、メッセージ生成時に message_sink という引数でこのインターフェースを持つオブジェクトを渡し、使う(インスタンス変数にしない)。 MessageSinkは、受信したメッセージごとに割り当てられ、以下の情報を持つものとする。

MessageSinkインターフェースを持つオブジェクトは、以下に示すメソッドを持つ。


# @return [String] メッセージを受信した部屋。
attr_reader :room

# @return [String] 送信者。
attr_reader :sender

# 部屋にメッセージを送信する
# @param [String] message 送信するメッセージ
# @return [void]
def to_room(message); end

# 送信者にメッセージを返信する
# @param [String] message 送信するメッセージ
# @return [void]
def to_sender(message); end

# 全部屋にメッセージを送信する
# @param [String] message 送信するメッセージ
# @return [void]
def broadcast(message)
  @bot.broadcast(message)
end

BCDice@nick_e の除去について

BCDiceやCardTraderで sendMessage 系を使用している部分については、上記のMessageSinkで sender にニックネームを設定することで、@nick_e を除去できる。

一方で、各システムのダイスボットにも @nick_e を使用している部分 dice_command_xRn(string, nick_e) がある。 これについては、出力がすべて "#{nick_e}: (#{string}) > #{output}" の形になることから、dice_command_xRn(string) と定義を変えて、nick_e の付加を(結果が空でない場合に)BCDice側で行うのが良い。 最近の新規ダイスボット(改版分を除く)ではdice_command_xRn が導入されることはまずないので、このメソッドのインターフェースを変更することは問題ない(変更したことを周知するのみでよい)と思われる。

ochaochaocha3 commented 4 years ago

プロットやカウンタの機能で、送信元と異なるチャンネルにメッセージを送る場合があり、to_room のインターフェースではカバーしきれなかった。また、新しくクラスを作るのも面倒だったので、quit を削除すること、@ircClient をCardHolder等に渡すことの2つくらいにとどめたい(最終的にすべて削除することもあるので)。