mirror of
https://github.com/syuilo/ai.git
synced 2024-11-22 05:08:00 +00:00
nanka iroiro
This commit is contained in:
parent
736693db5f
commit
cc335a6fde
|
@ -5,7 +5,6 @@ type Config = {
|
|||
apiUrl: string;
|
||||
keywordEnabled: boolean;
|
||||
reversiEnabled: boolean;
|
||||
serverMonitoring: boolean;
|
||||
mecab?: string;
|
||||
};
|
||||
|
||||
|
|
|
@ -1,9 +1,11 @@
|
|||
import 藍 from './ai';
|
||||
import IModule from './module';
|
||||
import getDate from './utils/get-date';
|
||||
import { User } from './misskey/user';
|
||||
|
||||
export type FriendDoc = {
|
||||
userId: string;
|
||||
user: any;
|
||||
user: User;
|
||||
name?: string;
|
||||
love?: number;
|
||||
lastLoveIncrementedAt?: string;
|
||||
|
@ -50,7 +52,7 @@ export default class Friend {
|
|||
}
|
||||
}
|
||||
|
||||
public updateUser = (user: any) => {
|
||||
public updateUser = (user: User) => {
|
||||
this.doc.user = user;
|
||||
this.save();
|
||||
}
|
||||
|
@ -79,11 +81,7 @@ export default class Friend {
|
|||
}
|
||||
|
||||
public incLove = () => {
|
||||
const now = new Date();
|
||||
const y = now.getFullYear();
|
||||
const m = now.getMonth();
|
||||
const d = now.getDate();
|
||||
const today = `${y}/${m + 1}/${d}`;
|
||||
const today = getDate();
|
||||
|
||||
if (this.doc.lastLoveIncrementedAt != today) {
|
||||
this.doc.todayLoveIncrements = 0;
|
||||
|
|
|
@ -3,7 +3,6 @@ import config from './config';
|
|||
|
||||
import CoreModule from './modules/core';
|
||||
import ReversiModule from './modules/reversi';
|
||||
import ServerModule from './modules/server';
|
||||
import PingModule from './modules/ping';
|
||||
import EmojiModule from './modules/emoji';
|
||||
import FortuneModule from './modules/fortune';
|
||||
|
@ -36,7 +35,6 @@ promiseRetry(retry => {
|
|||
ai.install(new GuessingGameModule());
|
||||
ai.install(new ReversiModule());
|
||||
ai.install(new TimerModule());
|
||||
if (config.serverMonitoring) ai.install(new ServerModule());
|
||||
if (config.keywordEnabled) ai.install(new KeywordModule());
|
||||
|
||||
console.log('--- ai started! ---');
|
||||
|
|
5
src/misskey/user.ts
Normal file
5
src/misskey/user.ts
Normal file
|
@ -0,0 +1,5 @@
|
|||
export type User = {
|
||||
id: string;
|
||||
name: string;
|
||||
username: string;
|
||||
};
|
|
@ -4,6 +4,7 @@ import IModule from '../../module';
|
|||
import MessageLike from '../../message-like';
|
||||
import serifs from '../../serifs';
|
||||
import Friend from '../../friend';
|
||||
import getDate from '../../utils/get-date';
|
||||
|
||||
function zeroPadding(num: number, length: number): string {
|
||||
return ('0000000000' + num).slice(-length);
|
||||
|
@ -76,12 +77,9 @@ export default class CoreModule implements IModule {
|
|||
return true;
|
||||
}
|
||||
|
||||
const withSan =
|
||||
name.endsWith('さん') ||
|
||||
name.endsWith('くん') ||
|
||||
name.endsWith('君') ||
|
||||
name.endsWith('ちゃん') ||
|
||||
name.endsWith('様');
|
||||
const titles = ['さん', 'くん', '君', 'ちゃん', '様', '先生'];
|
||||
|
||||
const withSan = titles.some(t => name.endsWith(t));
|
||||
|
||||
if (withSan) {
|
||||
msg.friend.updateName(name);
|
||||
|
@ -101,11 +99,7 @@ export default class CoreModule implements IModule {
|
|||
if (!msg.text) return false;
|
||||
|
||||
const incLove = () => {
|
||||
const now = new Date();
|
||||
const y = now.getFullYear();
|
||||
const m = now.getMonth();
|
||||
const d = now.getDate();
|
||||
const today = `${y}/${m + 1}/${d}`;
|
||||
const today = getDate();
|
||||
|
||||
const data = msg.friend.getPerModulesData(this);
|
||||
|
||||
|
@ -146,6 +140,7 @@ export default class CoreModule implements IModule {
|
|||
if (!msg.text) return false;
|
||||
if (!msg.text.includes('なでなで')) return false;
|
||||
|
||||
//#region 1日に1回だけ親愛度を上げる
|
||||
const now = new Date();
|
||||
const y = now.getFullYear();
|
||||
const m = now.getMonth();
|
||||
|
@ -160,6 +155,7 @@ export default class CoreModule implements IModule {
|
|||
|
||||
msg.friend.incLove();
|
||||
}
|
||||
//#endregion
|
||||
|
||||
msg.reply(
|
||||
msg.friend.love >= 5 ? serifs.core.nadenade2 :
|
||||
|
|
|
@ -128,7 +128,7 @@ export default class EmojiModule implements IModule {
|
|||
const hand = hands[Math.floor(Math.random() * hands.length)];
|
||||
const face = faces[Math.floor(Math.random() * faces.length)];
|
||||
const emoji = Array.isArray(hand) ? hand[0] + face + hand[1] : hand + face + hand;
|
||||
msg.reply(serifs.EMOJI_SUGGEST.replace('$', emoji));
|
||||
msg.reply(serifs.emoji.suggest.replace('$', emoji));
|
||||
return true;
|
||||
} else {
|
||||
return false;
|
||||
|
|
|
@ -36,7 +36,7 @@ export default class FortuneModule implements IModule {
|
|||
const rng = seedrandom(seed);
|
||||
const omikuji = omikujis[Math.floor(rng() * omikujis.length)];
|
||||
const item = items[Math.floor(rng() * items.length)];
|
||||
msg.reply(`**${omikuji}🎉**\nラッキーアイテム: ${item}`, serifs.FORTUNE_CW);
|
||||
msg.reply(`**${omikuji}🎉**\nラッキーアイテム: ${item}`, serifs.fortune.cw);
|
||||
return true;
|
||||
} else {
|
||||
return false;
|
||||
|
|
|
@ -38,9 +38,9 @@ export default class GuessingGameModule implements IModule {
|
|||
|
||||
if (!msg.isMessage) {
|
||||
if (exist != null) {
|
||||
msg.reply(serifs.GUESSINGGAME_ARLEADY_STARTED);
|
||||
msg.reply(serifs.guessingGame.arleadyStarted);
|
||||
} else {
|
||||
msg.reply(serifs.GUESSINGGAME_PLZ_DM);
|
||||
msg.reply(serifs.guessingGame.plzDm);
|
||||
}
|
||||
|
||||
return true;
|
||||
|
@ -57,7 +57,7 @@ export default class GuessingGameModule implements IModule {
|
|||
endedAt: null
|
||||
});
|
||||
|
||||
msg.reply(serifs.GUESSINGGAME_STARTED).then(reply => {
|
||||
msg.reply(serifs.guessingGame.started).then(reply => {
|
||||
this.ai.subscribeReply(this, msg.userId, msg.isMessage, msg.isMessage ? msg.userId : reply.id);
|
||||
});
|
||||
|
||||
|
@ -76,7 +76,7 @@ export default class GuessingGameModule implements IModule {
|
|||
});
|
||||
|
||||
if (msg.text.includes('やめ')) {
|
||||
msg.reply(serifs.GUESSINGGAME_CANCEL);
|
||||
msg.reply(serifs.guessingGame.cancel);
|
||||
exist.isEnded = true;
|
||||
exist.endedAt = Date.now();
|
||||
this.guesses.update(exist);
|
||||
|
@ -87,7 +87,7 @@ export default class GuessingGameModule implements IModule {
|
|||
const guess = msg.text.toLowerCase().replace(this.ai.account.username.toLowerCase(), '').match(/[0-9]+/);
|
||||
|
||||
if (guess == null) {
|
||||
msg.reply(serifs.GUESSINGGAME_NAN).then(reply => {
|
||||
msg.reply(serifs.guessingGame.nan).then(reply => {
|
||||
this.ai.subscribeReply(this, msg.userId, msg.isMessage, reply.id);
|
||||
});
|
||||
} else {
|
||||
|
@ -104,15 +104,15 @@ export default class GuessingGameModule implements IModule {
|
|||
|
||||
if (exist.secret < g) {
|
||||
text = firsttime
|
||||
? serifs.GUESSINGGAME_LESS.replace('$', g.toString())
|
||||
: serifs.GUESSINGGAME_LESS_AGAIN.replace('$', g.toString());
|
||||
? serifs.guessingGame.less.replace('$', g.toString())
|
||||
: serifs.guessingGame.lessAgain.replace('$', g.toString());
|
||||
} else if (exist.secret > g) {
|
||||
text = firsttime
|
||||
? serifs.GUESSINGGAME_GRATER.replace('$', g.toString())
|
||||
: serifs.GUESSINGGAME_GRATER_AGAIN.replace('$', g.toString());
|
||||
? serifs.guessingGame.grater.replace('$', g.toString())
|
||||
: serifs.guessingGame.graterAgain.replace('$', g.toString());
|
||||
} else {
|
||||
end = true;
|
||||
text = serifs.GUESSINGGAME_CONGRATS.replace('{tries}', exist.tries.length.toString());
|
||||
text = serifs.guessingGame.congrats.replace('{tries}', exist.tries.length.toString());
|
||||
}
|
||||
|
||||
if (end) {
|
||||
|
|
|
@ -9,6 +9,7 @@
|
|||
import * as request from 'request-promise-native';
|
||||
import Reversi, { Color } from 'misskey-reversi';
|
||||
import config from '../../config';
|
||||
import serifs from '../../serifs';
|
||||
|
||||
const db = {};
|
||||
|
||||
|
@ -208,36 +209,36 @@ class Session {
|
|||
private onEnded = async (msg: any) => {
|
||||
// ストリームから切断
|
||||
process.send({
|
||||
type: 'close'
|
||||
type: 'ended'
|
||||
});
|
||||
|
||||
let text: string;
|
||||
|
||||
if (msg.body.game.surrendered) {
|
||||
if (this.isSettai) {
|
||||
text = `(${this.userName}を接待していたら投了されちゃいました... ごめんなさい)`;
|
||||
text = serifs.reversi.settaiButYouSurrendered.replace('{name}', this.userName);
|
||||
} else {
|
||||
text = `${this.userName}が投了しちゃいました`;
|
||||
text = serifs.reversi.youSurrendered.replace('{name}', this.userName);
|
||||
}
|
||||
} else if (msg.body.winnerId) {
|
||||
if (msg.body.winnerId == this.account.id) {
|
||||
if (this.isSettai) {
|
||||
text = `${this.userName}に接待で勝ってしまいました...`;
|
||||
text = serifs.reversi.iWonButSettai.replace('{name}', this.userName);
|
||||
} else {
|
||||
text = `${this.userName}に勝ちました♪`;
|
||||
text = serifs.reversi.iWon.replace('{name}', this.userName);
|
||||
}
|
||||
} else {
|
||||
if (this.isSettai) {
|
||||
text = `(${this.userName}に接待で負けてあげました...♪)`;
|
||||
text = serifs.reversi.iLoseButSettai.replace('{name}', this.userName);
|
||||
} else {
|
||||
text = `${this.userName}に負けました...`;
|
||||
text = serifs.reversi.iLose.replace('{name}', this.userName);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
if (this.isSettai) {
|
||||
text = `(${this.userName}に接待で引き分けました...)`;
|
||||
text = serifs.reversi.drawnSettai.replace('{name}', this.userName);
|
||||
} else {
|
||||
text = `${this.userName}と引き分けました~`;
|
||||
text = serifs.reversi.drawn.replace('{name}', this.userName);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -416,8 +417,8 @@ class Session {
|
|||
*/
|
||||
private postGameStarted = async () => {
|
||||
const text = this.isSettai
|
||||
? `${this.userName}の接待を始めました!`
|
||||
: `対局を${this.userName}と始めました! (強さ${this.strength})`;
|
||||
? serifs.reversi.startedSettai.replace('{name}', this.userName)
|
||||
: serifs.reversi.started.replace('{name}', this.userName).replace('{strength}', this.strength.toString());
|
||||
|
||||
return await this.post(`${text}\n→[観戦する](${this.url})`);
|
||||
}
|
||||
|
|
|
@ -6,6 +6,9 @@ import serifs from '../../serifs';
|
|||
import config from '../../config';
|
||||
import MessageLike from '../../message-like';
|
||||
import * as WebSocket from 'ws';
|
||||
import Friend from '../../friend';
|
||||
import getDate from '../../utils/get-date';
|
||||
import { User } from '../../misskey/user';
|
||||
|
||||
export default class ReversiModule implements IModule {
|
||||
public name = 'reversi';
|
||||
|
@ -44,13 +47,13 @@ export default class ReversiModule implements IModule {
|
|||
public onMention = (msg: MessageLike) => {
|
||||
if (msg.text && (msg.text.includes('リバーシ') || msg.text.includes('りばーし') || msg.text.includes('オセロ') || msg.text.includes('おせろ') || msg.text.toLowerCase().includes('reversi'))) {
|
||||
if (config.reversiEnabled) {
|
||||
msg.reply(serifs.REVERSI_OK);
|
||||
msg.reply(serifs.reversi.ok);
|
||||
|
||||
this.ai.api('games/reversi/match', {
|
||||
userId: msg.userId
|
||||
});
|
||||
} else {
|
||||
msg.reply(serifs.REVERSI_DECLINE);
|
||||
msg.reply(serifs.reversi.decline);
|
||||
}
|
||||
|
||||
return true;
|
||||
|
@ -157,8 +160,10 @@ export default class ReversiModule implements IModule {
|
|||
type: 'set',
|
||||
pos: msg.pos
|
||||
});
|
||||
} else if (msg.type == 'close') {
|
||||
} else if (msg.type == 'ended') {
|
||||
gw.close();
|
||||
|
||||
this.onGameEnded(game);
|
||||
}
|
||||
});
|
||||
|
||||
|
@ -189,4 +194,23 @@ export default class ReversiModule implements IModule {
|
|||
console.log('reversi game stream closed');
|
||||
});
|
||||
}
|
||||
|
||||
private onGameEnded(game: any) {
|
||||
const user = game.user1Id == this.ai.account.id ? game.user2 : game.user1;
|
||||
|
||||
//#region 1日に1回だけ親愛度を上げる
|
||||
const today = getDate();
|
||||
|
||||
const friend = new Friend(this.ai, { user: user });
|
||||
|
||||
const data = friend.getPerModulesData(this);
|
||||
|
||||
if (data.lastPlayedAt != today) {
|
||||
data.lastPlayedAt = today;
|
||||
friend.setPerModulesData(this, data);
|
||||
|
||||
friend.incLove();
|
||||
}
|
||||
//#endregion
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,162 +0,0 @@
|
|||
import * as childProcess from 'child_process';
|
||||
import * as WebSocket from 'ws';
|
||||
import 藍 from '../../ai';
|
||||
import IModule from '../../module';
|
||||
import serifs from '../../serifs';
|
||||
import config from '../../config';
|
||||
import MessageLike from '../../message-like';
|
||||
const ReconnectingWebSocket = require('../../../node_modules/reconnecting-websocket/dist/reconnecting-websocket-cjs.js');
|
||||
|
||||
export default class ServerModule implements IModule {
|
||||
public name = 'server';
|
||||
|
||||
private ai: 藍;
|
||||
private connection?: any;
|
||||
private preventScheduleReboot = false;
|
||||
private rebootTimer: NodeJS.Timer;
|
||||
private rebootTimerSub: NodeJS.Timer;
|
||||
private recentStat: any;
|
||||
|
||||
/**
|
||||
* 1秒後とのログ1分間分
|
||||
*/
|
||||
private statsLogs: any[] = [];
|
||||
|
||||
public install = (ai: 藍) => {
|
||||
this.ai = ai;
|
||||
|
||||
this.connection = new ReconnectingWebSocket(`${config.wsUrl}/server-stats`, [], {
|
||||
WebSocket: WebSocket
|
||||
});
|
||||
|
||||
this.connection.addEventListener('open', () => {
|
||||
console.log('server-stats stream opened');
|
||||
});
|
||||
|
||||
this.connection.addEventListener('close', () => {
|
||||
console.log('server-stats stream closed');
|
||||
});
|
||||
|
||||
this.connection.addEventListener('message', message => {
|
||||
const msg = JSON.parse(message.data);
|
||||
|
||||
this.onConnectionMessage(msg);
|
||||
});
|
||||
|
||||
setInterval(() => {
|
||||
this.statsLogs.unshift(this.recentStat);
|
||||
if (this.statsLogs.length > 60) this.statsLogs.pop();
|
||||
}, 1000);
|
||||
|
||||
setInterval(() => {
|
||||
this.check();
|
||||
}, 3000);
|
||||
}
|
||||
|
||||
private check = () => {
|
||||
const average = (arr) => arr.reduce((a, b) => a + b) / arr.length;
|
||||
|
||||
const memPercentages = this.statsLogs.map(s => (s.mem.used / s.mem.total) * 100);
|
||||
const memPercentage = average(memPercentages);
|
||||
if (memPercentage >= 90) {
|
||||
this.scheduleReboot('mem');
|
||||
}
|
||||
|
||||
const cpuPercentages = this.statsLogs.map(s => s.cpu_usage * 100);
|
||||
const cpuPercentage = average(cpuPercentages);
|
||||
if (cpuPercentage >= 70) {
|
||||
this.scheduleReboot('cpu');
|
||||
}
|
||||
|
||||
console.log(`CPU: ${cpuPercentage}% | MEM: ${memPercentage}%`);
|
||||
}
|
||||
|
||||
private onConnectionMessage = (msg: any) => {
|
||||
switch (msg.type) {
|
||||
|
||||
case 'stats': {
|
||||
this.onStats(msg.body);
|
||||
break;
|
||||
}
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
private onStats = async (stats: any) => {
|
||||
this.recentStat = stats;
|
||||
}
|
||||
|
||||
private scheduleReboot = (reason: string) => {
|
||||
if (this.preventScheduleReboot) return;
|
||||
|
||||
this.preventScheduleReboot = true;
|
||||
|
||||
this.ai.post({
|
||||
text: reason == 'cpu' ? serifs.REBOOT_SCHEDULED_CPU : serifs.REBOOT_SCHEDULED_MEM
|
||||
}).then(post => {
|
||||
this.ai.subscribeReply(this, 'reboot', false, post.id);
|
||||
});
|
||||
|
||||
this.rebootTimer = setTimeout(() => {
|
||||
childProcess.exec('forever restartall');
|
||||
}, 1000 * 60);
|
||||
|
||||
this.rebootTimerSub = setTimeout(() => {
|
||||
this.ai.post({
|
||||
cw: serifs.REBOOT,
|
||||
text: serifs.REBOOT_DETAIL
|
||||
});
|
||||
}, 1000 * 50);
|
||||
}
|
||||
|
||||
public onReplyThisModule = (msg: MessageLike) => {
|
||||
if (msg.text == null) return;
|
||||
|
||||
if (msg.text.includes('やめ') || msg.text.includes('まって')) {
|
||||
if (msg.user.isAdmin) {
|
||||
msg.reply(serifs.REBOOT_CANCEL_REQUESTED_ACCEPT);
|
||||
|
||||
this.ai.post({
|
||||
text: serifs.REBOOT_CANCELED
|
||||
});
|
||||
|
||||
this.cancelReboot();
|
||||
} else {
|
||||
msg.reply(serifs.REBOOT_CANCEL_REQUESTED_REJECT);
|
||||
}
|
||||
}
|
||||
|
||||
this.ai.unsubscribeReply(this, 'reboot');
|
||||
}
|
||||
|
||||
public onMention = (msg: MessageLike) => {
|
||||
if (msg.text && msg.text.includes('再起動しないで')) {
|
||||
if (msg.user.isAdmin) {
|
||||
msg.reply(serifs.REBOOT_CANCEL_REQUESTED_ACCEPT);
|
||||
|
||||
this.ai.post({
|
||||
text: serifs.REBOOT_CANCELED
|
||||
});
|
||||
|
||||
this.cancelReboot();
|
||||
} else {
|
||||
msg.reply(serifs.REBOOT_CANCEL_REQUESTED_REJECT);
|
||||
}
|
||||
return true;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
private cancelReboot = () => {
|
||||
clearTimeout(this.rebootTimer);
|
||||
clearTimeout(this.rebootTimerSub);
|
||||
|
||||
// 10分間延期
|
||||
setTimeout(() => {
|
||||
this.preventScheduleReboot = false;
|
||||
}, 1000 * 60 * 10);
|
||||
}
|
||||
}
|
169
src/serifs.ts
169
src/serifs.ts
|
@ -22,94 +22,143 @@ export default {
|
|||
remembered: '{reading}!'
|
||||
},
|
||||
|
||||
/**
|
||||
* リバーシ
|
||||
*/
|
||||
reversi: {
|
||||
/**
|
||||
* リバーシへの誘いを承諾するとき
|
||||
*/
|
||||
REVERSI_OK: '良いですよ~',
|
||||
ok: '良いですよ~',
|
||||
|
||||
/**
|
||||
* リバーシへの誘いを断るとき
|
||||
*/
|
||||
REVERSI_DECLINE: 'ごめんなさい、今リバーシはするなと言われてます...',
|
||||
decline: 'ごめんなさい、今リバーシはするなと言われてます...',
|
||||
|
||||
/**
|
||||
* (メモリが足りないので)再起動がスケジュールされたとき
|
||||
* 対局開始
|
||||
*/
|
||||
REBOOT_SCHEDULED_MEM: 'サーバーの空きメモリが少なくなってきたので、1分後にサーバー再起動しますね!',
|
||||
started: '対局を{name}と始めました! (強さ{strength})',
|
||||
|
||||
/**
|
||||
* (CPU使用率が高いので)再起動がスケジュールされたとき
|
||||
* 接待開始
|
||||
*/
|
||||
REBOOT_SCHEDULED_CPU: 'サーバーの負荷が高いので、1分後にサーバー再起動しますね!',
|
||||
startedSettai: '({name}の接待を始めました)',
|
||||
|
||||
/**
|
||||
* まもなく再起動されるとき
|
||||
* 勝ったとき
|
||||
*/
|
||||
REBOOT: 'では、まもなくサーバーを再起動します!',
|
||||
REBOOT_DETAIL: '(私も再起動に巻き込まれちゃうので、サーバーの再起動が完了したことのお知らせはできません...)',
|
||||
iWon: '{name}に勝ちました♪',
|
||||
|
||||
REBOOT_CANCEL_REQUESTED_ACCEPT: 'わかりました。再起動の予定を取り消しました!',
|
||||
REBOOT_CANCEL_REQUESTED_REJECT: 'ごめんなさい、再起動の取り消しは管理者のみが行えます...',
|
||||
/**
|
||||
* 接待のつもりが勝ってしまったとき
|
||||
*/
|
||||
iWonButSettai: '({name}に接待で勝ってしまいました...)',
|
||||
|
||||
REBOOT_CANCELED: '再起動が取り消されました。お騒がせしました',
|
||||
/**
|
||||
* 負けたとき
|
||||
*/
|
||||
iLose: '{name}に負けました...',
|
||||
|
||||
/**
|
||||
* 接待で負けてあげたとき
|
||||
*/
|
||||
iLoseButSettai: '({name}に接待で負けてあげました...♪)',
|
||||
|
||||
/**
|
||||
* 引き分けたとき
|
||||
*/
|
||||
drawn: '{name}と引き分けました~',
|
||||
|
||||
/**
|
||||
* 接待で引き分けたとき
|
||||
*/
|
||||
drawnSettai: '({name}に接待で引き分けました...)',
|
||||
|
||||
/**
|
||||
* 相手が投了したとき
|
||||
*/
|
||||
youSurrendered: '{name}が投了しちゃいました',
|
||||
|
||||
/**
|
||||
* 接待してたら相手が投了したとき
|
||||
*/
|
||||
settaiButYouSurrendered: '({name}を接待していたら投了されちゃいました... ごめんなさい)',
|
||||
},
|
||||
|
||||
/**
|
||||
* 数当てゲーム
|
||||
*/
|
||||
guessingGame: {
|
||||
/**
|
||||
* やろうと言われたけど既にやっているとき
|
||||
*/
|
||||
arleadyStarted: 'え、ゲームは既に始まってますよ!',
|
||||
|
||||
/**
|
||||
* タイムライン上で誘われたとき
|
||||
*/
|
||||
plzDm: 'メッセージでやりましょう!',
|
||||
|
||||
/**
|
||||
* ゲーム開始
|
||||
*/
|
||||
started: '0~100の秘密の数を当ててみてください♪',
|
||||
|
||||
/**
|
||||
* 数字じゃない返信があったとき
|
||||
*/
|
||||
nan: '数字でお願いします!「やめる」と言ってゲームをやめることもできますよ!',
|
||||
|
||||
/**
|
||||
* 中止を要求されたとき
|
||||
*/
|
||||
cancel: 'わかりました~。ありがとうございました♪',
|
||||
|
||||
/**
|
||||
* 小さい数を言われたとき
|
||||
*/
|
||||
grater: '$より大きいですね',
|
||||
|
||||
/**
|
||||
* 小さい数を言われたとき(2度目)
|
||||
*/
|
||||
graterAgain: 'もう一度言いますが$より大きいですよ!',
|
||||
|
||||
/**
|
||||
* 大きい数を言われたとき
|
||||
*/
|
||||
less: '$より小さいですね',
|
||||
|
||||
/**
|
||||
* 大きい数を言われたとき(2度目)
|
||||
*/
|
||||
lessAgain: 'もう一度言いますが$より小さいですよ!',
|
||||
|
||||
/**
|
||||
* 正解したとき
|
||||
*/
|
||||
congrats: '正解です🎉 ({tries}回目で当てました)',
|
||||
},
|
||||
|
||||
/**
|
||||
* 絵文字生成
|
||||
*/
|
||||
EMOJI_SUGGEST: 'こんなのはどうですか?→$',
|
||||
|
||||
FORTUNE_CW: '私が今日のあなたの運勢を占いました...',
|
||||
emoji: {
|
||||
suggest: 'こんなのはどうですか?→$',
|
||||
},
|
||||
|
||||
/**
|
||||
* 数当てゲームをやろうと言われたけど既にやっているとき
|
||||
* 占い
|
||||
*/
|
||||
GUESSINGGAME_ARLEADY_STARTED: 'え、ゲームは既に始まってますよ!',
|
||||
fortune: {
|
||||
cw: '私が今日のあなたの運勢を占いました...',
|
||||
},
|
||||
|
||||
/**
|
||||
* タイムライン上で数当てゲームに誘われたとき
|
||||
* タイマー
|
||||
*/
|
||||
GUESSINGGAME_PLZ_DM: 'メッセージでやりましょう!',
|
||||
|
||||
/**
|
||||
* 数当てゲーム開始
|
||||
*/
|
||||
GUESSINGGAME_STARTED: '0~100の秘密の数を当ててみてください♪',
|
||||
|
||||
/**
|
||||
* 数当てゲームで数字じゃない返信があったとき
|
||||
*/
|
||||
GUESSINGGAME_NAN: '数字でお願いします!「やめる」と言ってゲームをやめることもできますよ!',
|
||||
|
||||
/**
|
||||
* 数当てゲーム中止を要求されたとき
|
||||
*/
|
||||
GUESSINGGAME_CANCEL: 'わかりました~。ありがとうございました♪',
|
||||
|
||||
/**
|
||||
* 数当てゲームで小さい数を言われたとき
|
||||
*/
|
||||
GUESSINGGAME_GRATER: '$より大きいですね',
|
||||
|
||||
/**
|
||||
* 数当てゲームで小さい数を言われたとき(2度目)
|
||||
*/
|
||||
GUESSINGGAME_GRATER_AGAIN: 'もう一度言いますが$より大きいですよ!',
|
||||
|
||||
/**
|
||||
* 数当てゲームで大きい数を言われたとき
|
||||
*/
|
||||
GUESSINGGAME_LESS: '$より小さいですね',
|
||||
|
||||
/**
|
||||
* 数当てゲームで大きい数を言われたとき(2度目)
|
||||
*/
|
||||
GUESSINGGAME_LESS_AGAIN: 'もう一度言いますが$より小さいですよ!',
|
||||
|
||||
/**
|
||||
* 数当てゲームで正解したとき
|
||||
*/
|
||||
GUESSINGGAME_CONGRATS: '正解です🎉 ({tries}回目で当てました)',
|
||||
|
||||
timer: {
|
||||
set: 'わかりました!',
|
||||
invalid: 'うーん...?',
|
||||
|
|
8
src/utils/get-date.ts
Normal file
8
src/utils/get-date.ts
Normal file
|
@ -0,0 +1,8 @@
|
|||
export default function (): string {
|
||||
const now = new Date();
|
||||
const y = now.getFullYear();
|
||||
const m = now.getMonth();
|
||||
const d = now.getDate();
|
||||
const today = `${y}/${m + 1}/${d}`;
|
||||
return today;
|
||||
}
|
Loading…
Reference in a new issue