Skip to content

Commit

Permalink
feat: こるくの玉音放送機能の追加 (#658)
Browse files Browse the repository at this point in the history
  • Loading branch information
m2en authored Jan 4, 2023
1 parent 57ecdcb commit 3166fc7
Show file tree
Hide file tree
Showing 5 changed files with 115 additions and 11 deletions.
Binary file added assets/gyokuon/gyokuon.mp3
Binary file not shown.
21 changes: 11 additions & 10 deletions src/server/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,7 @@ import { DiscordRoleManager } from '../adaptor/discord/role.js';
import { DiscordSheriff } from '../adaptor/discord/sheriff.js';
import { DiscordWS } from '../adaptor/discord/ws.js';
import { GenVersionFetcher } from '../adaptor/version/fetch.js';
import type { GyokuonAssetKey } from '../service/command/gyokuon.js';
import type { KaereMusicKey } from '../service/command/kaere.js';
import type { Snowflake } from '../model/id.js';
import dotenv from 'dotenv';
Expand Down Expand Up @@ -137,16 +138,16 @@ if (features.includes('COMMAND')) {
registerAllCommandResponder({
typoRepo,
reservationRepo,
factory: new DiscordVoiceConnectionFactory<AssetKey | KaereMusicKey>(
client,
{
COFFIN_INTRO: join('assets', 'party', 'coffin-intro.mp3'),
COFFIN_DROP: join('assets', 'party', 'coffin-drop.mp3'),
KAKAPO: join('assets', 'party', 'kakapo.mp3'),
KAKUSIN_DAISUKE: join('assets', 'party', 'kakusin-daisuke.mp3'),
NEROYO: join('assets', 'kaere', 'neroyo.mp3')
}
),
factory: new DiscordVoiceConnectionFactory<
AssetKey | KaereMusicKey | GyokuonAssetKey
>(client, {
COFFIN_INTRO: join('assets', 'party', 'coffin-intro.mp3'),
COFFIN_DROP: join('assets', 'party', 'coffin-drop.mp3'),
KAKAPO: join('assets', 'party', 'kakapo.mp3'),
KAKUSIN_DAISUKE: join('assets', 'party', 'kakusin-daisuke.mp3'),
NEROYO: join('assets', 'kaere', 'neroyo.mp3'),
GYOKUON: join('assets', 'gyokuon', 'gyokuon.mp3')
}),
clock,
scheduleRunner,
random: new MathRandomGenerator(),
Expand Down
7 changes: 6 additions & 1 deletion src/service/command.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ import { DebugCommand, MessageRepository } from './command/debug.js';
import { DiceCommand, DiceQueen } from './command/dice.js';
import { GetVersionCommand, VersionFetcher } from './command/version.js';
import { GuildInfo, GuildStatsRepository } from './command/guild-info.js';
import { GyokuonAssetKey, GyokuonCommand } from './command/gyokuon.js';
import { JudgingCommand, RandomGenerator } from './command/judging.js';
import {
KaereCommand,
Expand Down Expand Up @@ -54,7 +55,7 @@ export const registerAllCommandResponder = ({
}: {
typoRepo: TypoRepository;
reservationRepo: ReservationRepository;
factory: VoiceConnectionFactory<AssetKey | KaereMusicKey>;
factory: VoiceConnectionFactory<AssetKey | KaereMusicKey | GyokuonAssetKey>;
clock: Clock;
scheduleRunner: ScheduleRunner;
random: PartyRng & RandomGenerator;
Expand Down Expand Up @@ -82,6 +83,10 @@ export const registerAllCommandResponder = ({
scheduleRunner,
repo: reservationRepo
}),
new GyokuonCommand({
connectionFactory: factory,
controller: roomController
}),
new JudgingCommand(random),
new Meme(),
new HelpCommand(commandRunner),
Expand Down
21 changes: 21 additions & 0 deletions src/service/command/gyokuon.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
import { GyokuonAssetKey, GyokuonCommand } from './gyokuon.js';
import { it, vi } from 'vitest';

import { MockVoiceConnectionFactory } from '../../adaptor/index.js';
import { createMockMessage } from './command-message.js';
import { parseStringsOrThrow } from '../../adaptor/proxy/command/schema.js';

it('use case of gyokuon', async () => {
const fn = vi.fn();
const connectionFactory = new MockVoiceConnectionFactory<GyokuonAssetKey>();
const responder = new GyokuonCommand({
connectionFactory,
controller: {
disconnectAllUsersIn: fn
}
});

await responder.on(
createMockMessage(parseStringsOrThrow(['gyokuon'], responder.schema))
);
});
77 changes: 77 additions & 0 deletions src/service/command/gyokuon.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,77 @@
import type {
CommandMessage,
CommandResponder,
HelpInfo
} from './command-message.js';
import type { Schema } from '../../model/command-schema.js';
import type { Snowflake } from '../../model/id.js';
import type { VoiceConnectionFactory } from '../voice-connection.js';
import type { VoiceRoomController } from './kaere.js';

export type GyokuonAssetKey = 'GYOKUON';

const SCHEMA = {
names: ['gyokuon'],
subCommands: {}
} as const satisfies Schema;

/**
* gyokuon コマンドでこるくの玉音放送をボイスチャンネルに再生する機能
*
* @export
*/
export class GyokuonCommand implements CommandResponder<typeof SCHEMA> {
help: Readonly<HelpInfo> = {
title: 'こるくの玉音放送',
description:
'VC内にこるくの玉音放送を再生するよ。引数無しで即起動。どの方式でもコマンド発行者がVCに居ないと動かないよ。'
};
readonly schema = SCHEMA;

constructor(
private readonly deps: {
connectionFactory: VoiceConnectionFactory<GyokuonAssetKey>;
controller: VoiceRoomController;
}
) {}

async on(message: CommandMessage<typeof SCHEMA>): Promise<void> {
const roomId = message.senderVoiceChannelId;
if (!roomId) {
await message.reply({
title: 'Gyokuon安全装置が作動したよ。',
description:
'起動した本人がボイスチャンネルに居ないのでキャンセルしておいた。悪く思わないでね。'
});
return;
}

await this.start(message.senderGuildId, roomId);
return;
}

// 玉音放送がすでに行われているか
private doingGyokuon = false;
private async start(guildId: Snowflake, roomId: Snowflake): Promise<void> {
if (this.doingGyokuon) {
return;
}

this.doingGyokuon = true;
const connectionVC = await this.deps.connectionFactory.connectTo(
guildId,
roomId
);

connectionVC.connect();
connectionVC.onDisconnected(() => {
this.doingGyokuon = false;
return false;
});

await connectionVC.playToEnd('GYOKUON');

connectionVC.destroy();
this.doingGyokuon = false;
}
}

0 comments on commit 3166fc7

Please sign in to comment.