155 lines
8.0 KiB
Python
155 lines
8.0 KiB
Python
|
import logging
|
||
|
from classes.VoiceChannelManager import VoiceChannelManager
|
||
|
|
||
|
class CommandHandler:
|
||
|
def __init__(self, bot):
|
||
|
"""CommandHandlerクラスの初期化を行う"""
|
||
|
self.bot = bot
|
||
|
self.voice_channel_manager = VoiceChannelManager()
|
||
|
|
||
|
async def handle_message(self, message):
|
||
|
"""受信したメッセージを処理する"""
|
||
|
if message.author.bot:
|
||
|
return
|
||
|
|
||
|
try:
|
||
|
if not message.content.startswith(self.bot.prefix):
|
||
|
if not self.bot.is_valid_channel(message):
|
||
|
return
|
||
|
|
||
|
if self.bot.is_independence_chat:
|
||
|
input_message = f"{message.author.display_name}: {message.content}"
|
||
|
await self.bot.independence_chat.input_message(input_message)
|
||
|
else:
|
||
|
await self.handle_synthesize(message)
|
||
|
return
|
||
|
|
||
|
command, *args = message.content[len(self.bot.prefix):].split()
|
||
|
command_handler = getattr(self, f'handle_{command}', None)
|
||
|
if command_handler:
|
||
|
await command_handler(message, args)
|
||
|
else:
|
||
|
await message.reply(f"不明なコマンドです。\n`{self.bot.prefix}help`で使用可能なコマンドを確認してください。")
|
||
|
except Exception as e:
|
||
|
logging.info(f"Failed to process message: {e}")
|
||
|
raise
|
||
|
|
||
|
async def handle_join(self, message, args):
|
||
|
"""ボイスチャンネルに接続する"""
|
||
|
if message.author.voice and message.author.voice.channel:
|
||
|
if message.guild.voice_client and message.guild.voice_client.is_connected():
|
||
|
("他のボイスチャンネルに接続しています。")
|
||
|
return
|
||
|
self.bot.target_channel_id = message.channel.id
|
||
|
await self.voice_channel_manager.join_voice_channel(message.author.voice.channel)
|
||
|
await self.bot.set_bot_status("オシゴトチュウ…")
|
||
|
else:
|
||
|
await message.reply("ボイスチャンネルに接続してください。")
|
||
|
|
||
|
async def handle_ijoin(self, message, args):
|
||
|
"""ボイスチャンネルに接続して独立チャットを有効にする"""
|
||
|
await self.handle_join(message, args)
|
||
|
await self.handle_ichat(message, args, log=False)
|
||
|
|
||
|
async def handle_leave(self, message, args):
|
||
|
"""ボイスチャンネルから切断する"""
|
||
|
self.bot.volume = 1.0
|
||
|
self.bot.reset_emotion()
|
||
|
self.bot.target_channel_id = None
|
||
|
self.bot.is_name_reading = True
|
||
|
self.bot.disable_independence_chat()
|
||
|
await self.bot.set_bot_status(f"タイキチュウ… | {self.bot.prefix}help")
|
||
|
await self.voice_channel_manager.leave_voice_channel(message.guild, self.bot)
|
||
|
|
||
|
async def handle_volume(self, message, args):
|
||
|
"""ボットの音量を設定する"""
|
||
|
try:
|
||
|
if not self.bot.is_valid_channel(message):
|
||
|
return
|
||
|
new_volume = float(args[0])
|
||
|
self.bot.volume = max(0.0, min(1.0, new_volume))
|
||
|
await message.reply(f"音量を{self.bot.volume}に設定しました。")
|
||
|
except (IndexError, ValueError):
|
||
|
await message.reply(f"正しい音量を指定してください。例: `{self.bot.prefix}volume 0.5`")
|
||
|
|
||
|
async def handle_emotion(self, message, args):
|
||
|
"""ボットの感情を設定する"""
|
||
|
try:
|
||
|
if not self.bot.is_valid_channel(message):
|
||
|
return
|
||
|
self.bot.emotion_happy = int(args[0])
|
||
|
self.bot.emotion_sad = int(args[1])
|
||
|
self.bot.emotion_angry = int(args[2])
|
||
|
self.bot.emotion_fun = int(args[3])
|
||
|
self.bot.voice_synthesizer.set_emotion(self.bot.emotion_happy, self.bot.emotion_sad, self.bot.emotion_angry, self.bot.emotion_fun)
|
||
|
await message.reply(f"感情を設定しました。\nhappy={self.bot.emotion_happy}, sad={self.bot.emotion_sad}, angry={self.bot.emotion_angry}, fun={self.bot.emotion_fun}")
|
||
|
except (IndexError, ValueError):
|
||
|
await message.reply(f"正しい感情を指定してください。\n例: `{self.bot.prefix}emotion 100 0 0 0`")
|
||
|
|
||
|
async def handle_pitch(self, message, args):
|
||
|
"""ボットの音程を設定する"""
|
||
|
try:
|
||
|
if not self.bot.is_valid_channel(message):
|
||
|
return
|
||
|
new_pitch = int(args[0])
|
||
|
self.bot.pitch = max(-300, min(300, new_pitch))
|
||
|
self.bot.voice_synthesizer.set_pitch(self.bot.pitch)
|
||
|
await message.reply(f"音程を{self.bot.pitch}に設定しました。")
|
||
|
except (IndexError, ValueError):
|
||
|
await message.reply(f"正しい音程を指定してください。\n例: `{self.bot.prefix}pitch 50`")
|
||
|
|
||
|
async def handle_dictionary(self, message, args):
|
||
|
"""単語の辞書登録を行う"""
|
||
|
try:
|
||
|
if not self.bot.is_valid_channel(message):
|
||
|
return
|
||
|
original_word, converted_word = args
|
||
|
self.bot.word_dictionary.register_word(original_word, converted_word)
|
||
|
await message.reply(f"'{original_word}'を'{converted_word}'として登録しました。")
|
||
|
except ValueError:
|
||
|
await message.reply(f"正しい形式で単語を指定してください。\n例: `{self.bot.prefix}dictionary 単語 読み方`")
|
||
|
|
||
|
async def handle_rname(self, message, args):
|
||
|
"""名前の読み上げ機能のオン・オフを切り替える"""
|
||
|
self.bot.is_name_reading = not self.bot.is_name_reading
|
||
|
await message.reply(f"名前の読み上げを{'有効' if self.bot.is_name_reading else '無効'}にしました。")
|
||
|
|
||
|
async def handle_ichat(self, message, args, log=True):
|
||
|
"""独立チャット機能のオン・オフを切り替える"""
|
||
|
if not self.bot.is_valid_channel(message):
|
||
|
return
|
||
|
|
||
|
bot_admin_user_id = self.bot.config["bot_admin_user_id"]
|
||
|
if not message.author.id == bot_admin_user_id:
|
||
|
await message.reply("権限がありません。")
|
||
|
return
|
||
|
|
||
|
if self.bot.is_independence_chat:
|
||
|
self.bot.disable_independence_chat()
|
||
|
if log:
|
||
|
await message.reply("独立チャットを無効にしました。")
|
||
|
await self.bot.set_bot_status("オシゴトチュウ…")
|
||
|
else:
|
||
|
self.bot.enable_independence_chat(message.guild.voice_client)
|
||
|
await self.bot.set_bot_status("オハナシチュウ…")
|
||
|
if log:
|
||
|
await message.reply("独立チャットを有効にしました。")
|
||
|
|
||
|
async def handle_help(self, message, args):
|
||
|
"""ヘルプメッセージを表示する"""
|
||
|
help_message = (f"**ボットの使い方**\n"
|
||
|
f"> {self.bot.prefix}join: ボイスチャンネルに接続します。\n"
|
||
|
f"> {self.bot.prefix}leave: ボイスチャンネルから切断します。\n"
|
||
|
f"> {self.bot.prefix}volume: 音量を設定します。\n> \t例: `{self.bot.prefix}volume 0.5`\n"
|
||
|
f"> {self.bot.prefix}emotion: 感情を設定します。\n> \t例: `{self.bot.prefix}emotion 100 0 0 0`\n"
|
||
|
f"> {self.bot.prefix}pitch: 音程を設定します。\n> \t例: `{self.bot.prefix}pitch 50`\n"
|
||
|
f"> {self.bot.prefix}dictionary: 単語の辞書登録を行います。\n> \t例: `{self.bot.prefix}dictionary 単語 読み方`\n"
|
||
|
f"> {self.bot.prefix}rname: 名前の読み上げをするかどうかを変更します。\n"
|
||
|
f"> {self.bot.prefix}help: ヘルプを表示します。\n")
|
||
|
await message.reply(help_message)
|
||
|
|
||
|
async def handle_synthesize(self, message):
|
||
|
"""メッセージの音声合成を行う"""
|
||
|
logging.info(f"Synthesizing message: {message.content}")
|
||
|
await self.bot.message_reader.read_message(message, self.bot.word_dictionary, self.bot.config["ffmpeg_executable_path"], self.bot.volume)
|