From e3140f06fd7099f4677e167131ee6dec4364186c Mon Sep 17 00:00:00 2001 From: syuilo Date: Sat, 12 Sep 2020 19:46:33 +0900 Subject: [PATCH] nannka --- README.md | 1 + package.json | 2 +- src/config.ts | 1 + src/index.ts | 2 + src/modules/poll/index.ts | 106 ++++++++++++++++++++++++++++++++++++++ src/serifs.ts | 2 + src/vocabulary.ts | 26 ++++++++++ 7 files changed, 139 insertions(+), 1 deletion(-) create mode 100644 src/modules/poll/index.ts diff --git a/README.md b/README.md index ff7fc61..c18cd3c 100644 --- a/README.md +++ b/README.md @@ -13,6 +13,7 @@ Misskey用の日本語Botです。 { "host": "https:// + あなたのインスタンスのURL (末尾の / は除く)", "i": "藍として動かしたいアカウントのアクセストークン", + "master": "管理者のユーザー名(オプション)", "keywordEnabled": "キーワードを覚える機能 (MeCab が必要) を有効にする場合は true を入れる (無効にする場合は false)", "chartEnabled": "チャート機能を無効化する場合は false を入れてください", "reversiEnabled": "藍とリバーシで対局できる機能を有効にする場合は true を入れる (無効にする場合は false)", diff --git a/package.json b/package.json index 52f5be6..d5abcbc 100644 --- a/package.json +++ b/package.json @@ -1,5 +1,5 @@ { - "_v": "1.1.2", + "_v": "1.2.0", "main": "./built/index.js", "scripts": { "start": "node ./built", diff --git a/src/config.ts b/src/config.ts index 96d857f..8ea1dc8 100644 --- a/src/config.ts +++ b/src/config.ts @@ -1,6 +1,7 @@ type Config = { host: string; i: string; + master?: string; wsUrl: string; apiUrl: string; keywordEnabled: boolean; diff --git a/src/index.ts b/src/index.ts index 18a76e1..e2735cd 100644 --- a/src/index.ts +++ b/src/index.ts @@ -30,6 +30,7 @@ import MazeModule from './modules/maze'; import ChartModule from './modules/chart'; import SleepReportModule from './modules/sleep-report'; import NotingModule from './modules/noting'; +import PollModule from './modules/poll'; console.log(' __ ____ _____ ___ '); console.log(' /__\\ (_ _)( _ )/ __)'); @@ -82,6 +83,7 @@ promiseRetry(retry => { new ChartModule(), new SleepReportModule(), new NotingModule(), + new PollModule(), ]); }).catch(e => { log(chalk.red('Failed to fetch the account')); diff --git a/src/modules/poll/index.ts b/src/modules/poll/index.ts new file mode 100644 index 0000000..1ea7a9d --- /dev/null +++ b/src/modules/poll/index.ts @@ -0,0 +1,106 @@ +import autobind from 'autobind-decorator'; +import Message from '../../message'; +import Module from '../../module'; +import serifs from '../../serifs'; +import { genItem } from '../../vocabulary'; +import config from '../../config'; + +export default class extends Module { + public readonly name = 'poll'; + + @autobind + public install() { + setInterval(() => { + if (Math.random() < 0.1) { + this.post(); + } + }, 1000 * 60 * 60); + + return { + mentionHook: this.mentionHook, + timeoutCallback: this.timeoutCallback, + }; + } + + @autobind + private async post() { + const duration = 1000 * 60 * 30; + + const polls = [ // TODO: Extract serif + ['いちばん珍しそうなもの', 'みなさんは、どれがいちばん珍しいと思いますか? ヽ(・∀・)'], + ['いちばん美味しそうなもの', 'みなさんは、どれがいちばん美味しいと思いますか? ヽ(・∀・)'], + ['いちばん重そうなもの', 'みなさんは、どれがいちばん重いと思いますか? ヽ(・∀・)'], + ['いちばん欲しいもの', 'みなさんは、どれがいちばん欲しいですか? ヽ(・∀・)'], + ['無人島に持っていきたいもの', 'みなさんは、無人島にひとつ持っていけるとしたらどれにしますか? ヽ(・∀・)'], + ]; + + const poll = polls[Math.floor(Math.random() * polls.length)]; + + const note = await this.ai.post({ + text: poll[1], + poll: { + choices: [ + genItem(), + genItem(), + genItem(), + genItem(), + ], + expiredAfter: duration, + multiple: false, + } + }); + + // タイマーセット + this.setTimeoutWithPersistence(duration + 3000, { + title: poll[0], + noteId: note.id, + }); + } + + @autobind + private async mentionHook(msg: Message) { + if (!msg.or(['/poll']) || msg.user.username !== config.master) { + return false; + } else { + this.log('Manualy poll requested'); + } + + this.post(); + + return true; + } + + @autobind + private async timeoutCallback({ title, noteId }) { + const note = await this.ai.api('notes/show', { noteId }); + + const choices = note.poll.choices; + + let mostVotedChoice; + + for (const choice of choices) { + if (mostVotedChoice == null) { + mostVotedChoice = choice; + continue; + } + + // TODO: 同数一位のハンドリング + if (choice.votes > mostVotedChoice.votes) { + mostVotedChoice = choice; + } + } + + if (mostVotedChoice.votes === 0) { + this.ai.post({ // TODO: Extract serif + text: '投票はありませんでした', + renoteId: noteId, + }); + } else { + this.ai.post({ // TODO: Extract serif + cw: `${title}アンケートの結果発表です!`, + text: `結果は「${mostVotedChoice.text}」でした!`, + renoteId: noteId, + }); + } + } +} diff --git a/src/serifs.ts b/src/serifs.ts index dff0f1b..6832970 100644 --- a/src/serifs.ts +++ b/src/serifs.ts @@ -425,6 +425,8 @@ export default { 'ふみゃ〜', 'ふぁ… ねむねむですー', 'ヾ(๑╹◡╹)ノ"', + '私の"インスタンス"を周囲に展開して分身するのが特技です!\n人数分のエネルギー消費があるので、4人くらいが限界ですけど', + 'うとうと...', ], want: item => `${item}、欲しいなぁ...`, see: item => `お散歩していたら、道に${item}が落ちているのを見たんです!`, diff --git a/src/vocabulary.ts b/src/vocabulary.ts index 149707e..a4aa746 100644 --- a/src/vocabulary.ts +++ b/src/vocabulary.ts @@ -82,6 +82,14 @@ export const itemPrefixes = [ 'ホログラフィックな', '油圧式', '辛そうで辛くない少し辛い', + '焦げた', + '宇宙', + '電子', + '陽電子', + '量子力学的', + 'シュレディンガーの', + '分散型', + '卵かけ', ]; export const items = [ @@ -207,6 +215,24 @@ export const items = [ '宇宙', '素粒子', 'ごま油', + '卵かけご飯', + 'ダークマター', + 'ブラックホール', + '太陽', + '石英ガラス', + 'ダム', + 'ウイルス', + '細菌', + 'アーチ式コンクリートダム', + '重力式コンクリートダム', + 'フラッシュバルブ', + 'ヴィブラスラップ', + 'オブジェ', + '原子力発電所', + '原子炉', + 'エラトステネスの篩', + 'ブラウン管', + 'タキオン', ]; export const and = [