diff --git a/bot.py b/bot.py index 6f9f251..823afb8 100644 --- a/bot.py +++ b/bot.py @@ -45,7 +45,8 @@ def help(): # 在这里加入功能 from cmdproc import startcmd,rewardscmd,admincmd,weathercmd,infocmd,penaltiescmd,guesscmd,capitals,botadmincmd - from cmdproc import youtubemusic,game24,storymakergame + + from cmdproc import youtubemusic,game24,story commands = startcmd.add_dispatcher(dispatcher) commands = admincmd.add_dispatcher(dispatcher) commands = rewardscmd.add_dispatcher(dispatcher) @@ -57,7 +58,8 @@ def help(): commands += botadmincmd.add_dispatcher(dispatcher) commands += youtubemusic.add_dispatcher(dispatcher) commands += game24.add_handler(dispatcher) - commands += storymakergame.add_handler(dispatcher) + story.add_handler(dispatcher) + commands += story.get_command() updater.bot.set_my_commands(commands) diff --git a/cmdproc/story.py b/cmdproc/story.py new file mode 100644 index 0000000..98ee887 --- /dev/null +++ b/cmdproc/story.py @@ -0,0 +1,179 @@ +from telegram.ext import Dispatcher,CommandHandler,MessageHandler,Filters, CallbackQueryHandler +from telegram import BotCommand,Update,InlineKeyboardButton, InlineKeyboardMarkup +import random +import re +from datetime import datetime + +story = [] + +incomingstory = [] + +def get_last_letter(text): + chinesechars = [] + for char in text: + if '\u4e00' <= char <= '\u9fa5': + chinesechars.append(char) + return chinesechars[-1] + +def chinese(msg): + for char in msg: + if '\u4e00' <= char <= '\u9fa5': + return True + return False + +def get_formatted_story(storylist): + sendmsg = '' + for partlist in storylist: + sendmsg += f'\n{partlist[0]} ✍️ 作者:{partlist[1].first_name}' + return sendmsg + +def get_choices(storylist): + sendmsg = '' + count = 0 + for partlist in storylist: + count += 1 + sendmsg += f"\n\n{count}: {partlist['msg']} ✍️ 作者:{partlist['user'].first_name} 🗳 票数:{len(partlist['votes'])}" + return sendmsg + +def get_buttons(incomingstory): + kblist = [] + count = 0 + choicecount = -1 + for _i in incomingstory: + choicecount += 1 + if choicecount % 5 == 0: + kblist.append([]) + count += 1 + kblist[int(count/6)].append(InlineKeyboardButton(f'{count}',callback_data=f'getstory:{count-1}')) + kb = InlineKeyboardMarkup(kblist) + return kb + +def get_vote_max_nb(incomingstory): + uids = [] + for partlist in incomingstory: + if not partlist['user'].id in uids: + uids.append(partlist['user'].id) + return len(uids) + +def make_story(update,context): + msglist = context.args + user = update.effective_user + msg = '' + text = '' + for partlist in story: + text += partlist[0] + if text == '': + lastletter = '任何中文字' + else: + lastletter = get_last_letter(text) + if len(story) > 0: + sendmsg = get_formatted_story(story) + else: + sendmsg = '\n故事还没开始。' + if len(msglist) == 0: + update.message.reply_text(f'目前的故事:\n{sendmsg}\n\n请用‘{lastletter}’开始下一个句子。请用此格式:/cms [您的句子]\n\n如果想查看故事,请使用 /view_s') + return + for word in msglist: + msg += word + if text != '': + if msg[0] != lastletter: + update.message.reply_text(f'目前的故事:\n{sendmsg}\n\n⚠🤦 您没用正确字开头!请用‘{lastletter}’开始下一个句子!!!请用此格式:/cms [您的句子]\n\n如果想查看故事,请使用 /view_s') + return + if chinese(msg): + incomingstory.append({'msg':msg,'user':user,'votes':[]}) + for partlist in story: + text += partlist[0] + if text != '': + lastletter = get_last_letter(text) + sendmsg = get_formatted_story(story) + else: + sendmsg = '\n故事还没开始。' + sendchoices = get_choices(incomingstory) + kb = get_buttons(incomingstory) + update.message.reply_text(f"目前的故事:\n{sendmsg}\n\n目前的选项:{sendchoices}\n\n请用‘{lastletter}’开始下一个句子。请用此格式:/cms [您的句子]\n\n如果想查看故事,请使用 /view_s",reply_markup=kb) + else: + update.message.reply_text(f'目前的故事:\n{sendmsg}\n\n⚠️ 您没用中文!请用‘{lastletter}’开始下一个句子。请用此格式:/cms [您的句子]\n\n如果想查看故事,请使用 /view_s') + +def story_vote_callback(update,context): + global incomingstory + query = update.callback_query + _,index = query.data.split(':') + index = int(index) + user = update.effective_user + uid = user.id + votes_required = get_vote_max_nb(incomingstory) + text = '' + for partlist in story: + text += partlist[0] + count = 0 + for partlist in incomingstory: + if uid in partlist['votes']: + incomingstory[index]['votes'].append(uid) + incomingstory[count]['votes'].remove(uid) + for partlist in story: + text += partlist[0] + if text != '': + lastletter = get_last_letter(text) + sendmsg = get_formatted_story(story) + else: + sendmsg = '\n故事还没开始。' + lastletter = '任何中文字' + sendchoices = get_choices(incomingstory) + kb = get_buttons(incomingstory) + if len(incomingstory[index]['votes']) >= votes_required: + story.append([incomingstory[index]['msg'],incomingstory[index]['user']]) + text = '' + for partlist in story: + text += partlist[0] + lastletter = get_last_letter(text) + query.edit_message_text(f"{index+1}号句子,‘{incomingstory[index]['msg']}’,被加入故事,因为这是第一个获得{votes_required}票的片段。\n\n请用‘{lastletter}’开始下一个句子。请用此格式:/cms [您的句子]\n\n如果想查看故事,请使用 /view_s") + incomingstory = [] + else: + query.edit_message_text(f"目前的故事:\n{sendmsg}\n\n目前的选项:{sendchoices}\n\n请用‘{lastletter}’开始下一个句子。请用此格式:/cms [您的句子]\n\n如果想查看故事,请使用 /view_s\n\n{user.first_name}已成功的为{index+1}号句子投票。\n\n{user.first_name}给{count+1}号句子投的票已被重置。",reply_markup=kb) + return + count += 1 + incomingstory[index]['votes'].append(uid) + for partlist in story: + text += partlist[0] + if text != '': + lastletter = get_last_letter(text) + sendmsg = get_formatted_story(story) + else: + lastletter = '任何中文字' + sendmsg = '\n故事还没开始。' + sendchoices = get_choices(incomingstory) + kb = get_buttons(incomingstory) + if len(incomingstory[index]['votes']) >= votes_required: + story.append([incomingstory[index]['msg'],incomingstory[index]['user']]) + text = '' + for partlist in story: + text += partlist[0] + lastletter = get_last_letter(text) + query.edit_message_text(f"{index+1}号句子,‘{incomingstory[index]['msg']}’,被加入故事,因为这是第一个获得{votes_required}票的片段。\n\n请用‘{lastletter}’开始下一个句子。请用此格式:/cms [您的句子]\n\n如果想查看故事,请使用 /view_s") + incomingstory = [] + else: + query.edit_message_text(f"目前的故事:\n{sendmsg}\n\n目前的选项:{sendchoices}\n\n请用‘{lastletter}’开始下一个句子。请用此格式:/cms [您的句子]\n\n如果想查看故事,请使用 /view_s\n\n{user.first_name}已成功的为{index+1}号句子投票。",reply_markup=kb) + +def end_story(update,context): + global story + update.message.reply_text(f'故事:\n{get_formatted_story(story)}\n\n故事结束') + story = [] + +def view_story(update,context): + text = '' + for partlist in story: + text += partlist[0] + if text != '': + lastletter = get_last_letter(text) + else: + lastletter = '任何中文字' + update.message.reply_text(f'故事:\n{get_formatted_story(story)}\n\n请用‘{lastletter}’开始下一个句子。请用此格式:/cms [您的句子]\n\n如果想结束故事,请使用 /end_s') + +def get_command(): + return [BotCommand('cms','写故事')] + +def add_handler(dp): + dp.add_handler(CommandHandler('cms',make_story)) + dp.add_handler(CommandHandler('end_s',end_story)) + dp.add_handler(CommandHandler('view_s',view_story)) + dp.add_handler(CallbackQueryHandler(story_vote_callback,pattern="^getstory:[A-Za-z0-9_]*")) \ No newline at end of file diff --git a/cmdproc/storymakergame.py b/cmdproc/storymakergame.py deleted file mode 100644 index eb26b0e..0000000 --- a/cmdproc/storymakergame.py +++ /dev/null @@ -1,162 +0,0 @@ -import random -from telegram.ext import Dispatcher,CommandHandler, MessageHandler, Filters, Updater, CallbackQueryHandler -from telegram import BotCommand, InlineKeyboardMarkup,InlineKeyboardButton -import util - -games = {} - -def rules(): - return r""" 欢迎来到 Noah 的故事接龙游戏! - -您可以开启一个游戏使用命令 /smnew 。 -游戏开始之后,任意一个玩家可以编故事的第一句话。 - -第一句话说完之后,别的玩家可以来接龙使用 /smw [要说的东西]。 - -如果您想接龙,您句子的第一个字必须和上一个人说的句子的最后一个*中文汉字*一样。 -比如: - - 我是 Noah - 是 Noah 呀 - -您接龙的句子里并且还需要包括至少一个中文汉字。 - -别的玩家接龙完了之后,写上一句话的人可以选择他/她最喜欢的接龙使用命令 /smchoose。 - -如果想看目前的故事,可以使用命令 /sminfo。 -如果想查看规则, 可以使用命令 /smrules。 -如果想结束游戏, 可以使用命令 /smend。 - """ - -def detective_system(strs): - last = "" - for _char in strs: - if '\u4e00' <= _char <= '\u9fa5': - last = _char - return last - -def set_up(chatid): - games[chatid] = {} - games[chatid]['story'] = "" - games[chatid]['trans'] = "" - games[chatid]['current'] = "" - games[chatid]['count'] = 1 - games[chatid]['nextanswer'] = [] - games[chatid]['keyboard'] = [{}] - -def new(update,context): - chatid = update.effective_chat.id - set_up(chatid) - update.effective_message.reply_text(f"游戏开始!\n\n{rules()}") - -def start(update,context): - chatid = update.effective_chat.id - first_name = update.effective_user.first_name - uid = str(update.effective_user.id) - reply = "" - if not len(context.args) == 0: - for each in context.args: - reply += each + " " - else: - update.effective_message.reply_text("请按照格式:/smw [要说的东西]") - return - try: - if not detective_system(reply) == "": - if reply[0] == games[chatid]['trans']: - games[chatid]['nextanswer'].append(f"{uid}:{first_name}:{reply}:{games[chatid]['count']}") - games[chatid]['count'] += 1 - update.effective_message.reply_text("接龙成功!") - elif games[chatid]['trans'] == "": - games[chatid]['current'] = uid - games[chatid]['story'] += f"{reply} ➡ ({first_name})\n" - games[chatid]['trans'] = detective_system(reply) - update.effective_message.reply_text(f"{games[chatid]['story']}\n\n下一个人请使用 '{games[chatid]['trans']}' 开头的句子来造句。") - else: - update.effective_message.reply_text(f"{first_name} 请使用 '{games[chatid]['trans']}' 开头的句子来造句!") - else: - update.effective_message.reply_text(f"{first_name}, 请输入一个中文的句子!") - except KeyError: - update.effective_message.reply_text(f"目前没有被开启的游戏。请使用指令 /smnew 来开启一个新的游戏。") - -def vac(update,context): - msg = "" - chatid = update.effective_chat.id - uid = str(update.effective_user.id) - try: - games[chatid]['keyboard'] = [{}] - for every in games[chatid]['nextanswer']: - info = every.split(":") - if not len(games[chatid]['keyboard'][-1]) == 4: - games[chatid]['keyboard'][-1][info[3]] = f"story:{info[3]}:{uid}" - else: - games[chatid]['keyboard'].append({}) - games[chatid]['keyboard'][-1][info[3]] = f"story:{info[3]}:{uid}" - kb = util.getkb(games[chatid]['keyboard']) - info = every.split(":") - msg += f"{info[3]}: {info[2]} ➡ ({info[1]})\n" - update.effective_message.reply_text(msg,reply_markup=kb) - except KeyError: - update.effective_message.reply_text(f"目前没有被开启的游戏。请使用指令 /smnew 来开启一个新的游戏。") - -def info(update,context): - chatid = update.effective_chat.id - try: - if not games[chatid]['trans'] == "": - update.effective_message.reply_text(f"{games[chatid]['story']}\n\n下一个人请使用 '{games[chatid]['trans']}' 开头的句子来造句。") - else: - update.effective_message.reply_text("请说第一句话!") - except KeyError: - update.effective_message.reply_text(f"目前没有被开启的游戏。请使用指令 /makestory 来开启一个新的游戏。") - -def end(update,context): - chatid = update.effective_chat.id - try: - update.effective_message.reply_text(f"游戏结束。这是你们所编的故事:\n\n{games[chatid]['story']}") - del games[chatid] - except KeyError: - update.effective_message.reply_text(f"目前没有被开启的游戏。请使用指令 /makestory 来开启一个新的游戏。") - -def callback(update,context): - choice = 0 - chatid = update.effective_chat.id - query = update.callback_query - cmd = query.data.split(":") - if games[chatid]['current'] == str(update.effective_user.id): - query.answer("成功!") - for line in games[chatid]['keyboard']: - for button in line: - if cmd[1] == button: - choice = button - for every in games[chatid]['nextanswer']: - info = every.split(":") - if info[3] == choice: - update.effective_message.reply_text(f"👌 {info[1]} 会是接龙的人,他/她可以做下一个选择。(认为最棒的答案)") - games[chatid]['current'] = info[0] - games[chatid]['story'] += f"{info[2]} ➡ ({info[1]})\n" - games[chatid]['trans'] = detective_system(info[2]) - games[chatid]['nextanswer'] = [] - games[chatid]['count'] = 1 - games[chatid]['keyboard'] = [{}] - update.effective_message.reply_text(f"{games[chatid]['story']}\n\n下一个人请使用 '{games[chatid]['trans']}' 开头的句子来造句。") - else: - query.answer("您不是选择的人!") - -def gamerules(update,context): - update.effective_message.reply_text(rules()) - -def add_handler(dp:Dispatcher): - dp.add_handler(CommandHandler('smw', start)) - dp.add_handler(CommandHandler('smend', end)) - dp.add_handler(CommandHandler('sminfo', info)) - dp.add_handler(CommandHandler('smchoose', vac)) - dp.add_handler(CommandHandler('smnew', new)) - dp.add_handler(CommandHandler('smrules', gamerules)) - dp.add_handler(CallbackQueryHandler(callback,pattern="^story:[A-Za-z0-9_:]*")) - return [ - BotCommand('smnew','开始一个故事接龙的游戏'), - BotCommand('sminfo','查询一个故事接龙的游戏的信息'), - BotCommand('smchoose','选择下一个接龙的人'), - BotCommand('smw','继续接龙'), - BotCommand('smend','结束一个故事接龙的游戏'), - BotCommand('smrules','查询一个故事接龙的游戏的规则') - ] \ No newline at end of file