mirror of
https://github.com/syuilo/ai.git
synced 2025-03-25 21:12:56 +00:00
Add ESLint
This commit is contained in:
parent
98f22f2b9d
commit
71c73de59e
57 changed files with 6442 additions and 739 deletions
29
.eslintrc.js
Normal file
29
.eslintrc.js
Normal file
|
@ -0,0 +1,29 @@
|
||||||
|
module.exports = {
|
||||||
|
'env': {
|
||||||
|
'es2021': true,
|
||||||
|
'node': true,
|
||||||
|
},
|
||||||
|
'extends': [
|
||||||
|
'google',
|
||||||
|
],
|
||||||
|
'parser': '@typescript-eslint/parser',
|
||||||
|
'parserOptions': {
|
||||||
|
'ecmaVersion': 'latest',
|
||||||
|
'sourceType': 'module',
|
||||||
|
},
|
||||||
|
'plugins': [
|
||||||
|
'@typescript-eslint',
|
||||||
|
],
|
||||||
|
'rules': {
|
||||||
|
'no-tabs': 'off',
|
||||||
|
'max-len': ['error', {'code': 120}],
|
||||||
|
'indent': ['error', 'tab'],
|
||||||
|
'@typescript-eslint/no-unused-vars': ['warn', {'argsIgnorePattern': '^_'}],
|
||||||
|
'no-unused-vars': 'off',
|
||||||
|
'require-jsdoc': 'off',
|
||||||
|
'valid-jsdoc': 'off',
|
||||||
|
'max-len': 'off',
|
||||||
|
'no-mixed-spaces-and-tabs': 'off',
|
||||||
|
'new-cap': 'off',
|
||||||
|
},
|
||||||
|
};
|
19
.github/workflows/ci.yml
vendored
Normal file
19
.github/workflows/ci.yml
vendored
Normal file
|
@ -0,0 +1,19 @@
|
||||||
|
name: CI
|
||||||
|
on:
|
||||||
|
push:
|
||||||
|
branches-ignore:
|
||||||
|
- main
|
||||||
|
jobs:
|
||||||
|
ESLint:
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
steps:
|
||||||
|
- name: Checkout
|
||||||
|
uses: actions/checkout@v3
|
||||||
|
- name: Set Node.js 18.x
|
||||||
|
uses: actions/setup-node@v3
|
||||||
|
with:
|
||||||
|
node-version: 18.x
|
||||||
|
- name: ci
|
||||||
|
run: yarn install --immutable --immutable-cache --check-cache
|
||||||
|
- name: ESLint
|
||||||
|
run: yarn lint
|
|
@ -4,7 +4,9 @@
|
||||||
"scripts": {
|
"scripts": {
|
||||||
"start": "node ./built",
|
"start": "node ./built",
|
||||||
"build": "tsc",
|
"build": "tsc",
|
||||||
"test": "jest"
|
"test": "jest",
|
||||||
|
"lint": "yarn eslint --ext .js,.ts .",
|
||||||
|
"lint:fix": "yarn eslint --ext .js,.ts . --fix"
|
||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@types/chalk": "2.2.0",
|
"@types/chalk": "2.2.0",
|
||||||
|
@ -47,6 +49,10 @@
|
||||||
"@types/koa__router": "8.0.11",
|
"@types/koa__router": "8.0.11",
|
||||||
"@types/node-fetch": "3.0.3",
|
"@types/node-fetch": "3.0.3",
|
||||||
"@types/websocket": "1.0.5",
|
"@types/websocket": "1.0.5",
|
||||||
|
"@typescript-eslint/eslint-plugin": "5.33.0",
|
||||||
|
"@typescript-eslint/parser": "5.33.0",
|
||||||
|
"eslint": ">=5.16.0",
|
||||||
|
"eslint-config-google": "0.14.0",
|
||||||
"jest": "26.6.3",
|
"jest": "26.6.3",
|
||||||
"koa": "2.13.4",
|
"koa": "2.13.4",
|
||||||
"koa-json-body": "5.3.0",
|
"koa-json-body": "5.3.0",
|
||||||
|
|
52
src/ai.ts
52
src/ai.ts
|
@ -114,14 +114,14 @@ export default class 藍 {
|
||||||
autoload: true,
|
autoload: true,
|
||||||
autosave: true,
|
autosave: true,
|
||||||
autosaveInterval: 1000,
|
autosaveInterval: 1000,
|
||||||
autoloadCallback: err => {
|
autoloadCallback: (err) => {
|
||||||
if (err) {
|
if (err) {
|
||||||
this.log(chalk.red(`Failed to load the memory: ${err}`));
|
this.log(chalk.red(`Failed to load the memory: ${err}`));
|
||||||
} else {
|
} else {
|
||||||
this.log(chalk.green('The memory loaded successfully'));
|
this.log(chalk.green('The memory loaded successfully'));
|
||||||
this.run();
|
this.run();
|
||||||
}
|
}
|
||||||
}
|
},
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -136,19 +136,19 @@ export default class 藍 {
|
||||||
this.meta = this.getCollection('meta', {});
|
this.meta = this.getCollection('meta', {});
|
||||||
|
|
||||||
this.contexts = this.getCollection('contexts', {
|
this.contexts = this.getCollection('contexts', {
|
||||||
indices: ['key']
|
indices: ['key'],
|
||||||
});
|
});
|
||||||
|
|
||||||
this.timers = this.getCollection('timers', {
|
this.timers = this.getCollection('timers', {
|
||||||
indices: ['module']
|
indices: ['module'],
|
||||||
});
|
});
|
||||||
|
|
||||||
this.friends = this.getCollection('friends', {
|
this.friends = this.getCollection('friends', {
|
||||||
indices: ['userId']
|
indices: ['userId'],
|
||||||
});
|
});
|
||||||
|
|
||||||
this.moduleData = this.getCollection('moduleData', {
|
this.moduleData = this.getCollection('moduleData', {
|
||||||
indices: ['module']
|
indices: ['module'],
|
||||||
});
|
});
|
||||||
// #endregion
|
// #endregion
|
||||||
|
|
||||||
|
@ -162,7 +162,7 @@ export default class 藍 {
|
||||||
const mainStream = this.connection.useSharedConnection('main');
|
const mainStream = this.connection.useSharedConnection('main');
|
||||||
|
|
||||||
// メンションされたとき
|
// メンションされたとき
|
||||||
mainStream.on('mention', async data => {
|
mainStream.on('mention', async (data) => {
|
||||||
if (data.userId == this.account.id) return; // 自分は弾く
|
if (data.userId == this.account.id) return; // 自分は弾く
|
||||||
if (data.text && data.text.startsWith('@' + this.account.username)) {
|
if (data.text && data.text.startsWith('@' + this.account.username)) {
|
||||||
// Misskeyのバグで投稿が非公開扱いになる
|
// Misskeyのバグで投稿が非公開扱いになる
|
||||||
|
@ -172,7 +172,7 @@ export default class 藍 {
|
||||||
});
|
});
|
||||||
|
|
||||||
// 返信されたとき
|
// 返信されたとき
|
||||||
mainStream.on('reply', async data => {
|
mainStream.on('reply', async (data) => {
|
||||||
if (data.userId == this.account.id) return; // 自分は弾く
|
if (data.userId == this.account.id) return; // 自分は弾く
|
||||||
if (data.text && data.text.startsWith('@' + this.account.username)) return;
|
if (data.text && data.text.startsWith('@' + this.account.username)) return;
|
||||||
// Misskeyのバグで投稿が非公開扱いになる
|
// Misskeyのバグで投稿が非公開扱いになる
|
||||||
|
@ -181,31 +181,31 @@ export default class 藍 {
|
||||||
});
|
});
|
||||||
|
|
||||||
// Renoteされたとき
|
// Renoteされたとき
|
||||||
mainStream.on('renote', async data => {
|
mainStream.on('renote', async (data) => {
|
||||||
if (data.userId == this.account.id) return; // 自分は弾く
|
if (data.userId == this.account.id) return; // 自分は弾く
|
||||||
if (data.text == null && (data.files || []).length == 0) return;
|
if (data.text == null && (data.files || []).length == 0) return;
|
||||||
|
|
||||||
// リアクションする
|
// リアクションする
|
||||||
this.api('notes/reactions/create', {
|
this.api('notes/reactions/create', {
|
||||||
noteId: data.id,
|
noteId: data.id,
|
||||||
reaction: 'love'
|
reaction: 'love',
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
// メッセージ
|
// メッセージ
|
||||||
mainStream.on('messagingMessage', data => {
|
mainStream.on('messagingMessage', (data) => {
|
||||||
if (data.userId == this.account.id) return; // 自分は弾く
|
if (data.userId == this.account.id) return; // 自分は弾く
|
||||||
this.onReceiveMessage(new Message(this, data, true));
|
this.onReceiveMessage(new Message(this, data, true));
|
||||||
});
|
});
|
||||||
|
|
||||||
// 通知
|
// 通知
|
||||||
mainStream.on('notification', data => {
|
mainStream.on('notification', (data) => {
|
||||||
this.onNotification(data);
|
this.onNotification(data);
|
||||||
});
|
});
|
||||||
// #endregion
|
// #endregion
|
||||||
|
|
||||||
// Install modules
|
// Install modules
|
||||||
this.modules.forEach(m => {
|
this.modules.forEach((m) => {
|
||||||
this.log(`Installing ${chalk.cyan.italic(m.name)}\tmodule...`);
|
this.log(`Installing ${chalk.cyan.italic(m.name)}\tmodule...`);
|
||||||
m.init(this);
|
m.init(this);
|
||||||
const res = m.install();
|
const res = m.install();
|
||||||
|
@ -244,10 +244,10 @@ export default class 藍 {
|
||||||
// Look up the context
|
// Look up the context
|
||||||
const context = isNoContext ? null : this.contexts.findOne(msg.isDm ? {
|
const context = isNoContext ? null : this.contexts.findOne(msg.isDm ? {
|
||||||
isDm: true,
|
isDm: true,
|
||||||
userId: msg.userId
|
userId: msg.userId,
|
||||||
} : {
|
} : {
|
||||||
isDm: false,
|
isDm: false,
|
||||||
noteId: msg.replyId
|
noteId: msg.replyId,
|
||||||
});
|
});
|
||||||
|
|
||||||
let reaction: string | null = 'love';
|
let reaction: string | null = 'love';
|
||||||
|
@ -301,7 +301,7 @@ export default class 藍 {
|
||||||
if (reaction) {
|
if (reaction) {
|
||||||
this.api('notes/reactions/create', {
|
this.api('notes/reactions/create', {
|
||||||
noteId: msg.id,
|
noteId: msg.id,
|
||||||
reaction: reaction
|
reaction: reaction,
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -362,7 +362,7 @@ export default class 藍 {
|
||||||
@autobind
|
@autobind
|
||||||
public lookupFriend(userId: User['id']): Friend | null {
|
public lookupFriend(userId: User['id']): Friend | null {
|
||||||
const doc = this.friends.findOne({
|
const doc = this.friends.findOne({
|
||||||
userId: userId
|
userId: userId,
|
||||||
});
|
});
|
||||||
|
|
||||||
if (doc == null) return null;
|
if (doc == null) return null;
|
||||||
|
@ -383,10 +383,10 @@ export default class 藍 {
|
||||||
i: config.i,
|
i: config.i,
|
||||||
file: {
|
file: {
|
||||||
value: file,
|
value: file,
|
||||||
options: meta
|
options: meta,
|
||||||
}
|
|
||||||
},
|
},
|
||||||
json: true
|
},
|
||||||
|
json: true,
|
||||||
});
|
});
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
@ -417,8 +417,8 @@ export default class 藍 {
|
||||||
public api(endpoint: string, param?: any) {
|
public api(endpoint: string, param?: any) {
|
||||||
return request.post(`${config.apiUrl}/${endpoint}`, {
|
return request.post(`${config.apiUrl}/${endpoint}`, {
|
||||||
json: Object.assign({
|
json: Object.assign({
|
||||||
i: config.i
|
i: config.i,
|
||||||
}, param)
|
}, param),
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -437,13 +437,13 @@ export default class 藍 {
|
||||||
userId: id,
|
userId: id,
|
||||||
module: module.name,
|
module: module.name,
|
||||||
key: key,
|
key: key,
|
||||||
data: data
|
data: data,
|
||||||
} : {
|
} : {
|
||||||
isDm: false,
|
isDm: false,
|
||||||
noteId: id,
|
noteId: id,
|
||||||
module: module.name,
|
module: module.name,
|
||||||
key: key,
|
key: key,
|
||||||
data: data
|
data: data,
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -456,7 +456,7 @@ export default class 藍 {
|
||||||
public unsubscribeReply(module: Module, key: string | null) {
|
public unsubscribeReply(module: Module, key: string | null) {
|
||||||
this.contexts.findAndRemove({
|
this.contexts.findAndRemove({
|
||||||
key: key,
|
key: key,
|
||||||
module: module.name
|
module: module.name,
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -475,7 +475,7 @@ export default class 藍 {
|
||||||
module: module.name,
|
module: module.name,
|
||||||
insertedAt: Date.now(),
|
insertedAt: Date.now(),
|
||||||
delay: delay,
|
delay: delay,
|
||||||
data: data
|
data: data,
|
||||||
});
|
});
|
||||||
|
|
||||||
this.log(`Timer persisted: ${module.name} ${id} ${delay}ms`);
|
this.log(`Timer persisted: ${module.name} ${id} ${delay}ms`);
|
||||||
|
|
|
@ -43,13 +43,13 @@ export default class Friend {
|
||||||
|
|
||||||
if (opts.user) {
|
if (opts.user) {
|
||||||
const exist = this.ai.friends.findOne({
|
const exist = this.ai.friends.findOne({
|
||||||
userId: opts.user.id
|
userId: opts.user.id,
|
||||||
});
|
});
|
||||||
|
|
||||||
if (exist == null) {
|
if (exist == null) {
|
||||||
const inserted = this.ai.friends.insertOne({
|
const inserted = this.ai.friends.insertOne({
|
||||||
userId: opts.user.id,
|
userId: opts.user.id,
|
||||||
user: opts.user
|
user: opts.user,
|
||||||
});
|
});
|
||||||
|
|
||||||
if (inserted == null) {
|
if (inserted == null) {
|
||||||
|
@ -172,7 +172,7 @@ export default class Friend {
|
||||||
@autobind
|
@autobind
|
||||||
public transferMemory(code: string): boolean {
|
public transferMemory(code: string): boolean {
|
||||||
const src = this.ai.friends.findOne({
|
const src = this.ai.friends.findOne({
|
||||||
transferCode: code
|
transferCode: code,
|
||||||
});
|
});
|
||||||
|
|
||||||
if (src == null) return false;
|
if (src == null) return false;
|
||||||
|
|
24
src/index.ts
24
src/index.ts
|
@ -15,7 +15,7 @@ import CoreModule from './modules/core';
|
||||||
import TalkModule from './modules/talk';
|
import TalkModule from './modules/talk';
|
||||||
import BirthdayModule from './modules/birthday';
|
import BirthdayModule from './modules/birthday';
|
||||||
import ReversiModule from './modules/reversi';
|
import ReversiModule from './modules/reversi';
|
||||||
import summonCat from './modules/summonCat';
|
import SummonCat from './modules/summonCat';
|
||||||
import PingModule from './modules/ping';
|
import PingModule from './modules/ping';
|
||||||
import EmojiModule from './modules/emoji';
|
import EmojiModule from './modules/emoji';
|
||||||
import EmojiReactModule from './modules/emoji-react';
|
import EmojiReactModule from './modules/emoji-react';
|
||||||
|
@ -35,9 +35,9 @@ import SleepReportModule from './modules/sleep-report';
|
||||||
import NotingModule from './modules/noting';
|
import NotingModule from './modules/noting';
|
||||||
// import PollModule from './modules/poll';
|
// import PollModule from './modules/poll';
|
||||||
import ReminderModule from './modules/reminder';
|
import ReminderModule from './modules/reminder';
|
||||||
import earthquake from './modules/earthquake';
|
import Earthquake from './modules/earthquake';
|
||||||
import DicModule from './modules/dic';
|
import DicModule from './modules/dic';
|
||||||
import menuModule from './modules/menu';
|
import MenuModule from './modules/menu';
|
||||||
import GetColorModule from './modules/color';
|
import GetColorModule from './modules/color';
|
||||||
|
|
||||||
console.log(' __ ____ _____ ___ ');
|
console.log(' __ ____ _____ ___ ');
|
||||||
|
@ -51,18 +51,18 @@ function log(msg: string): void {
|
||||||
|
|
||||||
log(chalk.bold(`Ai v${pkg._v}`));
|
log(chalk.bold(`Ai v${pkg._v}`));
|
||||||
|
|
||||||
promiseRetry(retry => {
|
promiseRetry((retry) => {
|
||||||
log(`Account fetching... ${chalk.gray(config.host)}`);
|
log(`Account fetching... ${chalk.gray(config.host)}`);
|
||||||
|
|
||||||
// アカウントをフェッチ
|
// アカウントをフェッチ
|
||||||
return request.post(`${config.apiUrl}/i`, {
|
return request.post(`${config.apiUrl}/i`, {
|
||||||
json: {
|
json: {
|
||||||
i: config.i
|
i: config.i,
|
||||||
}
|
},
|
||||||
}).catch(retry);
|
}).catch(retry);
|
||||||
}, {
|
}, {
|
||||||
retries: 3
|
retries: 3,
|
||||||
}).then(account => {
|
}).then((account) => {
|
||||||
const acct = `@${account.username}`;
|
const acct = `@${account.username}`;
|
||||||
log(chalk.green(`Account fetched successfully: ${chalk.underline(acct)}`));
|
log(chalk.green(`Account fetched successfully: ${chalk.underline(acct)}`));
|
||||||
|
|
||||||
|
@ -72,7 +72,7 @@ promiseRetry(retry => {
|
||||||
new 藍(account, [
|
new 藍(account, [
|
||||||
new CoreModule(),
|
new CoreModule(),
|
||||||
new ReminderModule(),
|
new ReminderModule(),
|
||||||
new summonCat(),
|
new SummonCat(),
|
||||||
new EmojiModule(),
|
new EmojiModule(),
|
||||||
new EmojiReactModule(),
|
new EmojiReactModule(),
|
||||||
new FortuneModule(),
|
new FortuneModule(),
|
||||||
|
@ -95,10 +95,10 @@ promiseRetry(retry => {
|
||||||
new NotingModule(),
|
new NotingModule(),
|
||||||
// new PollModule(),
|
// new PollModule(),
|
||||||
new DicModule(),
|
new DicModule(),
|
||||||
new menuModule(),
|
new MenuModule(),
|
||||||
new GetColorModule(),
|
new GetColorModule(),
|
||||||
new earthquake(),
|
new Earthquake(),
|
||||||
]);
|
]);
|
||||||
}).catch(e => {
|
}).catch((e) => {
|
||||||
log(chalk.red('Failed to fetch the account'));
|
log(chalk.red('Failed to fetch the account'));
|
||||||
});
|
});
|
||||||
|
|
|
@ -64,8 +64,8 @@ export default class Message {
|
||||||
|
|
||||||
// メッセージなどに付いているユーザー情報は省略されている場合があるので完全なユーザー情報を持ってくる
|
// メッセージなどに付いているユーザー情報は省略されている場合があるので完全なユーザー情報を持ってくる
|
||||||
this.ai.api('users/show', {
|
this.ai.api('users/show', {
|
||||||
userId: this.userId
|
userId: this.userId,
|
||||||
}).then(user => {
|
}).then((user) => {
|
||||||
this.friend.updateUser(user);
|
this.friend.updateUser(user);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
@ -88,7 +88,7 @@ export default class Message {
|
||||||
if (this.isDm) {
|
if (this.isDm) {
|
||||||
return await this.ai.sendMessage(this.messageOrNote.userId, {
|
return await this.ai.sendMessage(this.messageOrNote.userId, {
|
||||||
text: text,
|
text: text,
|
||||||
fileId: opts?.file?.id
|
fileId: opts?.file?.id,
|
||||||
});
|
});
|
||||||
} else {
|
} else {
|
||||||
return await this.ai.post({
|
return await this.ai.post({
|
||||||
|
@ -96,7 +96,7 @@ export default class Message {
|
||||||
text: text,
|
text: text,
|
||||||
fileIds: opts?.file ? [opts?.file.id] : undefined,
|
fileIds: opts?.file ? [opts?.file.id] : undefined,
|
||||||
cw: opts?.cw,
|
cw: opts?.cw,
|
||||||
renoteId: opts?.renote
|
renoteId: opts?.renote,
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -7,7 +7,7 @@ export type Note = {
|
||||||
},
|
},
|
||||||
text: string | null;
|
text: string | null;
|
||||||
cw: string | null;
|
cw: string | null;
|
||||||
visibility: "public" | "home" | "followers" | "specified";
|
visibility: 'public' | 'home' | 'followers' | 'specified';
|
||||||
reply: any | null;
|
reply: any | null;
|
||||||
poll?: {
|
poll?: {
|
||||||
choices: {
|
choices: {
|
||||||
|
|
|
@ -11,13 +11,13 @@ export default abstract class Module {
|
||||||
this.ai = ai;
|
this.ai = ai;
|
||||||
|
|
||||||
this.doc = this.ai.moduleData.findOne({
|
this.doc = this.ai.moduleData.findOne({
|
||||||
module: this.name
|
module: this.name,
|
||||||
});
|
});
|
||||||
|
|
||||||
if (this.doc == null) {
|
if (this.doc == null) {
|
||||||
this.doc = this.ai.moduleData.insertOne({
|
this.doc = this.ai.moduleData.insertOne({
|
||||||
module: this.name,
|
module: this.name,
|
||||||
data: {}
|
data: {},
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -30,10 +30,10 @@ export default class extends Module {
|
||||||
const today = `${zeroPadding(m + 1, 2)}-${zeroPadding(d, 2)}`;
|
const today = `${zeroPadding(m + 1, 2)}-${zeroPadding(d, 2)}`;
|
||||||
|
|
||||||
const birthFriends = this.ai.friends.find({
|
const birthFriends = this.ai.friends.find({
|
||||||
'user.birthday': { '$regex': new RegExp('-' + today + '$') }
|
'user.birthday': {'$regex': new RegExp('-' + today + '$')},
|
||||||
} as any);
|
} as any);
|
||||||
|
|
||||||
birthFriends.forEach(f => {
|
birthFriends.forEach((f) => {
|
||||||
const friend = new Friend(this.ai, {doc: f});
|
const friend = new Friend(this.ai, {doc: f});
|
||||||
|
|
||||||
// 親愛度が3以上必要
|
// 親愛度が3以上必要
|
||||||
|
@ -49,7 +49,7 @@ export default class extends Module {
|
||||||
const text = serifs.birthday.happyBirthday(friend.name);
|
const text = serifs.birthday.happyBirthday(friend.name);
|
||||||
|
|
||||||
this.ai.sendMessage(friend.userId, {
|
this.ai.sendMessage(friend.userId, {
|
||||||
text: text
|
text: text,
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
|
@ -18,7 +18,7 @@ export default class extends Module {
|
||||||
setInterval(this.post, 1000 * 60 * 3);
|
setInterval(this.post, 1000 * 60 * 3);
|
||||||
|
|
||||||
return {
|
return {
|
||||||
mentionHook: this.mentionHook
|
mentionHook: this.mentionHook,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -38,7 +38,7 @@ export default class extends Module {
|
||||||
this.log('Posting...');
|
this.log('Posting...');
|
||||||
this.ai.post({
|
this.ai.post({
|
||||||
text: serifs.chart.post,
|
text: serifs.chart.post,
|
||||||
fileIds: [file.id]
|
fileIds: [file.id],
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -52,33 +52,33 @@ export default class extends Module {
|
||||||
const data = await this.ai.api('charts/user/notes', {
|
const data = await this.ai.api('charts/user/notes', {
|
||||||
span: 'day',
|
span: 'day',
|
||||||
limit: 30,
|
limit: 30,
|
||||||
userId: params.user.id
|
userId: params.user.id,
|
||||||
});
|
});
|
||||||
|
|
||||||
chart = {
|
chart = {
|
||||||
title: `@${params.user.username}さんの投稿数`,
|
title: `@${params.user.username}さんの投稿数`,
|
||||||
datasets: [{
|
datasets: [{
|
||||||
data: data.diffs.normal
|
data: data.diffs.normal,
|
||||||
}, {
|
}, {
|
||||||
data: data.diffs.reply
|
data: data.diffs.reply,
|
||||||
}, {
|
}, {
|
||||||
data: data.diffs.renote
|
data: data.diffs.renote,
|
||||||
}]
|
}],
|
||||||
};
|
};
|
||||||
} else if (type === 'followers') {
|
} else if (type === 'followers') {
|
||||||
const data = await this.ai.api('charts/user/following', {
|
const data = await this.ai.api('charts/user/following', {
|
||||||
span: 'day',
|
span: 'day',
|
||||||
limit: 30,
|
limit: 30,
|
||||||
userId: params.user.id
|
userId: params.user.id,
|
||||||
});
|
});
|
||||||
|
|
||||||
chart = {
|
chart = {
|
||||||
title: `@${params.user.username}さんのフォロワー数`,
|
title: `@${params.user.username}さんのフォロワー数`,
|
||||||
datasets: [{
|
datasets: [{
|
||||||
data: data.local.followers.total
|
data: data.local.followers.total,
|
||||||
}, {
|
}, {
|
||||||
data: data.remote.followers.total
|
data: data.remote.followers.total,
|
||||||
}]
|
}],
|
||||||
};
|
};
|
||||||
} else if (type === 'notes') {
|
} else if (type === 'notes') {
|
||||||
const data = await this.ai.api('charts/notes', {
|
const data = await this.ai.api('charts/notes', {
|
||||||
|
@ -88,12 +88,12 @@ export default class extends Module {
|
||||||
|
|
||||||
chart = {
|
chart = {
|
||||||
datasets: [{
|
datasets: [{
|
||||||
data: data.local.diffs.normal
|
data: data.local.diffs.normal,
|
||||||
}, {
|
}, {
|
||||||
data: data.local.diffs.reply
|
data: data.local.diffs.reply,
|
||||||
}, {
|
}, {
|
||||||
data: data.local.diffs.renote
|
data: data.local.diffs.renote,
|
||||||
}]
|
}],
|
||||||
};
|
};
|
||||||
} else {
|
} else {
|
||||||
const suffixes = ['の売り上げ', 'の消費', 'の生産'];
|
const suffixes = ['の売り上げ', 'の消費', 'の生産'];
|
||||||
|
@ -102,10 +102,10 @@ export default class extends Module {
|
||||||
const diffRange = 150;
|
const diffRange = 150;
|
||||||
const datasetCount = 1 + Math.floor(Math.random() * 3);
|
const datasetCount = 1 + Math.floor(Math.random() * 3);
|
||||||
|
|
||||||
let datasets: any[] = [];
|
const datasets: any[] = [];
|
||||||
|
|
||||||
for (let d = 0; d < datasetCount; d++) {
|
for (let d = 0; d < datasetCount; d++) {
|
||||||
let values = [Math.random() * 1000];
|
const values = [Math.random() * 1000];
|
||||||
|
|
||||||
for (let i = 1; i < limit; i++) {
|
for (let i = 1; i < limit; i++) {
|
||||||
const prev = values[i - 1];
|
const prev = values[i - 1];
|
||||||
|
@ -113,13 +113,13 @@ export default class extends Module {
|
||||||
}
|
}
|
||||||
|
|
||||||
datasets.push({
|
datasets.push({
|
||||||
data: values
|
data: values,
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
chart = {
|
chart = {
|
||||||
title: items[Math.floor(Math.random() * items.length)] + suffixes[Math.floor(Math.random() * suffixes.length)],
|
title: items[Math.floor(Math.random() * items.length)] + suffixes[Math.floor(Math.random() * suffixes.length)],
|
||||||
datasets: datasets
|
datasets: datasets,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -129,7 +129,7 @@ export default class extends Module {
|
||||||
this.log('Image uploading...');
|
this.log('Image uploading...');
|
||||||
const file = await this.ai.upload(img, {
|
const file = await this.ai.upload(img, {
|
||||||
filename: 'chart.png',
|
filename: 'chart.png',
|
||||||
contentType: 'image/png'
|
contentType: 'image/png',
|
||||||
});
|
});
|
||||||
|
|
||||||
return file;
|
return file;
|
||||||
|
@ -148,14 +148,14 @@ export default class extends Module {
|
||||||
if (msg.includes(['投稿'])) type = 'userNotes';
|
if (msg.includes(['投稿'])) type = 'userNotes';
|
||||||
|
|
||||||
const file = await this.genChart(type, {
|
const file = await this.genChart(type, {
|
||||||
user: msg.user
|
user: msg.user,
|
||||||
});
|
});
|
||||||
|
|
||||||
this.log('Replying...');
|
this.log('Replying...');
|
||||||
msg.reply(serifs.chart.foryou, {file});
|
msg.reply(serifs.chart.foryou, {file});
|
||||||
|
|
||||||
return {
|
return {
|
||||||
reaction: 'like'
|
reaction: 'like',
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -18,7 +18,7 @@ const colors = {
|
||||||
'#69d2e7',
|
'#69d2e7',
|
||||||
'#f38630',
|
'#f38630',
|
||||||
'#f9d423',
|
'#f9d423',
|
||||||
]
|
],
|
||||||
};
|
};
|
||||||
|
|
||||||
const yAxisTicks = 4;
|
const yAxisTicks = 4;
|
||||||
|
@ -42,9 +42,9 @@ export function renderChart(chart: Chart) {
|
||||||
ctx.beginPath();
|
ctx.beginPath();
|
||||||
ctx.fillRect(0, 0, width, height);
|
ctx.fillRect(0, 0, width, height);
|
||||||
|
|
||||||
let chartAreaX = margin;
|
const chartAreaX = margin;
|
||||||
let chartAreaY = margin;
|
let chartAreaY = margin;
|
||||||
let chartAreaWidth = width - (margin * 2);
|
const chartAreaWidth = width - (margin * 2);
|
||||||
let chartAreaHeight = height - (margin * 2);
|
let chartAreaHeight = height - (margin * 2);
|
||||||
|
|
||||||
// Draw title
|
// Draw title
|
||||||
|
@ -100,7 +100,7 @@ export function renderChart(chart: Chart) {
|
||||||
|
|
||||||
for (let series = 0; series < serieses; series++) {
|
for (let series = 0; series < serieses; series++) {
|
||||||
newDatasets.push({
|
newDatasets.push({
|
||||||
data: []
|
data: [],
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -9,7 +9,7 @@ export default class extends Module {
|
||||||
@autobind
|
@autobind
|
||||||
public install() {
|
public install() {
|
||||||
return {
|
return {
|
||||||
mentionHook: this.mentionHook
|
mentionHook: this.mentionHook,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -22,7 +22,7 @@ export default class extends Module {
|
||||||
const b = Math.floor(Math.random() * 256);
|
const b = Math.floor(Math.random() * 256);
|
||||||
// rgbをhexに変換する
|
// rgbをhexに変換する
|
||||||
const hex = `${r.toString(16)}${g.toString(16)}${b.toString(16)}`;
|
const hex = `${r.toString(16)}${g.toString(16)}${b.toString(16)}`;
|
||||||
const message = `RGB: ${r}, ${g}, ${b} \`(#${hex})\`とかどう?`
|
const message = `RGB: ${r}, ${g}, ${b} \`(#${hex})\`とかどう?`;
|
||||||
|
|
||||||
setTimeout(async () => {
|
setTimeout(async () => {
|
||||||
const file = await this.getColorSampleFile(r, g, b);
|
const file = await this.getColorSampleFile(r, g, b);
|
||||||
|
@ -30,7 +30,7 @@ export default class extends Module {
|
||||||
msg.reply(message, {file});
|
msg.reply(message, {file});
|
||||||
}, 500);
|
}, 500);
|
||||||
return {
|
return {
|
||||||
reaction: '🎨'
|
reaction: '🎨',
|
||||||
};
|
};
|
||||||
} else {
|
} else {
|
||||||
return false;
|
return false;
|
||||||
|
@ -44,7 +44,7 @@ export default class extends Module {
|
||||||
this.log('Image uploading...');
|
this.log('Image uploading...');
|
||||||
const file = await this.ai.upload(colorSample, {
|
const file = await this.ai.upload(colorSample, {
|
||||||
filename: 'color.png',
|
filename: 'color.png',
|
||||||
contentType: 'image/png'
|
contentType: 'image/png',
|
||||||
});
|
});
|
||||||
|
|
||||||
return file;
|
return file;
|
||||||
|
|
|
@ -13,7 +13,7 @@ export default class extends Module {
|
||||||
public install() {
|
public install() {
|
||||||
return {
|
return {
|
||||||
mentionHook: this.mentionHook,
|
mentionHook: this.mentionHook,
|
||||||
contextHook: this.contextHook
|
contextHook: this.contextHook,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -87,15 +87,15 @@ export default class extends Module {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
const withSan = titles.some(t => name.endsWith(t));
|
const withSan = titles.some((t) => name.endsWith(t));
|
||||||
|
|
||||||
if (withSan) {
|
if (withSan) {
|
||||||
msg.friend.updateName(name);
|
msg.friend.updateName(name);
|
||||||
msg.reply(serifs.core.setNameOk(name));
|
msg.reply(serifs.core.setNameOk(name));
|
||||||
} else {
|
} else {
|
||||||
msg.reply(serifs.core.san).then(reply => {
|
msg.reply(serifs.core.san).then((reply) => {
|
||||||
this.subscribeReply(msg.userId, msg.isDm, msg.isDm ? msg.userId : reply.id, {
|
this.subscribeReply(msg.userId, msg.isDm, msg.isDm ? msg.userId : reply.id, {
|
||||||
name: name
|
name: name,
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
@ -117,7 +117,7 @@ export default class extends Module {
|
||||||
text += '```';
|
text += '```';
|
||||||
|
|
||||||
msg.reply(text, {
|
msg.reply(text, {
|
||||||
immediate: true
|
immediate: true,
|
||||||
});
|
});
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
|
@ -129,7 +129,7 @@ export default class extends Module {
|
||||||
if (!msg.or(['v', 'version', 'バージョン'])) return false;
|
if (!msg.or(['v', 'version', 'バージョン'])) return false;
|
||||||
|
|
||||||
msg.reply(`\`\`\`\nv${this.ai.version}\n\`\`\``, {
|
msg.reply(`\`\`\`\nv${this.ai.version}\n\`\`\``, {
|
||||||
immediate: true
|
immediate: true,
|
||||||
});
|
});
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
|
@ -151,7 +151,7 @@ export default class extends Module {
|
||||||
msg.friend.updateName(data.name);
|
msg.friend.updateName(data.name);
|
||||||
done();
|
done();
|
||||||
} else {
|
} else {
|
||||||
msg.reply(serifs.core.yesOrNo).then(reply => {
|
msg.reply(serifs.core.yesOrNo).then((reply) => {
|
||||||
this.subscribeReply(msg.userId, msg.isDm, reply.id, data);
|
this.subscribeReply(msg.userId, msg.isDm, reply.id, data);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
|
@ -8,7 +8,7 @@ export default class extends Module {
|
||||||
@autobind
|
@autobind
|
||||||
public install() {
|
public install() {
|
||||||
return {
|
return {
|
||||||
mentionHook: this.mentionHook
|
mentionHook: this.mentionHook,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -16,13 +16,13 @@ export default class extends Module {
|
||||||
private async mentionHook(msg: Message) {
|
private async mentionHook(msg: Message) {
|
||||||
if (msg.text && msg.text.includes('って何')) {
|
if (msg.text && msg.text.includes('って何')) {
|
||||||
// msg.textのうち、「の意味は」の直前で、「@ai」よりも後の物を抽出
|
// msg.textのうち、「の意味は」の直前で、「@ai」よりも後の物を抽出
|
||||||
const dic_prefix = "https://www.weblio.jp/content/";
|
const dicPrefix = 'https://www.weblio.jp/content/';
|
||||||
const raw_word = msg.text.split('って何')[0].split('@ai')[1].trim();
|
const rawWord = msg.text.split('って何')[0].split('@ai')[1].trim();
|
||||||
// スペースがある場合は、半角スペースを除去
|
// スペースがある場合は、半角スペースを除去
|
||||||
const word = raw_word.replace(/\s/g, '');
|
const word = rawWord.replace(/\s/g, '');
|
||||||
const url = dic_prefix + encodeURIComponent(word);
|
const url = dicPrefix + encodeURIComponent(word);
|
||||||
msg.reply(`こんな意味っぽい?> [${word}](${url})`, {
|
msg.reply(`こんな意味っぽい?> [${word}](${url})`, {
|
||||||
immediate: true
|
immediate: true,
|
||||||
});
|
});
|
||||||
return true;
|
return true;
|
||||||
} else {
|
} else {
|
||||||
|
|
|
@ -9,7 +9,7 @@ export default class extends Module {
|
||||||
@autobind
|
@autobind
|
||||||
public install() {
|
public install() {
|
||||||
return {
|
return {
|
||||||
mentionHook: this.mentionHook
|
mentionHook: this.mentionHook,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,13 +1,13 @@
|
||||||
import autobind from "autobind-decorator";
|
import autobind from 'autobind-decorator';
|
||||||
import Module from "@/module";
|
import Module from '@/module';
|
||||||
import config from "@/config";
|
import config from '@/config';
|
||||||
import Message from "@/message";
|
import Message from '@/message';
|
||||||
import * as http from "http";
|
import * as http from 'http';
|
||||||
|
|
||||||
// 基本的に生データはstringばっかり。都合のいい形に加工済みの状態の型定義を書いています。
|
// 基本的に生データはstringばっかり。都合のいい形に加工済みの状態の型定義を書いています。
|
||||||
// ここでいくらか言及されてる(https://bultar.bbs.fc2.com/?act=reply&tid=5645851);
|
// ここでいくらか言及されてる(https://bultar.bbs.fc2.com/?act=reply&tid=5645851);
|
||||||
interface 緊急地震速報 {
|
interface 緊急地震速報 {
|
||||||
type: "eew";
|
type: 'eew';
|
||||||
time: Date;
|
time: Date;
|
||||||
report: string; // 第n報 最終報はstringで'final'となるので、とりあえずstring型
|
report: string; // 第n報 最終報はstringで'final'となるので、とりあえずstring型
|
||||||
epicenter: string; // 震源地
|
epicenter: string; // 震源地
|
||||||
|
@ -20,12 +20,12 @@ interface 緊急地震速報 {
|
||||||
}
|
}
|
||||||
|
|
||||||
interface 緊急地震速報キャンセル {
|
interface 緊急地震速報キャンセル {
|
||||||
type: "pga_alert_cancel";
|
type: 'pga_alert_cancel';
|
||||||
time: Date;
|
time: Date;
|
||||||
}
|
}
|
||||||
|
|
||||||
interface 震度レポート {
|
interface 震度レポート {
|
||||||
type: "intensity_report";
|
type: 'intensity_report';
|
||||||
time: string;
|
time: string;
|
||||||
max_index: number;
|
max_index: number;
|
||||||
intensity_list: {
|
intensity_list: {
|
||||||
|
@ -36,7 +36,7 @@ interface 震度レポート {
|
||||||
}
|
}
|
||||||
|
|
||||||
interface 地震検知 {
|
interface 地震検知 {
|
||||||
type: "pga_alert";
|
type: 'pga_alert';
|
||||||
time: Date;
|
time: Date;
|
||||||
max_pga: number;
|
max_pga: number;
|
||||||
new: boolean;
|
new: boolean;
|
||||||
|
@ -45,22 +45,22 @@ interface 地震検知 {
|
||||||
}
|
}
|
||||||
|
|
||||||
export default class extends Module {
|
export default class extends Module {
|
||||||
public readonly name = "earthquake";
|
public readonly name = 'earthquake';
|
||||||
private message: string = "";
|
private message: string = '';
|
||||||
|
|
||||||
private thresholdVal = 3; // 下の配列の添え字に相当する値。しきい値以上のものについて通知を出す。 普段は3(震度2)
|
private thresholdVal = 3; // 下の配列の添え字に相当する値。しきい値以上のものについて通知を出す。 普段は3(震度2)
|
||||||
private earthquakeIntensityIndex: string[] = [
|
private earthquakeIntensityIndex: string[] = [
|
||||||
"0未満",
|
'0未満',
|
||||||
"0",
|
'0',
|
||||||
"1",
|
'1',
|
||||||
"2",
|
'2',
|
||||||
"3",
|
'3',
|
||||||
"4",
|
'4',
|
||||||
"5弱",
|
'5弱',
|
||||||
"5強",
|
'5強',
|
||||||
"6弱",
|
'6弱',
|
||||||
"6強",
|
'6強',
|
||||||
"7",
|
'7',
|
||||||
];
|
];
|
||||||
|
|
||||||
@autobind
|
@autobind
|
||||||
|
@ -72,7 +72,7 @@ export default class extends Module {
|
||||||
@autobind
|
@autobind
|
||||||
private async createListenServer() {
|
private async createListenServer() {
|
||||||
http.createServer(async (req, res) => {
|
http.createServer(async (req, res) => {
|
||||||
this.message = "";
|
this.message = '';
|
||||||
const buffers: Buffer[] = [];
|
const buffers: Buffer[] = [];
|
||||||
for await (const chunk of req) {
|
for await (const chunk of req) {
|
||||||
buffers.push(chunk);
|
buffers.push(chunk);
|
||||||
|
@ -88,7 +88,7 @@ export default class extends Module {
|
||||||
}),
|
}),
|
||||||
);
|
);
|
||||||
|
|
||||||
if (rawDataJSON.type == "intensity_report") {
|
if (rawDataJSON.type == 'intensity_report') {
|
||||||
if (rawDataJSON.max_index >= this.thresholdVal - 1) {
|
if (rawDataJSON.max_index >= this.thresholdVal - 1) {
|
||||||
// 日付時刻は、yyyy-mm-dd hh:mm:ss
|
// 日付時刻は、yyyy-mm-dd hh:mm:ss
|
||||||
const time = new Date(parseInt(rawDataJSON.time));
|
const time = new Date(parseInt(rawDataJSON.time));
|
||||||
|
@ -106,13 +106,13 @@ export default class extends Module {
|
||||||
}\n\n${
|
}\n\n${
|
||||||
data.intensity_list.map((intensity) =>
|
data.intensity_list.map((intensity) =>
|
||||||
`震度${this.earthquakeIntensityIndex[intensity.index + 1]}: ${
|
`震度${this.earthquakeIntensityIndex[intensity.index + 1]}: ${
|
||||||
intensity.region_list.join(" ")
|
intensity.region_list.join(' ')
|
||||||
}`
|
}`,
|
||||||
).join("\n")
|
).join('\n')
|
||||||
}\n\`\`\``;
|
}\n\`\`\``;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (rawDataJSON.type == "eew") { // これ使わなさそうだしとりあえず入らないようにした
|
if (rawDataJSON.type == 'eew') { // これ使わなさそうだしとりあえず入らないようにした
|
||||||
const data: 緊急地震速報 = {
|
const data: 緊急地震速報 = {
|
||||||
type: rawDataJSON.type,
|
type: rawDataJSON.type,
|
||||||
time: new Date(parseInt(rawDataJSON.time)),
|
time: new Date(parseInt(rawDataJSON.time)),
|
||||||
|
@ -126,7 +126,7 @@ export default class extends Module {
|
||||||
index: rawDataJSON.index,
|
index: rawDataJSON.index,
|
||||||
};
|
};
|
||||||
|
|
||||||
if (data.report == "final") { // && data.index >= this.thresholdVal - 1
|
if (data.report == 'final') { // && data.index >= this.thresholdVal - 1
|
||||||
const timeString = `${data.time.getFullYear()}-${(data.time.getMonth() +
|
const timeString = `${data.time.getFullYear()}-${(data.time.getMonth() +
|
||||||
1).toString().padStart(2, '0')}-${data.time.getDate().toString().padStart(2, '0')} ${data.time.getHours().toString().padStart(2, '0')}:${data.time.getMinutes().toString().padStart(2, '0')}:${data.time.getSeconds().toString().padStart(2, '0')}`;
|
1).toString().padStart(2, '0')}-${data.time.getDate().toString().padStart(2, '0')} ${data.time.getHours().toString().padStart(2, '0')}:${data.time.getMinutes().toString().padStart(2, '0')}:${data.time.getSeconds().toString().padStart(2, '0')}`;
|
||||||
this.message = `\`\`\`\n緊急地震速報(最終報)\n${timeString}\n震源地: ${data.epicenter}\n震源の深さ: ${data.depth}\n最大予測震度: ${this.earthquakeIntensityIndex[data.index + 1]}\nマグニチュード: ${data.magnitude}\n\`\`\``;
|
this.message = `\`\`\`\n緊急地震速報(最終報)\n${timeString}\n震源地: ${data.epicenter}\n震源の深さ: ${data.depth}\n最大予測震度: ${this.earthquakeIntensityIndex[data.index + 1]}\nマグニチュード: ${data.magnitude}\n\`\`\``;
|
||||||
|
@ -138,10 +138,10 @@ export default class extends Module {
|
||||||
console.table(rawDataJSON.intensity_list); // デバッグ用
|
console.table(rawDataJSON.intensity_list); // デバッグ用
|
||||||
}
|
}
|
||||||
|
|
||||||
this.returnResponse(res, "ok");
|
this.returnResponse(res, 'ok');
|
||||||
if (this.message) {
|
if (this.message) {
|
||||||
this.ai.post({
|
this.ai.post({
|
||||||
visibility: "home",
|
visibility: 'home',
|
||||||
text: this.message,
|
text: this.message,
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
@ -152,7 +152,7 @@ export default class extends Module {
|
||||||
@autobind
|
@autobind
|
||||||
private returnResponse(res: http.ServerResponse, text: string) {
|
private returnResponse(res: http.ServerResponse, text: string) {
|
||||||
res.writeHead(200, {
|
res.writeHead(200, {
|
||||||
"Content-Type": "text/plain",
|
'Content-Type': 'text/plain',
|
||||||
});
|
});
|
||||||
res.end(text);
|
res.end(text);
|
||||||
}
|
}
|
||||||
|
|
|
@ -32,7 +32,7 @@ export default class extends Module {
|
||||||
}
|
}
|
||||||
this.ai.api('notes/reactions/create', {
|
this.ai.api('notes/reactions/create', {
|
||||||
noteId: note.id,
|
noteId: note.id,
|
||||||
reaction: reaction
|
reaction: reaction,
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -45,7 +45,7 @@ export default class extends Module {
|
||||||
return await react(':erait:');
|
return await react(':erait:');
|
||||||
}
|
}
|
||||||
|
|
||||||
if (includes(note.text, ['いい']) && (includes(note.text, ["?"]) || includes(note.text, ["?"]))) {
|
if (includes(note.text, ['いい']) && (includes(note.text, ['?']) || includes(note.text, ['?']))) {
|
||||||
// 50%の確率で":dame:"または":yattare:"を返す
|
// 50%の確率で":dame:"または":yattare:"を返す
|
||||||
if (Math.random() < 0.5) {
|
if (Math.random() < 0.5) {
|
||||||
return react(':dame:');
|
return react(':dame:');
|
||||||
|
@ -68,14 +68,14 @@ export default class extends Module {
|
||||||
return react(customEmojis[0]);
|
return react(customEmojis[0]);
|
||||||
}
|
}
|
||||||
|
|
||||||
const emojis = parse(note.text).map(x => x.text);
|
const emojis = parse(note.text).map((x) => x.text);
|
||||||
if (emojis.length > 0) {
|
if (emojis.length > 0) {
|
||||||
// 絵文字が複数種類ある場合はキャンセル
|
// 絵文字が複数種類ある場合はキャンセル
|
||||||
if (!emojis.every((val, i, arr) => val === arr[0])) return;
|
if (!emojis.every((val, i, arr) => val === arr[0])) return;
|
||||||
|
|
||||||
this.log(`Emoji detected - ${emojis[0]}`);
|
this.log(`Emoji detected - ${emojis[0]}`);
|
||||||
|
|
||||||
let reaction = emojis[0];
|
const reaction = emojis[0];
|
||||||
|
|
||||||
switch (reaction) {
|
switch (reaction) {
|
||||||
case '✊': return react('🖐', true);
|
case '✊': return react('🖐', true);
|
||||||
|
@ -93,7 +93,7 @@ export default class extends Module {
|
||||||
if (includes(note.text, ['ずなず']) || includes(note.text, ['ずにゃず'])) return react('🙌');
|
if (includes(note.text, ['ずなず']) || includes(note.text, ['ずにゃず'])) return react('🙌');
|
||||||
if (includes(note.text, ['なず']) || includes(note.text, ['にゃず'])) {
|
if (includes(note.text, ['なず']) || includes(note.text, ['にゃず'])) {
|
||||||
if (this.ai.isMaster(note.userId)) {
|
if (this.ai.isMaster(note.userId)) {
|
||||||
return react(':google_hart:')
|
return react(':google_hart:');
|
||||||
}
|
}
|
||||||
return react(':oltu:');
|
return react(':oltu:');
|
||||||
};
|
};
|
||||||
|
@ -101,8 +101,8 @@ export default class extends Module {
|
||||||
const gameReact = [
|
const gameReact = [
|
||||||
':ysvi:',
|
':ysvi:',
|
||||||
':ysf:',
|
':ysf:',
|
||||||
':yso:'
|
':yso:',
|
||||||
]
|
];
|
||||||
if (includes(note.text, ['おゲームするかしら'])) {
|
if (includes(note.text, ['おゲームするかしら'])) {
|
||||||
// gameReactの中からランダムに選択
|
// gameReactの中からランダムに選択
|
||||||
return react(gameReact[Math.floor(Math.random() * gameReact.length)]);
|
return react(gameReact[Math.floor(Math.random() * gameReact.length)]);
|
||||||
|
|
|
@ -30,8 +30,8 @@ const hands = [
|
||||||
'🤙',
|
'🤙',
|
||||||
'💪',
|
'💪',
|
||||||
['💪', '✌'],
|
['💪', '✌'],
|
||||||
'🖕'
|
'🖕',
|
||||||
]
|
];
|
||||||
|
|
||||||
const faces = [
|
const faces = [
|
||||||
'😀',
|
'😀',
|
||||||
|
@ -123,8 +123,8 @@ const faces = [
|
||||||
'🤠',
|
'🤠',
|
||||||
'🗿',
|
'🗿',
|
||||||
'🤖',
|
'🤖',
|
||||||
'👽'
|
'👽',
|
||||||
]
|
];
|
||||||
|
|
||||||
export default class extends Module {
|
export default class extends Module {
|
||||||
public readonly name = 'emoji';
|
public readonly name = 'emoji';
|
||||||
|
@ -132,7 +132,7 @@ export default class extends Module {
|
||||||
@autobind
|
@autobind
|
||||||
public install() {
|
public install() {
|
||||||
return {
|
return {
|
||||||
mentionHook: this.mentionHook
|
mentionHook: this.mentionHook,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -8,7 +8,7 @@ export default class extends Module {
|
||||||
@autobind
|
@autobind
|
||||||
public install() {
|
public install() {
|
||||||
return {
|
return {
|
||||||
mentionHook: this.mentionHook
|
mentionHook: this.mentionHook,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -20,11 +20,11 @@ export default class extends Module {
|
||||||
userId: msg.userId,
|
userId: msg.userId,
|
||||||
});
|
});
|
||||||
return {
|
return {
|
||||||
reaction: msg.friend.love >= 0 ? 'like' : null
|
reaction: msg.friend.love >= 0 ? 'like' : null,
|
||||||
};
|
};
|
||||||
} else {
|
} else {
|
||||||
return {
|
return {
|
||||||
reaction: msg.friend.love >= 0 ? 'hmm' : null
|
reaction: msg.friend.love >= 0 ? 'hmm' : null,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
|
|
|
@ -43,7 +43,7 @@ export default class extends Module {
|
||||||
@autobind
|
@autobind
|
||||||
public install() {
|
public install() {
|
||||||
return {
|
return {
|
||||||
mentionHook: this.mentionHook
|
mentionHook: this.mentionHook,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -56,7 +56,7 @@ export default class extends Module {
|
||||||
const omikuji = blessing[Math.floor(rng() * blessing.length)];
|
const omikuji = blessing[Math.floor(rng() * blessing.length)];
|
||||||
const item = genItem(rng);
|
const item = genItem(rng);
|
||||||
msg.reply(`**${omikuji}🎉**\nラッキーアイテム: ${item}`, {
|
msg.reply(`**${omikuji}🎉**\nラッキーアイテム: ${item}`, {
|
||||||
cw: serifs.fortune.cw(msg.friend.name)
|
cw: serifs.fortune.cw(msg.friend.name),
|
||||||
});
|
});
|
||||||
return true;
|
return true;
|
||||||
} else {
|
} else {
|
||||||
|
|
|
@ -19,12 +19,12 @@ export default class extends Module {
|
||||||
@autobind
|
@autobind
|
||||||
public install() {
|
public install() {
|
||||||
this.guesses = this.ai.getCollection('guessingGame', {
|
this.guesses = this.ai.getCollection('guessingGame', {
|
||||||
indices: ['userId']
|
indices: ['userId'],
|
||||||
});
|
});
|
||||||
|
|
||||||
return {
|
return {
|
||||||
mentionHook: this.mentionHook,
|
mentionHook: this.mentionHook,
|
||||||
contextHook: this.contextHook
|
contextHook: this.contextHook,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -34,7 +34,7 @@ export default class extends Module {
|
||||||
|
|
||||||
const exist = this.guesses.findOne({
|
const exist = this.guesses.findOne({
|
||||||
userId: msg.userId,
|
userId: msg.userId,
|
||||||
isEnded: false
|
isEnded: false,
|
||||||
});
|
});
|
||||||
|
|
||||||
if (!msg.isDm) {
|
if (!msg.isDm) {
|
||||||
|
@ -55,10 +55,10 @@ export default class extends Module {
|
||||||
tries: [],
|
tries: [],
|
||||||
isEnded: false,
|
isEnded: false,
|
||||||
startedAt: Date.now(),
|
startedAt: Date.now(),
|
||||||
endedAt: null
|
endedAt: null,
|
||||||
});
|
});
|
||||||
|
|
||||||
msg.reply(serifs.guessingGame.started).then(reply => {
|
msg.reply(serifs.guessingGame.started).then((reply) => {
|
||||||
this.subscribeReply(msg.userId, msg.isDm, msg.isDm ? msg.userId : reply.id);
|
this.subscribeReply(msg.userId, msg.isDm, msg.isDm ? msg.userId : reply.id);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -71,7 +71,7 @@ export default class extends Module {
|
||||||
|
|
||||||
const exist = this.guesses.findOne({
|
const exist = this.guesses.findOne({
|
||||||
userId: msg.userId,
|
userId: msg.userId,
|
||||||
isEnded: false
|
isEnded: false,
|
||||||
});
|
});
|
||||||
|
|
||||||
// 処理の流れ上、実際にnullになることは無さそうだけど一応
|
// 処理の流れ上、実際にnullになることは無さそうだけど一応
|
||||||
|
@ -92,7 +92,7 @@ export default class extends Module {
|
||||||
const guess = msg.extractedText.match(/[0-9]+/);
|
const guess = msg.extractedText.match(/[0-9]+/);
|
||||||
|
|
||||||
if (guess == null) {
|
if (guess == null) {
|
||||||
msg.reply(serifs.guessingGame.nan).then(reply => {
|
msg.reply(serifs.guessingGame.nan).then((reply) => {
|
||||||
this.subscribeReply(msg.userId, msg.isDm, reply.id);
|
this.subscribeReply(msg.userId, msg.isDm, reply.id);
|
||||||
});
|
});
|
||||||
return;
|
return;
|
||||||
|
@ -109,13 +109,13 @@ export default class extends Module {
|
||||||
let end = false;
|
let end = false;
|
||||||
|
|
||||||
if (exist.secret < g) {
|
if (exist.secret < g) {
|
||||||
text = firsttime
|
text = firsttime ?
|
||||||
? serifs.guessingGame.less(g.toString())
|
serifs.guessingGame.less(g.toString()) :
|
||||||
: serifs.guessingGame.lessAgain(g.toString());
|
serifs.guessingGame.lessAgain(g.toString());
|
||||||
} else if (exist.secret > g) {
|
} else if (exist.secret > g) {
|
||||||
text = firsttime
|
text = firsttime ?
|
||||||
? serifs.guessingGame.grater(g.toString())
|
serifs.guessingGame.grater(g.toString()) :
|
||||||
: serifs.guessingGame.graterAgain(g.toString());
|
serifs.guessingGame.graterAgain(g.toString());
|
||||||
} else {
|
} else {
|
||||||
end = true;
|
end = true;
|
||||||
text = serifs.guessingGame.congrats(exist.tries.length.toString());
|
text = serifs.guessingGame.congrats(exist.tries.length.toString());
|
||||||
|
@ -129,7 +129,7 @@ export default class extends Module {
|
||||||
|
|
||||||
this.guesses.update(exist);
|
this.guesses.update(exist);
|
||||||
|
|
||||||
msg.reply(text).then(reply => {
|
msg.reply(text).then((reply) => {
|
||||||
if (!end) {
|
if (!end) {
|
||||||
this.subscribeReply(msg.userId, msg.isDm, reply.id);
|
this.subscribeReply(msg.userId, msg.isDm, reply.id);
|
||||||
}
|
}
|
||||||
|
|
|
@ -36,7 +36,7 @@ export default class extends Module {
|
||||||
|
|
||||||
return {
|
return {
|
||||||
mentionHook: this.mentionHook,
|
mentionHook: this.mentionHook,
|
||||||
contextHook: this.contextHook
|
contextHook: this.contextHook,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -52,7 +52,7 @@ export default class extends Module {
|
||||||
// 現在アクティブなゲームがある場合
|
// 現在アクティブなゲームがある場合
|
||||||
if (!recentGame.isEnded) {
|
if (!recentGame.isEnded) {
|
||||||
msg.reply(serifs.kazutori.alreadyStarted, {
|
msg.reply(serifs.kazutori.alreadyStarted, {
|
||||||
renote: recentGame.postId
|
renote: recentGame.postId,
|
||||||
});
|
});
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
@ -65,14 +65,14 @@ export default class extends Module {
|
||||||
}
|
}
|
||||||
|
|
||||||
const post = await this.ai.post({
|
const post = await this.ai.post({
|
||||||
text: serifs.kazutori.intro(limitMinutes)
|
text: serifs.kazutori.intro(limitMinutes),
|
||||||
});
|
});
|
||||||
|
|
||||||
this.games.insertOne({
|
this.games.insertOne({
|
||||||
votes: [],
|
votes: [],
|
||||||
isEnded: false,
|
isEnded: false,
|
||||||
startedAt: Date.now(),
|
startedAt: Date.now(),
|
||||||
postId: post.id
|
postId: post.id,
|
||||||
});
|
});
|
||||||
|
|
||||||
this.subscribeReply(null, false, post.id);
|
this.subscribeReply(null, false, post.id);
|
||||||
|
@ -84,38 +84,48 @@ export default class extends Module {
|
||||||
|
|
||||||
@autobind
|
@autobind
|
||||||
private async contextHook(key: any, msg: Message) {
|
private async contextHook(key: any, msg: Message) {
|
||||||
if (msg.text == null) return {
|
if (msg.text == null) {
|
||||||
reaction: 'hmm'
|
return {
|
||||||
|
reaction: 'hmm',
|
||||||
};
|
};
|
||||||
|
}
|
||||||
|
|
||||||
const game = this.games.findOne({
|
const game = this.games.findOne({
|
||||||
isEnded: false
|
isEnded: false,
|
||||||
});
|
});
|
||||||
|
|
||||||
// 処理の流れ上、実際にnullになることは無さそうだけど一応
|
// 処理の流れ上、実際にnullになることは無さそうだけど一応
|
||||||
if (game == null) return;
|
if (game == null) return;
|
||||||
|
|
||||||
// 既に数字を取っていたら
|
// 既に数字を取っていたら
|
||||||
if (game.votes.some(x => x.user.id == msg.userId)) return {
|
if (game.votes.some((x) => x.user.id == msg.userId)) {
|
||||||
reaction: 'confused'
|
return {
|
||||||
|
reaction: 'confused',
|
||||||
};
|
};
|
||||||
|
}
|
||||||
|
|
||||||
const match = msg.extractedText.match(/[0-9]+/);
|
const match = msg.extractedText.match(/[0-9]+/);
|
||||||
if (match == null) return {
|
if (match == null) {
|
||||||
reaction: 'hmm'
|
return {
|
||||||
|
reaction: 'hmm',
|
||||||
};
|
};
|
||||||
|
}
|
||||||
|
|
||||||
const num = parseInt(match[0], 10);
|
const num = parseInt(match[0], 10);
|
||||||
|
|
||||||
// 整数じゃない
|
// 整数じゃない
|
||||||
if (!Number.isInteger(num)) return {
|
if (!Number.isInteger(num)) {
|
||||||
reaction: 'hmm'
|
return {
|
||||||
|
reaction: 'hmm',
|
||||||
};
|
};
|
||||||
|
}
|
||||||
|
|
||||||
// 範囲外
|
// 範囲外
|
||||||
if (num < 0 || num > 100) return {
|
if (num < 0 || num > 100) {
|
||||||
reaction: 'confused'
|
return {
|
||||||
|
reaction: 'confused',
|
||||||
};
|
};
|
||||||
|
}
|
||||||
|
|
||||||
this.log(`Voted ${num} by ${msg.user.id}`);
|
this.log(`Voted ${num} by ${msg.user.id}`);
|
||||||
|
|
||||||
|
@ -124,15 +134,15 @@ export default class extends Module {
|
||||||
user: {
|
user: {
|
||||||
id: msg.user.id,
|
id: msg.user.id,
|
||||||
username: msg.user.username,
|
username: msg.user.username,
|
||||||
host: msg.user.host
|
host: msg.user.host,
|
||||||
},
|
},
|
||||||
number: num
|
number: num,
|
||||||
});
|
});
|
||||||
|
|
||||||
this.games.update(game);
|
this.games.update(game);
|
||||||
|
|
||||||
return {
|
return {
|
||||||
reaction: 'like'
|
reaction: 'like',
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -142,7 +152,7 @@ export default class extends Module {
|
||||||
@autobind
|
@autobind
|
||||||
private crawleGameEnd() {
|
private crawleGameEnd() {
|
||||||
const game = this.games.findOne({
|
const game = this.games.findOne({
|
||||||
isEnded: false
|
isEnded: false,
|
||||||
});
|
});
|
||||||
|
|
||||||
if (game == null) return;
|
if (game == null) return;
|
||||||
|
@ -167,19 +177,19 @@ export default class extends Module {
|
||||||
if (game.votes.length <= 1) {
|
if (game.votes.length <= 1) {
|
||||||
this.ai.post({
|
this.ai.post({
|
||||||
text: serifs.kazutori.onagare,
|
text: serifs.kazutori.onagare,
|
||||||
renoteId: game.postId
|
renoteId: game.postId,
|
||||||
});
|
});
|
||||||
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
let results: string[] = [];
|
const results: string[] = [];
|
||||||
let winner: Game['votes'][0]['user'] | null = null;
|
let winner: Game['votes'][0]['user'] | null = null;
|
||||||
|
|
||||||
for (let i = 100; i >= 0; i--) {
|
for (let i = 100; i >= 0; i--) {
|
||||||
const users = game.votes
|
const users = game.votes
|
||||||
.filter(x => x.number == i)
|
.filter((x) => x.number == i)
|
||||||
.map(x => x.user);
|
.map((x) => x.user);
|
||||||
|
|
||||||
if (users.length == 1) {
|
if (users.length == 1) {
|
||||||
if (winner == null) {
|
if (winner == null) {
|
||||||
|
@ -190,21 +200,21 @@ export default class extends Module {
|
||||||
results.push(`➖ ${i}: ${acct(users[0])}`);
|
results.push(`➖ ${i}: ${acct(users[0])}`);
|
||||||
}
|
}
|
||||||
} else if (users.length > 1) {
|
} else if (users.length > 1) {
|
||||||
results.push(`❌ ${i}: ${users.map(u => acct(u)).join(' ')}`);
|
results.push(`❌ ${i}: ${users.map((u) => acct(u)).join(' ')}`);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
const winnerFriend = winner ? this.ai.lookupFriend(winner.id) : null;
|
const winnerFriend = winner ? this.ai.lookupFriend(winner.id) : null;
|
||||||
const name = winnerFriend ? winnerFriend.name : null;
|
const name = winnerFriend ? winnerFriend.name : null;
|
||||||
|
|
||||||
const text = results.join('\n') + '\n\n' + (winner
|
const text = results.join('\n') + '\n\n' + (winner ?
|
||||||
? serifs.kazutori.finishWithWinner(acct(winner), name)
|
serifs.kazutori.finishWithWinner(acct(winner), name) :
|
||||||
: serifs.kazutori.finishWithNoWinner);
|
serifs.kazutori.finishWithNoWinner);
|
||||||
|
|
||||||
this.ai.post({
|
this.ai.post({
|
||||||
text: text,
|
text: text,
|
||||||
cw: serifs.kazutori.finish,
|
cw: serifs.kazutori.finish,
|
||||||
renoteId: game.postId
|
renoteId: game.postId,
|
||||||
});
|
});
|
||||||
|
|
||||||
this.unsubscribeReply(null);
|
this.unsubscribeReply(null);
|
||||||
|
|
|
@ -7,7 +7,7 @@ import { mecab } from './mecab';
|
||||||
import {Note} from '@/misskey/note';
|
import {Note} from '@/misskey/note';
|
||||||
|
|
||||||
function kanaToHira(str: string) {
|
function kanaToHira(str: string) {
|
||||||
return str.replace(/[\u30a1-\u30f6]/g, match => {
|
return str.replace(/[\u30a1-\u30f6]/g, (match) => {
|
||||||
const chr = match.charCodeAt(0) - 0x60;
|
const chr = match.charCodeAt(0) - 0x60;
|
||||||
return String.fromCharCode(chr);
|
return String.fromCharCode(chr);
|
||||||
});
|
});
|
||||||
|
@ -26,7 +26,7 @@ export default class extends Module {
|
||||||
if (!config.keywordEnabled) return {};
|
if (!config.keywordEnabled) return {};
|
||||||
|
|
||||||
this.learnedKeywords = this.ai.getCollection('_keyword_learnedKeywords', {
|
this.learnedKeywords = this.ai.getCollection('_keyword_learnedKeywords', {
|
||||||
indices: ['userId']
|
indices: ['userId'],
|
||||||
});
|
});
|
||||||
|
|
||||||
setInterval(this.learn, 1000 * 60 * 60);
|
setInterval(this.learn, 1000 * 60 * 60);
|
||||||
|
@ -37,7 +37,7 @@ export default class extends Module {
|
||||||
@autobind
|
@autobind
|
||||||
private async learn() {
|
private async learn() {
|
||||||
const tl = await this.ai.api('notes/local-timeline', {
|
const tl = await this.ai.api('notes/local-timeline', {
|
||||||
limit: 30
|
limit: 30,
|
||||||
});
|
});
|
||||||
|
|
||||||
const interestedNotes = tl.filter((note: Note) =>
|
const interestedNotes = tl.filter((note: Note) =>
|
||||||
|
@ -49,7 +49,7 @@ export default class extends Module {
|
||||||
|
|
||||||
for (const note of interestedNotes) {
|
for (const note of interestedNotes) {
|
||||||
const tokens = await mecab(note.text, config.mecab, config.mecabDic);
|
const tokens = await mecab(note.text, config.mecab, config.mecabDic);
|
||||||
const keywordsInThisNote = tokens.filter(token => token[2] == '固有名詞' && token[8] != null);
|
const keywordsInThisNote = tokens.filter((token) => token[2] == '固有名詞' && token[8] != null);
|
||||||
keywords = keywords.concat(keywordsInThisNote);
|
keywords = keywords.concat(keywordsInThisNote);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -59,7 +59,7 @@ export default class extends Module {
|
||||||
const keyword = keywords.sort((a, b) => a[0].length < b[0].length ? 1 : -1)[rnd];
|
const keyword = keywords.sort((a, b) => a[0].length < b[0].length ? 1 : -1)[rnd];
|
||||||
|
|
||||||
const exist = this.learnedKeywords.findOne({
|
const exist = this.learnedKeywords.findOne({
|
||||||
keyword: keyword[0]
|
keyword: keyword[0],
|
||||||
});
|
});
|
||||||
|
|
||||||
let text: string;
|
let text: string;
|
||||||
|
@ -69,14 +69,14 @@ export default class extends Module {
|
||||||
} else {
|
} else {
|
||||||
this.learnedKeywords.insertOne({
|
this.learnedKeywords.insertOne({
|
||||||
keyword: keyword[0],
|
keyword: keyword[0],
|
||||||
learnedAt: Date.now()
|
learnedAt: Date.now(),
|
||||||
});
|
});
|
||||||
|
|
||||||
text = serifs.keyword.learned(keyword[0], kanaToHira(keyword[8]));
|
text = serifs.keyword.learned(keyword[0], kanaToHira(keyword[8]));
|
||||||
}
|
}
|
||||||
|
|
||||||
this.ai.post({
|
this.ai.post({
|
||||||
text: text
|
text: text,
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
import * as gen from 'random-seed';
|
import * as gen from 'random-seed';
|
||||||
import {CellType} from './maze';
|
import {CellType} from './maze';
|
||||||
import {mazeSize} from './index'
|
import {mazeSize} from './index';
|
||||||
|
|
||||||
const cellVariants = {
|
const cellVariants = {
|
||||||
void: {
|
void: {
|
||||||
|
@ -92,7 +92,7 @@ export function genMaze(seed: string, complexity: mazeSize): CellType[][] {
|
||||||
return 11 + rand(21);
|
return 11 + rand(21);
|
||||||
}
|
}
|
||||||
|
|
||||||
let mazeSize: number = decisionSize(complexity);
|
const mazeSize: number = decisionSize(complexity);
|
||||||
|
|
||||||
|
|
||||||
const donut = rand(3) === 0;
|
const donut = rand(3) === 0;
|
||||||
|
|
|
@ -16,7 +16,7 @@ export default class extends Module {
|
||||||
setInterval(this.post, 1000 * 60 * 3);
|
setInterval(this.post, 1000 * 60 * 3);
|
||||||
|
|
||||||
return {
|
return {
|
||||||
mentionHook: this.mentionHook
|
mentionHook: this.mentionHook,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -36,7 +36,7 @@ export default class extends Module {
|
||||||
this.log('Posting...');
|
this.log('Posting...');
|
||||||
this.ai.post({
|
this.ai.post({
|
||||||
text: serifs.maze.post,
|
text: serifs.maze.post,
|
||||||
fileIds: [file.id]
|
fileIds: [file.id],
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -51,7 +51,7 @@ export default class extends Module {
|
||||||
this.log('Image uploading...');
|
this.log('Image uploading...');
|
||||||
const file = await this.ai.upload(data, {
|
const file = await this.ai.upload(data, {
|
||||||
filename: 'maze.png',
|
filename: 'maze.png',
|
||||||
contentType: 'image/png'
|
contentType: 'image/png',
|
||||||
});
|
});
|
||||||
|
|
||||||
return file;
|
return file;
|
||||||
|
@ -73,7 +73,7 @@ export default class extends Module {
|
||||||
msg.reply(serifs.maze.foryou, {file});
|
msg.reply(serifs.maze.foryou, {file});
|
||||||
}, 3000);
|
}, 3000);
|
||||||
return {
|
return {
|
||||||
reaction: 'like'
|
reaction: 'like',
|
||||||
};
|
};
|
||||||
} else {
|
} else {
|
||||||
return false;
|
return false;
|
||||||
|
|
|
@ -9,7 +9,7 @@ export default class extends Module {
|
||||||
@autobind
|
@autobind
|
||||||
public install() {
|
public install() {
|
||||||
return {
|
return {
|
||||||
mentionHook: this.mentionHook
|
mentionHook: this.mentionHook,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -17,8 +17,8 @@ export default class extends Module {
|
||||||
private async mentionHook(msg: Message): Promise<boolean> {
|
private async mentionHook(msg: Message): Promise<boolean> {
|
||||||
if (msg.text && msg.text.includes('ごはん')) {
|
if (msg.text && msg.text.includes('ごはん')) {
|
||||||
// 1~2535111の適当な数字を取得
|
// 1~2535111の適当な数字を取得
|
||||||
const random_number = Math.floor(Math.random() * 2535111) + 1;
|
const randomNumber = Math.floor(Math.random() * 2535111) + 1;
|
||||||
const url = `https://cookpad.com/recipe/${random_number}`;
|
const url = `https://cookpad.com/recipe/${randomNumber}`;
|
||||||
// testUrlして、200以外なら再取得
|
// testUrlして、200以外なら再取得
|
||||||
const res = await fetch(url);
|
const res = await fetch(url);
|
||||||
if (res.status !== 200) {
|
if (res.status !== 200) {
|
||||||
|
@ -31,7 +31,7 @@ export default class extends Module {
|
||||||
// titleから改行を除去
|
// titleから改行を除去
|
||||||
title = title!.replace(/\n/g, '');
|
title = title!.replace(/\n/g, '');
|
||||||
msg.reply(`こんなのどう?> [${title}](${url})`, {
|
msg.reply(`こんなのどう?> [${title}](${url})`, {
|
||||||
immediate: true
|
immediate: true,
|
||||||
});
|
});
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
|
@ -43,7 +43,7 @@ export default class extends Module {
|
||||||
// TODO: 季節に応じたセリフ
|
// TODO: 季節に応じたセリフ
|
||||||
|
|
||||||
this.ai.post({
|
this.ai.post({
|
||||||
text: typeof note === 'function' ? note() : note
|
text: typeof note === 'function' ? note() : note,
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -8,7 +8,7 @@ export default class extends Module {
|
||||||
@autobind
|
@autobind
|
||||||
public install() {
|
public install() {
|
||||||
return {
|
return {
|
||||||
mentionHook: this.mentionHook
|
mentionHook: this.mentionHook,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -18,14 +18,14 @@ export default class extends Module {
|
||||||
if (msg.text.includes('おい')) {
|
if (msg.text.includes('おい')) {
|
||||||
if (this.ai.isMaster(msg.userId)) {
|
if (this.ai.isMaster(msg.userId)) {
|
||||||
msg.reply('はい。。。', {
|
msg.reply('はい。。。', {
|
||||||
immediate: true
|
immediate: true,
|
||||||
});
|
});
|
||||||
} else {
|
} else {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
msg.reply('PONG!', {
|
msg.reply('PONG!', {
|
||||||
immediate: true
|
immediate: true,
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
|
|
|
@ -79,7 +79,7 @@ export default class extends Module {
|
||||||
choices,
|
choices,
|
||||||
expiredAfter: duration,
|
expiredAfter: duration,
|
||||||
multiple: false,
|
multiple: false,
|
||||||
}
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
// タイマーセット
|
// タイマーセット
|
||||||
|
@ -121,7 +121,7 @@ export default class extends Module {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
const mostVotedChoices = choices.filter(choice => choice.votes === mostVotedChoice.votes);
|
const mostVotedChoices = choices.filter((choice) => choice.votes === mostVotedChoice.votes);
|
||||||
|
|
||||||
if (mostVotedChoice.votes === 0) {
|
if (mostVotedChoice.votes === 0) {
|
||||||
this.ai.post({ // TODO: Extract serif
|
this.ai.post({ // TODO: Extract serif
|
||||||
|
@ -135,7 +135,7 @@ export default class extends Module {
|
||||||
renoteId: noteId,
|
renoteId: noteId,
|
||||||
});
|
});
|
||||||
} else {
|
} else {
|
||||||
const choices = mostVotedChoices.map(choice => `「${choice.text}」`).join('と');
|
const choices = mostVotedChoices.map((choice) => `「${choice.text}」`).join('と');
|
||||||
this.ai.post({ // TODO: Extract serif
|
this.ai.post({ // TODO: Extract serif
|
||||||
cw: `${title}アンケートの結果発表です!`,
|
cw: `${title}アンケートの結果発表です!`,
|
||||||
text: `結果は${mostVotedChoice.votes}票の${choices}でした!`,
|
text: `結果は${mostVotedChoice.votes}票の${choices}でした!`,
|
||||||
|
|
|
@ -24,7 +24,7 @@ export default class extends Module {
|
||||||
@autobind
|
@autobind
|
||||||
public install() {
|
public install() {
|
||||||
this.reminds = this.ai.getCollection('reminds', {
|
this.reminds = this.ai.getCollection('reminds', {
|
||||||
indices: ['userId', 'id']
|
indices: ['userId', 'id'],
|
||||||
});
|
});
|
||||||
|
|
||||||
return {
|
return {
|
||||||
|
@ -44,9 +44,9 @@ export default class extends Module {
|
||||||
userId: msg.userId,
|
userId: msg.userId,
|
||||||
});
|
});
|
||||||
|
|
||||||
const getQuoteLink = id => `[${id}](${config.host}/notes/${id})`;
|
const getQuoteLink = (id) => `[${id}](${config.host}/notes/${id})`;
|
||||||
|
|
||||||
msg.reply(serifs.reminder.reminds + '\n' + reminds.map(remind => `・${remind.thing ? remind.thing : getQuoteLink(remind.quoteId)}`).join('\n'));
|
msg.reply(serifs.reminder.reminds + '\n' + reminds.map((remind) => `・${remind.thing ? remind.thing : getQuoteLink(remind.quoteId)}`).join('\n'));
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -87,13 +87,13 @@ export default class extends Module {
|
||||||
|
|
||||||
// メンションをsubscribe
|
// メンションをsubscribe
|
||||||
this.subscribeReply(remind!.id, msg.isDm, msg.isDm ? msg.userId : msg.id, {
|
this.subscribeReply(remind!.id, msg.isDm, msg.isDm ? msg.userId : msg.id, {
|
||||||
id: remind!.id
|
id: remind!.id,
|
||||||
});
|
});
|
||||||
|
|
||||||
if (msg.quoteId) {
|
if (msg.quoteId) {
|
||||||
// 引用元をsubscribe
|
// 引用元をsubscribe
|
||||||
this.subscribeReply(remind!.id, false, msg.quoteId, {
|
this.subscribeReply(remind!.id, false, msg.quoteId, {
|
||||||
id: remind!.id
|
id: remind!.id,
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -142,7 +142,7 @@ export default class extends Module {
|
||||||
@autobind
|
@autobind
|
||||||
private async timeoutCallback(data) {
|
private async timeoutCallback(data) {
|
||||||
const remind = this.reminds.findOne({
|
const remind = this.reminds.findOne({
|
||||||
id: data.id
|
id: data.id,
|
||||||
});
|
});
|
||||||
if (remind == null) return;
|
if (remind == null) return;
|
||||||
|
|
||||||
|
@ -155,13 +155,13 @@ export default class extends Module {
|
||||||
let reply;
|
let reply;
|
||||||
if (remind.isDm) {
|
if (remind.isDm) {
|
||||||
this.ai.sendMessage(friend.userId, {
|
this.ai.sendMessage(friend.userId, {
|
||||||
text: serifs.reminder.notifyWithThing(remind.thing, friend.name)
|
text: serifs.reminder.notifyWithThing(remind.thing, friend.name),
|
||||||
});
|
});
|
||||||
} else {
|
} else {
|
||||||
try {
|
try {
|
||||||
reply = await this.ai.post({
|
reply = await this.ai.post({
|
||||||
renoteId: remind.thing == null && remind.quoteId ? remind.quoteId : remind.id,
|
renoteId: remind.thing == null && remind.quoteId ? remind.quoteId : remind.id,
|
||||||
text: acct(friend.doc.user) + ' ' + serifs.reminder.notify(friend.name)
|
text: acct(friend.doc.user) + ' ' + serifs.reminder.notify(friend.name),
|
||||||
});
|
});
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
// renote対象が消されていたらリマインダー解除
|
// renote対象が消されていたらリマインダー解除
|
||||||
|
@ -175,7 +175,7 @@ export default class extends Module {
|
||||||
}
|
}
|
||||||
|
|
||||||
this.subscribeReply(remind.id, remind.isDm, remind.isDm ? remind.userId : reply.id, {
|
this.subscribeReply(remind.id, remind.isDm, remind.isDm ? remind.userId : reply.id, {
|
||||||
id: remind.id
|
id: remind.id,
|
||||||
});
|
});
|
||||||
|
|
||||||
// タイマーセット
|
// タイマーセット
|
||||||
|
|
|
@ -22,7 +22,7 @@ const titles = [
|
||||||
'さん', 'サン', 'サン', '㌠',
|
'さん', 'サン', 'サン', '㌠',
|
||||||
'ちゃん', 'チャン', 'チャン',
|
'ちゃん', 'チャン', 'チャン',
|
||||||
'君', 'くん', 'クン', 'クン',
|
'君', 'くん', 'クン', 'クン',
|
||||||
'先生', 'せんせい', 'センセイ', 'センセイ'
|
'先生', 'せんせい', 'センセイ', 'センセイ',
|
||||||
];
|
];
|
||||||
|
|
||||||
class Session {
|
class Session {
|
||||||
|
@ -63,11 +63,11 @@ class Session {
|
||||||
|
|
||||||
private get userName(): string {
|
private get userName(): string {
|
||||||
const name = getUserName(this.user);
|
const name = getUserName(this.user);
|
||||||
return `?[${name}](${config.host}/@${this.user.username})${titles.some(x => name.endsWith(x)) ? '' : 'さん'}`;
|
return `?[${name}](${config.host}/@${this.user.username})${titles.some((x) => name.endsWith(x)) ? '' : 'さん'}`;
|
||||||
}
|
}
|
||||||
|
|
||||||
private get strength(): number {
|
private get strength(): number {
|
||||||
return this.form.find(i => i.id == 'strength').value;
|
return this.form.find((i) => i.id == 'strength').value;
|
||||||
}
|
}
|
||||||
|
|
||||||
private get isSettai(): boolean {
|
private get isSettai(): boolean {
|
||||||
|
@ -75,7 +75,7 @@ class Session {
|
||||||
}
|
}
|
||||||
|
|
||||||
private get allowPost(): boolean {
|
private get allowPost(): boolean {
|
||||||
return this.form.find(i => i.id == 'publish').value;
|
return this.form.find((i) => i.id == 'publish').value;
|
||||||
}
|
}
|
||||||
|
|
||||||
private get url(): string {
|
private get url(): string {
|
||||||
|
@ -94,21 +94,21 @@ class Session {
|
||||||
case 'ended': this.onEnded(msg.body); break;
|
case 'ended': this.onEnded(msg.body); break;
|
||||||
case 'set': this.onSet(msg.body); break;
|
case 'set': this.onSet(msg.body); break;
|
||||||
}
|
}
|
||||||
}
|
};
|
||||||
|
|
||||||
// 親プロセスからデータをもらう
|
// 親プロセスからデータをもらう
|
||||||
private onInit = (msg: any) => {
|
private onInit = (msg: any) => {
|
||||||
this.game = msg.game;
|
this.game = msg.game;
|
||||||
this.form = msg.form;
|
this.form = msg.form;
|
||||||
this.account = msg.account;
|
this.account = msg.account;
|
||||||
}
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* フォームが更新されたとき
|
* フォームが更新されたとき
|
||||||
*/
|
*/
|
||||||
private onUpdateForn = (msg: any) => {
|
private onUpdateForn = (msg: any) => {
|
||||||
this.form.find(i => i.id == msg.id).value = msg.value;
|
this.form.find((i) => i.id == msg.id).value = msg.value;
|
||||||
}
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 対局が始まったとき
|
* 対局が始まったとき
|
||||||
|
@ -117,7 +117,7 @@ class Session {
|
||||||
this.game = msg;
|
this.game = msg;
|
||||||
|
|
||||||
// TLに投稿する
|
// TLに投稿する
|
||||||
this.postGameStarted().then(note => {
|
this.postGameStarted().then((note) => {
|
||||||
this.startedNote = note;
|
this.startedNote = note;
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -125,10 +125,10 @@ class Session {
|
||||||
this.o = new Reversi(this.game.map, {
|
this.o = new Reversi(this.game.map, {
|
||||||
isLlotheo: this.game.isLlotheo,
|
isLlotheo: this.game.isLlotheo,
|
||||||
canPutEverywhere: this.game.canPutEverywhere,
|
canPutEverywhere: this.game.canPutEverywhere,
|
||||||
loopedBoard: this.game.loopedBoard
|
loopedBoard: this.game.loopedBoard,
|
||||||
});
|
});
|
||||||
|
|
||||||
this.maxTurn = this.o.map.filter(p => p === 'empty').length - this.o.board.filter(x => x != null).length;
|
this.maxTurn = this.o.map.filter((p) => p === 'empty').length - this.o.board.filter((x) => x != null).length;
|
||||||
|
|
||||||
// #region 隅の位置計算など
|
// #region 隅の位置計算など
|
||||||
|
|
||||||
|
@ -162,7 +162,7 @@ class Session {
|
||||||
// -+-
|
// -+-
|
||||||
//
|
//
|
||||||
(get(x - 1, y) == 'empty' && get(x + 1, y) == 'empty')
|
(get(x - 1, y) == 'empty' && get(x + 1, y) == 'empty')
|
||||||
)
|
);
|
||||||
|
|
||||||
const isSumi = !isNotSumi;
|
const isSumi = !isNotSumi;
|
||||||
|
|
||||||
|
@ -191,7 +191,7 @@ class Session {
|
||||||
check(x, y + 1) || // 下
|
check(x, y + 1) || // 下
|
||||||
check(x - 1, y + 1) || // 左下
|
check(x - 1, y + 1) || // 左下
|
||||||
check(x - 1, y ) // 左
|
check(x - 1, y ) // 左
|
||||||
)
|
);
|
||||||
|
|
||||||
if (isSumiNear) this.sumiNearIndexes.push(i);
|
if (isSumiNear) this.sumiNearIndexes.push(i);
|
||||||
});
|
});
|
||||||
|
@ -204,7 +204,7 @@ class Session {
|
||||||
if (this.botColor) {
|
if (this.botColor) {
|
||||||
this.think();
|
this.think();
|
||||||
}
|
}
|
||||||
}
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 対局が終わったとき
|
* 対局が終わったとき
|
||||||
|
@ -212,7 +212,7 @@ class Session {
|
||||||
private onEnded = async (msg: any) => {
|
private onEnded = async (msg: any) => {
|
||||||
// ストリームから切断
|
// ストリームから切断
|
||||||
process.send!({
|
process.send!({
|
||||||
type: 'ended'
|
type: 'ended',
|
||||||
});
|
});
|
||||||
|
|
||||||
let text: string;
|
let text: string;
|
||||||
|
@ -248,7 +248,7 @@ class Session {
|
||||||
await this.post(text, this.startedNote);
|
await this.post(text, this.startedNote);
|
||||||
|
|
||||||
process.exit();
|
process.exit();
|
||||||
}
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 打たれたとき
|
* 打たれたとき
|
||||||
|
@ -260,7 +260,7 @@ class Session {
|
||||||
if (msg.next === this.botColor) {
|
if (msg.next === this.botColor) {
|
||||||
this.think();
|
this.think();
|
||||||
}
|
}
|
||||||
}
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Botにとってある局面がどれだけ有利か静的に評価する
|
* Botにとってある局面がどれだけ有利か静的に評価する
|
||||||
|
@ -299,7 +299,7 @@ class Session {
|
||||||
if (this.isSettai) score = -score;
|
if (this.isSettai) score = -score;
|
||||||
|
|
||||||
return score;
|
return score;
|
||||||
}
|
};
|
||||||
|
|
||||||
private think = () => {
|
private think = () => {
|
||||||
console.log(`(${this.currentTurn}/${this.maxTurn}) Thinking...`);
|
console.log(`(${this.currentTurn}/${this.maxTurn}) Thinking...`);
|
||||||
|
@ -344,9 +344,9 @@ class Session {
|
||||||
this.o.undo();
|
this.o.undo();
|
||||||
|
|
||||||
// 接待なら自分が負けた方が高スコア
|
// 接待なら自分が負けた方が高スコア
|
||||||
return this.isSettai
|
return this.isSettai ?
|
||||||
? winner !== this.botColor ? score : -score
|
winner !== this.botColor ? score : -score :
|
||||||
: winner === this.botColor ? score : -score;
|
winner === this.botColor ? score : -score;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (depth === maxDepth) {
|
if (depth === maxDepth) {
|
||||||
|
@ -391,7 +391,7 @@ class Session {
|
||||||
};
|
};
|
||||||
|
|
||||||
const cans = this.o.canPutSomewhere(this.botColor);
|
const cans = this.o.canPutSomewhere(this.botColor);
|
||||||
const scores = cans.map(p => dive(p));
|
const scores = cans.map((p) => dive(p));
|
||||||
const pos = cans[scores.indexOf(Math.max(...scores))];
|
const pos = cans[scores.indexOf(Math.max(...scores))];
|
||||||
|
|
||||||
console.log('Thinked:', pos);
|
console.log('Thinked:', pos);
|
||||||
|
@ -400,21 +400,21 @@ class Session {
|
||||||
setTimeout(() => {
|
setTimeout(() => {
|
||||||
process.send!({
|
process.send!({
|
||||||
type: 'put',
|
type: 'put',
|
||||||
pos
|
pos,
|
||||||
});
|
});
|
||||||
}, 500);
|
}, 500);
|
||||||
}
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 対局が始まったことをMisskeyに投稿します
|
* 対局が始まったことをMisskeyに投稿します
|
||||||
*/
|
*/
|
||||||
private postGameStarted = async () => {
|
private postGameStarted = async () => {
|
||||||
const text = this.isSettai
|
const text = this.isSettai ?
|
||||||
? serifs.reversi.startedSettai(this.userName)
|
serifs.reversi.startedSettai(this.userName) :
|
||||||
: serifs.reversi.started(this.userName, this.strength.toString());
|
serifs.reversi.started(this.userName, this.strength.toString());
|
||||||
|
|
||||||
return await this.post(`${text}\n→[観戦する](${this.url})`);
|
return await this.post(`${text}\n→[観戦する](${this.url})`);
|
||||||
}
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Misskeyに投稿します
|
* Misskeyに投稿します
|
||||||
|
@ -425,7 +425,7 @@ class Session {
|
||||||
const body = {
|
const body = {
|
||||||
i: config.i,
|
i: config.i,
|
||||||
text: text,
|
text: text,
|
||||||
visibility: 'home'
|
visibility: 'home',
|
||||||
} as any;
|
} as any;
|
||||||
|
|
||||||
if (renote) {
|
if (renote) {
|
||||||
|
@ -434,7 +434,7 @@ class Session {
|
||||||
|
|
||||||
try {
|
try {
|
||||||
const res = await request.post(`${config.host}/api/notes/create`, {
|
const res = await request.post(`${config.host}/api/notes/create`, {
|
||||||
json: body
|
json: body,
|
||||||
});
|
});
|
||||||
|
|
||||||
return res.createdNote;
|
return res.createdNote;
|
||||||
|
@ -445,7 +445,7 @@ class Session {
|
||||||
} else {
|
} else {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
}
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
new Session();
|
new Session();
|
||||||
|
|
|
@ -22,24 +22,24 @@ export default class extends Module {
|
||||||
this.reversiConnection = this.ai.connection.useSharedConnection('gamesReversi');
|
this.reversiConnection = this.ai.connection.useSharedConnection('gamesReversi');
|
||||||
|
|
||||||
// 招待されたとき
|
// 招待されたとき
|
||||||
this.reversiConnection.on('invited', msg => this.onReversiInviteMe(msg.parent));
|
this.reversiConnection.on('invited', (msg) => this.onReversiInviteMe(msg.parent));
|
||||||
|
|
||||||
// マッチしたとき
|
// マッチしたとき
|
||||||
this.reversiConnection.on('matched', msg => this.onReversiGameStart(msg));
|
this.reversiConnection.on('matched', (msg) => this.onReversiGameStart(msg));
|
||||||
|
|
||||||
if (config.reversiEnabled) {
|
if (config.reversiEnabled) {
|
||||||
const mainStream = this.ai.connection.useSharedConnection('main');
|
const mainStream = this.ai.connection.useSharedConnection('main');
|
||||||
mainStream.on('pageEvent', msg => {
|
mainStream.on('pageEvent', (msg) => {
|
||||||
if (msg.event === 'inviteReversi') {
|
if (msg.event === 'inviteReversi') {
|
||||||
this.ai.api('games/reversi/match', {
|
this.ai.api('games/reversi/match', {
|
||||||
userId: msg.user.id
|
userId: msg.user.id,
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
return {
|
return {
|
||||||
mentionHook: this.mentionHook
|
mentionHook: this.mentionHook,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -50,7 +50,7 @@ export default class extends Module {
|
||||||
msg.reply(serifs.reversi.ok);
|
msg.reply(serifs.reversi.ok);
|
||||||
|
|
||||||
this.ai.api('games/reversi/match', {
|
this.ai.api('games/reversi/match', {
|
||||||
userId: msg.userId
|
userId: msg.userId,
|
||||||
});
|
});
|
||||||
} else {
|
} else {
|
||||||
msg.reply(serifs.reversi.decline);
|
msg.reply(serifs.reversi.decline);
|
||||||
|
@ -69,7 +69,7 @@ export default class extends Module {
|
||||||
if (config.reversiEnabled) {
|
if (config.reversiEnabled) {
|
||||||
// 承認
|
// 承認
|
||||||
const game = await this.ai.api('games/reversi/match', {
|
const game = await this.ai.api('games/reversi/match', {
|
||||||
userId: inviter.id
|
userId: inviter.id,
|
||||||
});
|
});
|
||||||
|
|
||||||
this.onReversiGameStart(game);
|
this.onReversiGameStart(game);
|
||||||
|
@ -84,7 +84,7 @@ export default class extends Module {
|
||||||
|
|
||||||
// ゲームストリームに接続
|
// ゲームストリームに接続
|
||||||
const gw = this.ai.connection.connectToChannel('gamesReversiGame', {
|
const gw = this.ai.connection.connectToChannel('gamesReversiGame', {
|
||||||
gameId: game.id
|
gameId: game.id,
|
||||||
});
|
});
|
||||||
|
|
||||||
// フォーム
|
// フォーム
|
||||||
|
@ -92,7 +92,7 @@ export default class extends Module {
|
||||||
id: 'publish',
|
id: 'publish',
|
||||||
type: 'switch',
|
type: 'switch',
|
||||||
label: '藍が対局情報を投稿するのを許可',
|
label: '藍が対局情報を投稿するのを許可',
|
||||||
value: true
|
value: true,
|
||||||
}, {
|
}, {
|
||||||
id: 'strength',
|
id: 'strength',
|
||||||
type: 'radio',
|
type: 'radio',
|
||||||
|
@ -100,20 +100,20 @@ export default class extends Module {
|
||||||
value: 3,
|
value: 3,
|
||||||
items: [{
|
items: [{
|
||||||
label: '接待',
|
label: '接待',
|
||||||
value: 0
|
value: 0,
|
||||||
}, {
|
}, {
|
||||||
label: '弱',
|
label: '弱',
|
||||||
value: 2
|
value: 2,
|
||||||
}, {
|
}, {
|
||||||
label: '中',
|
label: '中',
|
||||||
value: 3
|
value: 3,
|
||||||
}, {
|
}, {
|
||||||
label: '強',
|
label: '強',
|
||||||
value: 4
|
value: 4,
|
||||||
}, {
|
}, {
|
||||||
label: '最強',
|
label: '最強',
|
||||||
value: 5
|
value: 5,
|
||||||
}]
|
}],
|
||||||
}];
|
}];
|
||||||
|
|
||||||
// #region バックエンドプロセス開始
|
// #region バックエンドプロセス開始
|
||||||
|
@ -125,14 +125,14 @@ export default class extends Module {
|
||||||
body: {
|
body: {
|
||||||
game: game,
|
game: game,
|
||||||
form: form,
|
form: form,
|
||||||
account: this.ai.account
|
account: this.ai.account,
|
||||||
}
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
ai.on('message', (msg: Record<string, any>) => {
|
ai.on('message', (msg: Record<string, any>) => {
|
||||||
if (msg.type == 'put') {
|
if (msg.type == 'put') {
|
||||||
gw.send('set', {
|
gw.send('set', {
|
||||||
pos: msg.pos
|
pos: msg.pos,
|
||||||
});
|
});
|
||||||
} else if (msg.type == 'ended') {
|
} else if (msg.type == 'ended') {
|
||||||
gw.dispose();
|
gw.dispose();
|
||||||
|
@ -142,7 +142,7 @@ export default class extends Module {
|
||||||
});
|
});
|
||||||
|
|
||||||
// ゲームストリームから情報が流れてきたらそのままバックエンドプロセスに伝える
|
// ゲームストリームから情報が流れてきたらそのままバックエンドプロセスに伝える
|
||||||
gw.addListener('*', message => {
|
gw.addListener('*', (message) => {
|
||||||
ai.send(message);
|
ai.send(message);
|
||||||
});
|
});
|
||||||
// #endregion
|
// #endregion
|
||||||
|
|
|
@ -39,7 +39,7 @@ export default class extends Module {
|
||||||
private check() {
|
private check() {
|
||||||
const average = (arr) => arr.reduce((a, b) => a + b) / arr.length;
|
const average = (arr) => arr.reduce((a, b) => a + b) / arr.length;
|
||||||
|
|
||||||
const cpuPercentages = this.statsLogs.map(s => s && (s.cpu_usage || s.cpu) * 100 || 0);
|
const cpuPercentages = this.statsLogs.map((s) => s && (s.cpu_usage || s.cpu) * 100 || 0);
|
||||||
const cpuPercentage = average(cpuPercentages);
|
const cpuPercentage = average(cpuPercentages);
|
||||||
if (cpuPercentage >= 70) {
|
if (cpuPercentage >= 70) {
|
||||||
this.warn();
|
this.warn();
|
||||||
|
@ -71,9 +71,9 @@ export default class extends Module {
|
||||||
// #endregion
|
// #endregion
|
||||||
|
|
||||||
this.ai.post({
|
this.ai.post({
|
||||||
visibility: "home",
|
visibility: 'home',
|
||||||
localOnly: true,
|
localOnly: true,
|
||||||
text: serifs.server.cpu
|
text: serifs.server.cpu,
|
||||||
});
|
});
|
||||||
|
|
||||||
this.warned = true;
|
this.warned = true;
|
||||||
|
|
|
@ -24,11 +24,11 @@ export default class extends Module {
|
||||||
|
|
||||||
if (sleepHours >= 1) {
|
if (sleepHours >= 1) {
|
||||||
this.ai.post({
|
this.ai.post({
|
||||||
text: serifs.sleepReport.report(Math.round(sleepHours))
|
text: serifs.sleepReport.report(Math.round(sleepHours)),
|
||||||
});
|
});
|
||||||
} else {
|
} else {
|
||||||
this.ai.post({
|
this.ai.post({
|
||||||
text: serifs.sleepReport.reportUtatane
|
text: serifs.sleepReport.reportUtatane,
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -10,16 +10,16 @@ export default class extends Module {
|
||||||
@autobind
|
@autobind
|
||||||
public install() {
|
public install() {
|
||||||
return {
|
return {
|
||||||
mentionHook: this.mentionHook
|
mentionHook: this.mentionHook,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
@autobind
|
@autobind
|
||||||
private async mentionHook(msg: Message) {
|
private async mentionHook(msg: Message) {
|
||||||
// cat/Cat/ねこ/ネコ/にゃん
|
// cat/Cat/ねこ/ネコ/にゃん
|
||||||
console.log(msg.text)
|
console.log(msg.text);
|
||||||
if (msg.text && (msg.text.match(/(cat|Cat|ねこ|ネコ|にゃ[〜|ー]*ん)/g))) {
|
if (msg.text && (msg.text.match(/(cat|Cat|ねこ|ネコ|にゃ[〜|ー]*ん)/g))) {
|
||||||
const message = "にゃ~ん!";
|
const message = 'にゃ~ん!';
|
||||||
|
|
||||||
const file = await this.getCatImage();
|
const file = await this.getCatImage();
|
||||||
this.log(file);
|
this.log(file);
|
||||||
|
@ -27,7 +27,7 @@ export default class extends Module {
|
||||||
msg.reply(message, {file});
|
msg.reply(message, {file});
|
||||||
|
|
||||||
return {
|
return {
|
||||||
reaction: ':blobcatmeltnomblobcatmelt:'
|
reaction: ':blobcatmeltnomblobcatmelt:',
|
||||||
};
|
};
|
||||||
} else {
|
} else {
|
||||||
return false;
|
return false;
|
||||||
|
|
|
@ -87,9 +87,9 @@ export default class extends Module {
|
||||||
|
|
||||||
if (msg.includes(['行ってくる', '行ってきます', 'いってくる', 'いってきます'])) {
|
if (msg.includes(['行ってくる', '行ってきます', 'いってくる', 'いってきます'])) {
|
||||||
msg.reply(
|
msg.reply(
|
||||||
msg.friend.love >= 7
|
msg.friend.love >= 7 ?
|
||||||
? serifs.core.itterassyai.love(msg.friend.name)
|
serifs.core.itterassyai.love(msg.friend.name) :
|
||||||
: serifs.core.itterassyai.normal(msg.friend.name));
|
serifs.core.itterassyai.normal(msg.friend.name));
|
||||||
incLove();
|
incLove();
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
@ -171,7 +171,7 @@ export default class extends Module {
|
||||||
msg.friend.love <= -10 ? serifs.core.nadenade.hate3 :
|
msg.friend.love <= -10 ? serifs.core.nadenade.hate3 :
|
||||||
msg.friend.love <= -5 ? serifs.core.nadenade.hate2 :
|
msg.friend.love <= -5 ? serifs.core.nadenade.hate2 :
|
||||||
msg.friend.love <= -1 ? serifs.core.nadenade.hate1 :
|
msg.friend.love <= -1 ? serifs.core.nadenade.hate1 :
|
||||||
serifs.core.nadenade.normal
|
serifs.core.nadenade.normal,
|
||||||
));
|
));
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
|
@ -305,7 +305,7 @@ export default class extends Module {
|
||||||
msg.friend.decLove();
|
msg.friend.decLove();
|
||||||
|
|
||||||
return {
|
return {
|
||||||
reaction: 'angry'
|
reaction: 'angry',
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -316,7 +316,7 @@ export default class extends Module {
|
||||||
msg.friend.decLove();
|
msg.friend.decLove();
|
||||||
|
|
||||||
return {
|
return {
|
||||||
reaction: 'angry'
|
reaction: 'angry',
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -327,7 +327,7 @@ export default class extends Module {
|
||||||
msg.reply(serifs.core.shutdown);
|
msg.reply(serifs.core.shutdown);
|
||||||
|
|
||||||
return {
|
return {
|
||||||
reaction: 'confused'
|
reaction: 'confused',
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -50,7 +50,7 @@ export default class extends Module {
|
||||||
isDm: msg.isDm,
|
isDm: msg.isDm,
|
||||||
msgId: msg.id,
|
msgId: msg.id,
|
||||||
userId: msg.friend.userId,
|
userId: msg.friend.userId,
|
||||||
time: str
|
time: str,
|
||||||
});
|
});
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
|
@ -63,12 +63,12 @@ export default class extends Module {
|
||||||
const text = serifs.timer.notify(data.time, friend.name);
|
const text = serifs.timer.notify(data.time, friend.name);
|
||||||
if (data.isDm) {
|
if (data.isDm) {
|
||||||
this.ai.sendMessage(friend.userId, {
|
this.ai.sendMessage(friend.userId, {
|
||||||
text: text
|
text: text,
|
||||||
});
|
});
|
||||||
} else {
|
} else {
|
||||||
this.ai.post({
|
this.ai.post({
|
||||||
replyId: data.msgId,
|
replyId: data.msgId,
|
||||||
text: text
|
text: text,
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -28,7 +28,7 @@ export default class extends Module {
|
||||||
|
|
||||||
const friends = this.ai.friends.find({} as any);
|
const friends = this.ai.friends.find({} as any);
|
||||||
|
|
||||||
friends.forEach(f => {
|
friends.forEach((f) => {
|
||||||
const friend = new Friend(this.ai, {doc: f});
|
const friend = new Friend(this.ai, {doc: f});
|
||||||
|
|
||||||
// 親愛度が5以上必要
|
// 親愛度が5以上必要
|
||||||
|
@ -44,7 +44,7 @@ export default class extends Module {
|
||||||
const text = serifs.valentine.chocolateForYou(friend.name);
|
const text = serifs.valentine.chocolateForYou(friend.name);
|
||||||
|
|
||||||
this.ai.sendMessage(friend.userId, {
|
this.ai.sendMessage(friend.userId, {
|
||||||
text: text
|
text: text,
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
|
@ -18,14 +18,14 @@ export default class extends Module {
|
||||||
if (note.isFirstNote) {
|
if (note.isFirstNote) {
|
||||||
setTimeout(() => {
|
setTimeout(() => {
|
||||||
this.ai.api('notes/create', {
|
this.ai.api('notes/create', {
|
||||||
renoteId: note.id
|
renoteId: note.id,
|
||||||
});
|
});
|
||||||
}, 3000);
|
}, 3000);
|
||||||
|
|
||||||
setTimeout(() => {
|
setTimeout(() => {
|
||||||
this.ai.api('notes/reactions/create', {
|
this.ai.api('notes/reactions/create', {
|
||||||
noteId: note.id,
|
noteId: note.id,
|
||||||
reaction: 'congrats'
|
reaction: 'congrats',
|
||||||
});
|
});
|
||||||
}, 5000);
|
}, 5000);
|
||||||
}
|
}
|
||||||
|
|
118
src/serifs.ts
118
src/serifs.ts
|
@ -2,15 +2,15 @@
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
core: {
|
core: {
|
||||||
setNameOk: name => `わかりました。これからは${name}とお呼びしますね!`,
|
setNameOk: (name) => `わかりました。これからは${name}とお呼びしますね!`,
|
||||||
|
|
||||||
san: 'さん付けした方がいいですか?',
|
san: 'さん付けした方がいいですか?',
|
||||||
|
|
||||||
yesOrNo: '「はい」か「いいえ」しかわからないんです...',
|
yesOrNo: '「はい」か「いいえ」しかわからないんです...',
|
||||||
|
|
||||||
hello: name => name ? `こんにちは、${name}♪` : `こんにちは♪`,
|
hello: (name) => name ? `こんにちは、${name}♪` : `こんにちは♪`,
|
||||||
|
|
||||||
helloNight: name => name ? `こんばんは、${name}♪` : `こんばんは♪`,
|
helloNight: (name) => name ? `こんばんは、${name}♪` : `こんばんは♪`,
|
||||||
|
|
||||||
goodMorning: (tension, name) => name ? `おはようございます、${name}!${tension}` : `おはようございます!${tension}`,
|
goodMorning: (tension, name) => name ? `おはようございます、${name}!${tension}` : `おはようございます!${tension}`,
|
||||||
|
|
||||||
|
@ -22,54 +22,54 @@ export default {
|
||||||
},
|
},
|
||||||
*/
|
*/
|
||||||
|
|
||||||
goodNight: name => name ? `おやすみなさい、${name}!` : 'おやすみなさい!',
|
goodNight: (name) => name ? `おやすみなさい、${name}!` : 'おやすみなさい!',
|
||||||
|
|
||||||
omedeto: name => name ? `ありがとうございます、${name}♪` : 'ありがとうございます♪',
|
omedeto: (name) => name ? `ありがとうございます、${name}♪` : 'ありがとうございます♪',
|
||||||
|
|
||||||
erait: {
|
erait: {
|
||||||
general: name => name ? [
|
general: (name) => name ? [
|
||||||
`${name}、今日もえらいです!`,
|
`${name}、今日もえらいです!`,
|
||||||
`${name}、今日もえらいですよ~♪`
|
`${name}、今日もえらいですよ~♪`,
|
||||||
] : [
|
] : [
|
||||||
`今日もえらいです!`,
|
`今日もえらいです!`,
|
||||||
`今日もえらいですよ~♪`
|
`今日もえらいですよ~♪`,
|
||||||
],
|
],
|
||||||
|
|
||||||
specify: (thing, name) => name ? [
|
specify: (thing, name) => name ? [
|
||||||
`${name}、${thing}てえらいです!`,
|
`${name}、${thing}てえらいです!`,
|
||||||
`${name}、${thing}てえらいですよ~♪`
|
`${name}、${thing}てえらいですよ~♪`,
|
||||||
] : [
|
] : [
|
||||||
`${thing}てえらいです!`,
|
`${thing}てえらいです!`,
|
||||||
`${thing}てえらいですよ~♪`
|
`${thing}てえらいですよ~♪`,
|
||||||
],
|
],
|
||||||
|
|
||||||
specify2: (thing, name) => name ? [
|
specify2: (thing, name) => name ? [
|
||||||
`${name}、${thing}でえらいです!`,
|
`${name}、${thing}でえらいです!`,
|
||||||
`${name}、${thing}でえらいですよ~♪`
|
`${name}、${thing}でえらいですよ~♪`,
|
||||||
] : [
|
] : [
|
||||||
`${thing}でえらいです!`,
|
`${thing}でえらいです!`,
|
||||||
`${thing}でえらいですよ~♪`
|
`${thing}でえらいですよ~♪`,
|
||||||
],
|
],
|
||||||
},
|
},
|
||||||
|
|
||||||
okaeri: {
|
okaeri: {
|
||||||
love: name => name ? [
|
love: (name) => name ? [
|
||||||
`おかえりなさい、${name}♪`,
|
`おかえりなさい、${name}♪`,
|
||||||
`おかえりなさいませっ、${name}っ。`
|
`おかえりなさいませっ、${name}っ。`,
|
||||||
] : [
|
] : [
|
||||||
'おかえりなさい♪',
|
'おかえりなさい♪',
|
||||||
'おかえりなさいませっ、ご主人様っ。'
|
'おかえりなさいませっ、ご主人様っ。',
|
||||||
],
|
],
|
||||||
|
|
||||||
love2: name => name ? `おかえりなさいませ♡♡♡${name}っっ♡♡♡♡♡` : 'おかえりなさいませ♡♡♡ご主人様っっ♡♡♡♡♡',
|
love2: (name) => name ? `おかえりなさいませ♡♡♡${name}っっ♡♡♡♡♡` : 'おかえりなさいませ♡♡♡ご主人様っっ♡♡♡♡♡',
|
||||||
|
|
||||||
normal: name => name ? `おかえりなさい、${name}!` : 'おかえりなさい!',
|
normal: (name) => name ? `おかえりなさい、${name}!` : 'おかえりなさい!',
|
||||||
},
|
},
|
||||||
|
|
||||||
itterassyai: {
|
itterassyai: {
|
||||||
love: name => name ? `いってらっしゃい、${name}♪` : 'いってらっしゃい♪',
|
love: (name) => name ? `いってらっしゃい、${name}♪` : 'いってらっしゃい♪',
|
||||||
|
|
||||||
normal: name => name ? `いってらっしゃい、${name}!` : 'いってらっしゃい!',
|
normal: (name) => name ? `いってらっしゃい、${name}!` : 'いってらっしゃい!',
|
||||||
},
|
},
|
||||||
|
|
||||||
tooLong: '長すぎる気がします...',
|
tooLong: '長すぎる気がします...',
|
||||||
|
@ -97,15 +97,15 @@ export default {
|
||||||
|
|
||||||
love: ['嬉しいです♪', '照れちゃいます...'],
|
love: ['嬉しいです♪', '照れちゃいます...'],
|
||||||
|
|
||||||
hate: '…ありがとうございます'
|
hate: '…ありがとうございます',
|
||||||
},
|
},
|
||||||
|
|
||||||
suki: {
|
suki: {
|
||||||
normal: 'えっ… ありがとうございます…♪',
|
normal: 'えっ… ありがとうございます…♪',
|
||||||
|
|
||||||
love: name => `私もその… ${name}のこと好きですよ!`,
|
love: (name) => `私もその… ${name}のこと好きですよ!`,
|
||||||
|
|
||||||
hate: null
|
hate: null,
|
||||||
},
|
},
|
||||||
|
|
||||||
hug: {
|
hug: {
|
||||||
|
@ -113,7 +113,7 @@ export default {
|
||||||
|
|
||||||
love: 'ぎゅーっ♪',
|
love: 'ぎゅーっ♪',
|
||||||
|
|
||||||
hate: '離れてください...'
|
hate: '離れてください...',
|
||||||
},
|
},
|
||||||
|
|
||||||
humu: {
|
humu: {
|
||||||
|
@ -121,7 +121,7 @@ export default {
|
||||||
|
|
||||||
normal: 'えぇ... それはちょっと...',
|
normal: 'えぇ... それはちょっと...',
|
||||||
|
|
||||||
hate: '……'
|
hate: '……',
|
||||||
},
|
},
|
||||||
|
|
||||||
batou: {
|
batou: {
|
||||||
|
@ -129,10 +129,10 @@ export default {
|
||||||
|
|
||||||
normal: '(じとー…)',
|
normal: '(じとー…)',
|
||||||
|
|
||||||
hate: '…頭大丈夫ですか?'
|
hate: '…頭大丈夫ですか?',
|
||||||
},
|
},
|
||||||
|
|
||||||
itai: name => name ? `${name}、大丈夫ですか…? いたいのいたいの飛んでけっ!` : '大丈夫ですか…? いたいのいたいの飛んでけっ!',
|
itai: (name) => name ? `${name}、大丈夫ですか…? いたいのいたいの飛んでけっ!` : '大丈夫ですか…? いたいのいたいの飛んでけっ!',
|
||||||
|
|
||||||
ote: {
|
ote: {
|
||||||
normal: 'くぅん... 私わんちゃんじゃないですよ...?',
|
normal: 'くぅん... 私わんちゃんじゃないですよ...?',
|
||||||
|
@ -146,25 +146,25 @@ export default {
|
||||||
|
|
||||||
transferNeedDm: 'わかりました、それはチャットで話しませんか?',
|
transferNeedDm: 'わかりました、それはチャットで話しませんか?',
|
||||||
|
|
||||||
transferCode: code => `わかりました。\n合言葉は「${code}」です!`,
|
transferCode: (code) => `わかりました。\n合言葉は「${code}」です!`,
|
||||||
|
|
||||||
transferFailed: 'うーん、合言葉が間違ってませんか...?',
|
transferFailed: 'うーん、合言葉が間違ってませんか...?',
|
||||||
|
|
||||||
transferDone: name => name ? `はっ...! おかえりなさい、${name}!` : `はっ...! おかえりなさい!`,
|
transferDone: (name) => name ? `はっ...! おかえりなさい、${name}!` : `はっ...! おかえりなさい!`,
|
||||||
},
|
},
|
||||||
|
|
||||||
keyword: {
|
keyword: {
|
||||||
learned: (word, reading) => `(${word}..... ${reading}..... 覚えました)`,
|
learned: (word, reading) => `(${word}..... ${reading}..... 覚えました)`,
|
||||||
|
|
||||||
remembered: (word) => `${word}`
|
remembered: (word) => `${word}`,
|
||||||
},
|
},
|
||||||
|
|
||||||
dice: {
|
dice: {
|
||||||
done: res => `${res} です!`
|
done: (res) => `${res} です!`,
|
||||||
},
|
},
|
||||||
|
|
||||||
birthday: {
|
birthday: {
|
||||||
happyBirthday: name => name ? `お誕生日おめでとうございます、${name}🎉` : 'お誕生日おめでとうございます🎉',
|
happyBirthday: (name) => name ? `お誕生日おめでとうございます、${name}🎉` : 'お誕生日おめでとうございます🎉',
|
||||||
},
|
},
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -189,47 +189,47 @@ export default {
|
||||||
/**
|
/**
|
||||||
* 接待開始
|
* 接待開始
|
||||||
*/
|
*/
|
||||||
startedSettai: name => `(${name}の接待を始めました)`,
|
startedSettai: (name) => `(${name}の接待を始めました)`,
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 勝ったとき
|
* 勝ったとき
|
||||||
*/
|
*/
|
||||||
iWon: name => `${name}に勝ちました♪`,
|
iWon: (name) => `${name}に勝ちました♪`,
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 接待のつもりが勝ってしまったとき
|
* 接待のつもりが勝ってしまったとき
|
||||||
*/
|
*/
|
||||||
iWonButSettai: name => `(${name}に接待で勝っちゃいました...)`,
|
iWonButSettai: (name) => `(${name}に接待で勝っちゃいました...)`,
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 負けたとき
|
* 負けたとき
|
||||||
*/
|
*/
|
||||||
iLose: name => `${name}に負けました...`,
|
iLose: (name) => `${name}に負けました...`,
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 接待で負けてあげたとき
|
* 接待で負けてあげたとき
|
||||||
*/
|
*/
|
||||||
iLoseButSettai: name => `(${name}に接待で負けてあげました...♪)`,
|
iLoseButSettai: (name) => `(${name}に接待で負けてあげました...♪)`,
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 引き分けたとき
|
* 引き分けたとき
|
||||||
*/
|
*/
|
||||||
drawn: name => `${name}と引き分けました~`,
|
drawn: (name) => `${name}と引き分けました~`,
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 接待で引き分けたとき
|
* 接待で引き分けたとき
|
||||||
*/
|
*/
|
||||||
drawnSettai: name => `(${name}に接待で引き分けました...)`,
|
drawnSettai: (name) => `(${name}に接待で引き分けました...)`,
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 相手が投了したとき
|
* 相手が投了したとき
|
||||||
*/
|
*/
|
||||||
youSurrendered: name => `${name}が投了しちゃいました`,
|
youSurrendered: (name) => `${name}が投了しちゃいました`,
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 接待してたら相手が投了したとき
|
* 接待してたら相手が投了したとき
|
||||||
*/
|
*/
|
||||||
settaiButYouSurrendered: name => `(${name}を接待していたら投了されちゃいました... ごめんなさい)`,
|
settaiButYouSurrendered: (name) => `(${name}を接待していたら投了されちゃいました... ごめんなさい)`,
|
||||||
},
|
},
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -264,27 +264,27 @@ export default {
|
||||||
/**
|
/**
|
||||||
* 小さい数を言われたとき
|
* 小さい数を言われたとき
|
||||||
*/
|
*/
|
||||||
grater: num => `${num}より大きいですね`,
|
grater: (num) => `${num}より大きいですね`,
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 小さい数を言われたとき(2度目)
|
* 小さい数を言われたとき(2度目)
|
||||||
*/
|
*/
|
||||||
graterAgain: num => `もう一度言いますが${num}より大きいですよ!`,
|
graterAgain: (num) => `もう一度言いますが${num}より大きいですよ!`,
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 大きい数を言われたとき
|
* 大きい数を言われたとき
|
||||||
*/
|
*/
|
||||||
less: num => `${num}より小さいですね`,
|
less: (num) => `${num}より小さいですね`,
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 大きい数を言われたとき(2度目)
|
* 大きい数を言われたとき(2度目)
|
||||||
*/
|
*/
|
||||||
lessAgain: num => `もう一度言いますが${num}より小さいですよ!`,
|
lessAgain: (num) => `もう一度言いますが${num}より小さいですよ!`,
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 正解したとき
|
* 正解したとき
|
||||||
*/
|
*/
|
||||||
congrats: tries => `正解です🎉 (${tries}回目で当てました)`,
|
congrats: (tries) => `正解です🎉 (${tries}回目で当てました)`,
|
||||||
},
|
},
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -295,7 +295,7 @@ export default {
|
||||||
|
|
||||||
matakondo: 'また今度やりましょう!',
|
matakondo: 'また今度やりましょう!',
|
||||||
|
|
||||||
intro: minutes => `みなさん、数取りゲームしましょう!\n0~100の中で最も大きい数字を取った人が勝ちです。他の人と被ったらだめですよ~\n制限時間は${minutes}分です。数字はこの投稿にリプライで送ってくださいね!`,
|
intro: (minutes) => `みなさん、数取りゲームしましょう!\n0~100の中で最も大きい数字を取った人が勝ちです。他の人と被ったらだめですよ~\n制限時間は${minutes}分です。数字はこの投稿にリプライで送ってくださいね!`,
|
||||||
|
|
||||||
finish: 'ゲームの結果発表です!',
|
finish: 'ゲームの結果発表です!',
|
||||||
|
|
||||||
|
@ -303,21 +303,21 @@ export default {
|
||||||
|
|
||||||
finishWithNoWinner: '今回は勝者はいませんでした... またやりましょう♪',
|
finishWithNoWinner: '今回は勝者はいませんでした... またやりましょう♪',
|
||||||
|
|
||||||
onagare: '参加者が集まらなかったのでお流れになりました...'
|
onagare: '参加者が集まらなかったのでお流れになりました...',
|
||||||
},
|
},
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 絵文字生成
|
* 絵文字生成
|
||||||
*/
|
*/
|
||||||
emoji: {
|
emoji: {
|
||||||
suggest: emoji => `こんなのはどうですか?→${emoji}`,
|
suggest: (emoji) => `こんなのはどうですか?→${emoji}`,
|
||||||
},
|
},
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 占い
|
* 占い
|
||||||
*/
|
*/
|
||||||
fortune: {
|
fortune: {
|
||||||
cw: name => name ? `私が今日の${name}の運勢を占いました...` : '私が今日のあなたの運勢を占いました...',
|
cw: (name) => name ? `私が今日の${name}の運勢を占いました...` : '私が今日のあなたの運勢を占いました...',
|
||||||
},
|
},
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -330,7 +330,7 @@ export default {
|
||||||
|
|
||||||
tooLong: '長すぎます…',
|
tooLong: '長すぎます…',
|
||||||
|
|
||||||
notify: (time, name) => name ? `${name}、${time}経ちましたよ!` : `${time}経ちましたよ!`
|
notify: (time, name) => name ? `${name}、${time}経ちましたよ!` : `${time}経ちましたよ!`,
|
||||||
},
|
},
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -341,7 +341,7 @@ export default {
|
||||||
|
|
||||||
doneFromInvalidUser: 'イタズラはめっですよ!',
|
doneFromInvalidUser: 'イタズラはめっですよ!',
|
||||||
|
|
||||||
invalidVisibility: "公開範囲の指定を変えてみて",
|
invalidVisibility: '公開範囲の指定を変えてみて',
|
||||||
|
|
||||||
reminds: 'やること一覧です!',
|
reminds: 'やること一覧です!',
|
||||||
|
|
||||||
|
@ -366,25 +366,25 @@ export default {
|
||||||
* バレンタイン
|
* バレンタイン
|
||||||
*/
|
*/
|
||||||
valentine: {
|
valentine: {
|
||||||
chocolateForYou: name => name ? `${name}、その... チョコレート作ったのでよかったらどうぞ!🍫` : 'チョコレート作ったのでよかったらどうぞ!🍫',
|
chocolateForYou: (name) => name ? `${name}、その... チョコレート作ったのでよかったらどうぞ!🍫` : 'チョコレート作ったのでよかったらどうぞ!🍫',
|
||||||
},
|
},
|
||||||
|
|
||||||
server: {
|
server: {
|
||||||
cpu: 'サーバーの負荷が高そうです。大丈夫でしょうか...?'
|
cpu: 'サーバーの負荷が高そうです。大丈夫でしょうか...?',
|
||||||
},
|
},
|
||||||
|
|
||||||
maze: {
|
maze: {
|
||||||
post: '今日の迷路です! #2na2Maze',
|
post: '今日の迷路です! #2na2Maze',
|
||||||
foryou: '描きました!'
|
foryou: '描きました!',
|
||||||
},
|
},
|
||||||
|
|
||||||
chart: {
|
chart: {
|
||||||
post: 'インスタンスの投稿数です!',
|
post: 'インスタンスの投稿数です!',
|
||||||
foryou: '描きました!'
|
foryou: '描きました!',
|
||||||
},
|
},
|
||||||
|
|
||||||
sleepReport: {
|
sleepReport: {
|
||||||
report: hours => `んぅ、${hours}時間くらい寝ちゃってたみたいです`,
|
report: (hours) => `んぅ、${hours}時間くらい寝ちゃってたみたいです`,
|
||||||
reportUtatane: 'ん... うたた寝しちゃってました',
|
reportUtatane: 'ん... うたた寝しちゃってました',
|
||||||
},
|
},
|
||||||
|
|
||||||
|
@ -466,9 +466,9 @@ export default {
|
||||||
'じー',
|
'じー',
|
||||||
'はにゃ?',
|
'はにゃ?',
|
||||||
],
|
],
|
||||||
want: item => `${item}、欲しいなぁ...`,
|
want: (item) => `${item}、欲しいなぁ...`,
|
||||||
see: item => `お散歩していたら、道に${item}が落ちているのを見たんです!`,
|
see: (item) => `お散歩していたら、道に${item}が落ちているのを見たんです!`,
|
||||||
expire: item => `気づいたら、${item}の賞味期限が切れてました…`,
|
expire: (item) => `気づいたら、${item}の賞味期限が切れてました…`,
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -22,7 +22,7 @@ export default class Stream extends EventEmitter {
|
||||||
this.buffer = [];
|
this.buffer = [];
|
||||||
|
|
||||||
this.stream = new ReconnectingWebsocket(`${config.wsUrl}/streaming?i=${config.i}`, [], {
|
this.stream = new ReconnectingWebsocket(`${config.wsUrl}/streaming?i=${config.i}`, [], {
|
||||||
WebSocket: WebSocket
|
WebSocket: WebSocket,
|
||||||
});
|
});
|
||||||
this.stream.addEventListener('open', this.onOpen);
|
this.stream.addEventListener('open', this.onOpen);
|
||||||
this.stream.addEventListener('close', this.onClose);
|
this.stream.addEventListener('close', this.onClose);
|
||||||
|
@ -31,7 +31,7 @@ export default class Stream extends EventEmitter {
|
||||||
|
|
||||||
@autobind
|
@autobind
|
||||||
public useSharedConnection(channel: string): SharedConnection {
|
public useSharedConnection(channel: string): SharedConnection {
|
||||||
let pool = this.sharedConnectionPools.find(p => p.channel === channel);
|
let pool = this.sharedConnectionPools.find((p) => p.channel === channel);
|
||||||
|
|
||||||
if (pool == null) {
|
if (pool == null) {
|
||||||
pool = new Pool(this, channel);
|
pool = new Pool(this, channel);
|
||||||
|
@ -45,7 +45,7 @@ export default class Stream extends EventEmitter {
|
||||||
|
|
||||||
@autobind
|
@autobind
|
||||||
public removeSharedConnection(connection: SharedConnection) {
|
public removeSharedConnection(connection: SharedConnection) {
|
||||||
this.sharedConnections = this.sharedConnections.filter(c => c !== connection);
|
this.sharedConnections = this.sharedConnections.filter((c) => c !== connection);
|
||||||
}
|
}
|
||||||
|
|
||||||
@autobind
|
@autobind
|
||||||
|
@ -57,7 +57,7 @@ export default class Stream extends EventEmitter {
|
||||||
|
|
||||||
@autobind
|
@autobind
|
||||||
public disconnectToChannel(connection: NonSharedConnection) {
|
public disconnectToChannel(connection: NonSharedConnection) {
|
||||||
this.nonSharedConnections = this.nonSharedConnections.filter(c => c !== connection);
|
this.nonSharedConnections = this.nonSharedConnections.filter((c) => c !== connection);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -79,10 +79,10 @@ export default class Stream extends EventEmitter {
|
||||||
|
|
||||||
// チャンネル再接続
|
// チャンネル再接続
|
||||||
if (isReconnect) {
|
if (isReconnect) {
|
||||||
this.sharedConnectionPools.forEach(p => {
|
this.sharedConnectionPools.forEach((p) => {
|
||||||
p.connect();
|
p.connect();
|
||||||
});
|
});
|
||||||
this.nonSharedConnections.forEach(c => {
|
this.nonSharedConnections.forEach((c) => {
|
||||||
c.connect();
|
c.connect();
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
@ -109,13 +109,13 @@ export default class Stream extends EventEmitter {
|
||||||
|
|
||||||
let connections: (Connection | undefined)[];
|
let connections: (Connection | undefined)[];
|
||||||
|
|
||||||
connections = this.sharedConnections.filter(c => c.id === id);
|
connections = this.sharedConnections.filter((c) => c.id === id);
|
||||||
|
|
||||||
if (connections.length === 0) {
|
if (connections.length === 0) {
|
||||||
connections = [this.nonSharedConnections.find(c => c.id === id)];
|
connections = [this.nonSharedConnections.find((c) => c.id === id)];
|
||||||
}
|
}
|
||||||
|
|
||||||
for (const c of connections.filter(c => c != null)) {
|
for (const c of connections.filter((c) => c != null)) {
|
||||||
c!.emit(body.type, body.body);
|
c!.emit(body.type, body.body);
|
||||||
c!.emit('*', {type: body.type, body: body.body});
|
c!.emit('*', {type: body.type, body: body.body});
|
||||||
}
|
}
|
||||||
|
@ -132,7 +132,7 @@ export default class Stream extends EventEmitter {
|
||||||
public send(typeOrPayload, payload?) {
|
public send(typeOrPayload, payload?) {
|
||||||
const data = payload === undefined ? typeOrPayload : {
|
const data = payload === undefined ? typeOrPayload : {
|
||||||
type: typeOrPayload,
|
type: typeOrPayload,
|
||||||
body: payload
|
body: payload,
|
||||||
};
|
};
|
||||||
|
|
||||||
// まだ接続が確立されていなかったらバッファリングして次に接続した時に送信する
|
// まだ接続が確立されていなかったらバッファリングして次に接続した時に送信する
|
||||||
|
@ -203,7 +203,7 @@ class Pool {
|
||||||
this.isConnected = true;
|
this.isConnected = true;
|
||||||
this.stream.send('connect', {
|
this.stream.send('connect', {
|
||||||
channel: this.channel,
|
channel: this.channel,
|
||||||
id: this.id
|
id: this.id,
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -235,7 +235,7 @@ abstract class Connection extends EventEmitter {
|
||||||
this.stream.send('ch', {
|
this.stream.send('ch', {
|
||||||
id: id,
|
id: id,
|
||||||
type: type,
|
type: type,
|
||||||
body: body
|
body: body,
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -287,7 +287,7 @@ class NonSharedConnection extends Connection {
|
||||||
this.stream.send('connect', {
|
this.stream.send('connect', {
|
||||||
channel: this.channel,
|
channel: this.channel,
|
||||||
id: this.id,
|
id: this.id,
|
||||||
params: this.params
|
params: this.params,
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
export function acct(user: { username: string; host?: string | null; }): string {
|
export function acct(user: { username: string; host?: string | null; }): string {
|
||||||
return user.host
|
return user.host ?
|
||||||
? `@${user.username}@${user.host}`
|
`@${user.username}@${user.host}` :
|
||||||
: `@${user.username}`;
|
`@${user.username}`;
|
||||||
}
|
}
|
||||||
|
|
|
@ -4,7 +4,7 @@ export default function(text: string, words: string[]): boolean {
|
||||||
if (text == null) return false;
|
if (text == null) return false;
|
||||||
|
|
||||||
text = katakanaToHiragana(hankakuToZenkaku(text)).toLowerCase();
|
text = katakanaToHiragana(hankakuToZenkaku(text)).toLowerCase();
|
||||||
words = words.map(word => katakanaToHiragana(word).toLowerCase());
|
words = words.map((word) => katakanaToHiragana(word).toLowerCase());
|
||||||
|
|
||||||
return words.some(word => text.includes(word));
|
return words.some((word) => text.includes(word));
|
||||||
}
|
}
|
||||||
|
|
|
@ -19,16 +19,16 @@ const kanaMap: string[][] = [
|
||||||
['ワ', 'ワ'], ['ヲ', 'ヲ'], ['ン', 'ン'],
|
['ワ', 'ワ'], ['ヲ', 'ヲ'], ['ン', 'ン'],
|
||||||
['ァ', 'ァ'], ['ィ', 'ィ'], ['ゥ', 'ゥ'], ['ェ', 'ェ'], ['ォ', 'ォ'],
|
['ァ', 'ァ'], ['ィ', 'ィ'], ['ゥ', 'ゥ'], ['ェ', 'ェ'], ['ォ', 'ォ'],
|
||||||
['ッ', 'ッ'], ['ャ', 'ャ'], ['ュ', 'ュ'], ['ョ', 'ョ'],
|
['ッ', 'ッ'], ['ャ', 'ャ'], ['ュ', 'ュ'], ['ョ', 'ョ'],
|
||||||
['ー', 'ー']
|
['ー', 'ー'],
|
||||||
];
|
];
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* カタカナをひらがなに変換します
|
* カタカナをひらがなに変換します
|
||||||
* @param str カタカナ
|
* @param str カタカナ
|
||||||
* @returns ひらがな
|
* @return ひらがな
|
||||||
*/
|
*/
|
||||||
export function katakanaToHiragana(str: string): string {
|
export function katakanaToHiragana(str: string): string {
|
||||||
return str.replace(/[\u30a1-\u30f6]/g, match => {
|
return str.replace(/[\u30a1-\u30f6]/g, (match) => {
|
||||||
const char = match.charCodeAt(0) - 0x60;
|
const char = match.charCodeAt(0) - 0x60;
|
||||||
return String.fromCharCode(char);
|
return String.fromCharCode(char);
|
||||||
});
|
});
|
||||||
|
@ -37,10 +37,10 @@ export function katakanaToHiragana(str: string): string {
|
||||||
/**
|
/**
|
||||||
* ひらがなをカタカナに変換します
|
* ひらがなをカタカナに変換します
|
||||||
* @param str ひらがな
|
* @param str ひらがな
|
||||||
* @returns カタカナ
|
* @return カタカナ
|
||||||
*/
|
*/
|
||||||
export function hiraganaToKatagana(str: string): string {
|
export function hiraganaToKatagana(str: string): string {
|
||||||
return str.replace(/[\u3041-\u3096]/g, match => {
|
return str.replace(/[\u3041-\u3096]/g, (match) => {
|
||||||
const char = match.charCodeAt(0) + 0x60;
|
const char = match.charCodeAt(0) + 0x60;
|
||||||
return String.fromCharCode(char);
|
return String.fromCharCode(char);
|
||||||
});
|
});
|
||||||
|
@ -49,14 +49,14 @@ export function hiraganaToKatagana(str: string): string {
|
||||||
/**
|
/**
|
||||||
* 全角カタカナを半角カタカナに変換します
|
* 全角カタカナを半角カタカナに変換します
|
||||||
* @param str 全角カタカナ
|
* @param str 全角カタカナ
|
||||||
* @returns 半角カタカナ
|
* @return 半角カタカナ
|
||||||
*/
|
*/
|
||||||
export function zenkakuToHankaku(str: string): string {
|
export function zenkakuToHankaku(str: string): string {
|
||||||
const reg = new RegExp('(' + kanaMap.map(x => x[0]).join('|') + ')', 'g');
|
const reg = new RegExp('(' + kanaMap.map((x) => x[0]).join('|') + ')', 'g');
|
||||||
|
|
||||||
return str
|
return str
|
||||||
.replace(reg, match =>
|
.replace(reg, (match) =>
|
||||||
kanaMap.find(x => x[0] == match)![1]
|
kanaMap.find((x) => x[0] == match)![1],
|
||||||
)
|
)
|
||||||
.replace(/゛/g, '゙')
|
.replace(/゛/g, '゙')
|
||||||
.replace(/゜/g, '゚');
|
.replace(/゜/g, '゚');
|
||||||
|
@ -65,14 +65,14 @@ export function zenkakuToHankaku(str: string): string {
|
||||||
/**
|
/**
|
||||||
* 半角カタカナを全角カタカナに変換します
|
* 半角カタカナを全角カタカナに変換します
|
||||||
* @param str 半角カタカナ
|
* @param str 半角カタカナ
|
||||||
* @returns 全角カタカナ
|
* @return 全角カタカナ
|
||||||
*/
|
*/
|
||||||
export function hankakuToZenkaku(str: string): string {
|
export function hankakuToZenkaku(str: string): string {
|
||||||
const reg = new RegExp('(' + kanaMap.map(x => x[1]).join('|') + ')', 'g');
|
const reg = new RegExp('(' + kanaMap.map((x) => x[1]).join('|') + ')', 'g');
|
||||||
|
|
||||||
return str
|
return str
|
||||||
.replace(reg, match =>
|
.replace(reg, (match) =>
|
||||||
kanaMap.find(x => x[1] == match)![0]
|
kanaMap.find((x) => x[1] == match)![0],
|
||||||
)
|
)
|
||||||
.replace(/゙/g, '゛')
|
.replace(/゙/g, '゛')
|
||||||
.replace(/゚/g, '゜');
|
.replace(/゚/g, '゜');
|
||||||
|
|
|
@ -4,9 +4,9 @@ export default function(text: string, words: (string | RegExp)[]): boolean {
|
||||||
if (text == null) return false;
|
if (text == null) return false;
|
||||||
|
|
||||||
text = katakanaToHiragana(hankakuToZenkaku(text));
|
text = katakanaToHiragana(hankakuToZenkaku(text));
|
||||||
words = words.map(word => typeof word == 'string' ? katakanaToHiragana(word) : word);
|
words = words.map((word) => typeof word == 'string' ? katakanaToHiragana(word) : word);
|
||||||
|
|
||||||
return words.some(word => {
|
return words.some((word) => {
|
||||||
/**
|
/**
|
||||||
* テキストの余分な部分を取り除く
|
* テキストの余分な部分を取り除く
|
||||||
* 例えば「藍ちゃん好き!」のようなテキストを「好き」にする
|
* 例えば「藍ちゃん好き!」のようなテキストを「好き」にする
|
||||||
|
|
|
@ -12,5 +12,5 @@ const invalidChars = [
|
||||||
];
|
];
|
||||||
|
|
||||||
export function safeForInterpolate(text: string): boolean {
|
export function safeForInterpolate(text: string): boolean {
|
||||||
return !invalidChars.some(c => text.includes(c));
|
return !invalidChars.some((c) => text.includes(c));
|
||||||
}
|
}
|
||||||
|
|
|
@ -459,11 +459,11 @@ export const and = [
|
||||||
];
|
];
|
||||||
|
|
||||||
export function genItem(seedOrRng?: (() => number) | string | number) {
|
export function genItem(seedOrRng?: (() => number) | string | number) {
|
||||||
const rng = seedOrRng
|
const rng = seedOrRng ?
|
||||||
? typeof seedOrRng === 'function'
|
typeof seedOrRng === 'function' ?
|
||||||
? seedOrRng
|
seedOrRng :
|
||||||
: seedrandom(seedOrRng.toString())
|
seedrandom(seedOrRng.toString()) :
|
||||||
: Math.random;
|
Math.random;
|
||||||
|
|
||||||
let item = '';
|
let item = '';
|
||||||
if (Math.floor(rng() * 5) !== 0) item += itemPrefixes[Math.floor(rng() * itemPrefixes.length)];
|
if (Math.floor(rng() * 5) !== 0) item += itemPrefixes[Math.floor(rng() * itemPrefixes.length)];
|
||||||
|
|
|
@ -12,7 +12,7 @@ export class Misskey {
|
||||||
this.server = http.createServer(app.callback());
|
this.server = http.createServer(app.callback());
|
||||||
|
|
||||||
const ws = new websocket.server({
|
const ws = new websocket.server({
|
||||||
httpServer: this.server
|
httpServer: this.server,
|
||||||
});
|
});
|
||||||
|
|
||||||
ws.on('request', async (request) => {
|
ws.on('request', async (request) => {
|
||||||
|
@ -40,7 +40,7 @@ export class Misskey {
|
||||||
}
|
}
|
||||||
|
|
||||||
public async waitForMainChannelConnected() {
|
public async waitForMainChannelConnected() {
|
||||||
await this.waitForStreamingMessage(message => {
|
await this.waitForStreamingMessage((message) => {
|
||||||
const {type, body} = message;
|
const {type, body} = message;
|
||||||
if (type === 'connect') {
|
if (type === 'connect') {
|
||||||
const {channel, id, params, pong} = body;
|
const {channel, id, params, pong} = body;
|
||||||
|
@ -49,7 +49,7 @@ export class Misskey {
|
||||||
|
|
||||||
if (pong) {
|
if (pong) {
|
||||||
this.sendStreamingMessage('connected', {
|
this.sendStreamingMessage('connected', {
|
||||||
id: id
|
id: id,
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -61,7 +61,7 @@ export class Misskey {
|
||||||
public sendStreamingMessage(type: string, payload: any) {
|
public sendStreamingMessage(type: string, payload: any) {
|
||||||
this.streaming.send(JSON.stringify({
|
this.streaming.send(JSON.stringify({
|
||||||
type: type,
|
type: type,
|
||||||
body: payload
|
body: payload,
|
||||||
}));
|
}));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -8,7 +8,7 @@ export class StreamingApi {
|
||||||
}
|
}
|
||||||
|
|
||||||
public async waitForMainChannelConnected() {
|
public async waitForMainChannelConnected() {
|
||||||
await expect(this.ws).toReceiveMessage("hello");
|
await expect(this.ws).toReceiveMessage('hello');
|
||||||
}
|
}
|
||||||
|
|
||||||
public send(message) {
|
public send(message) {
|
||||||
|
|
|
@ -8,7 +8,7 @@ export default class extends Module {
|
||||||
@autobind
|
@autobind
|
||||||
public install() {
|
public install() {
|
||||||
return {
|
return {
|
||||||
mentionHook: this.mentionHook
|
mentionHook: this.mentionHook,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -16,7 +16,7 @@ export default class extends Module {
|
||||||
private async mentionHook(msg: Message) {
|
private async mentionHook(msg: Message) {
|
||||||
if (msg.text && msg.text.includes('ping')) {
|
if (msg.text && msg.text.includes('ping')) {
|
||||||
msg.reply('PONG!', {
|
msg.reply('PONG!', {
|
||||||
immediate: true
|
immediate: true,
|
||||||
});
|
});
|
||||||
return true;
|
return true;
|
||||||
} else {
|
} else {
|
||||||
|
|
|
@ -15,6 +15,4 @@ beforeEach(() => {
|
||||||
|
|
||||||
test('mention hook', async () => {
|
test('mention hook', async () => {
|
||||||
const streaming = new StreamingApi();
|
const streaming = new StreamingApi();
|
||||||
|
|
||||||
|
|
||||||
});
|
});
|
||||||
|
|
Loading…
Reference in a new issue