From a8810af8d9a78c0819781001ab045a9c8cf9d171 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E3=81=8B=E3=81=A3=E3=81=93=E3=81=8B=E3=82=8A?= <67428053+kakkokari-gtyih@users.noreply.github.com> Date: Fri, 16 Aug 2024 21:02:12 +0900 Subject: [PATCH] =?UTF-8?q?fix(backend):=20=E3=83=AA=E3=83=90=E3=83=BC?= =?UTF-8?q?=E3=82=B7=E3=81=AE=E8=A8=AD=E5=AE=9A=E5=A4=89=E6=9B=B4=E3=81=8C?= =?UTF-8?q?=E5=8F=8D=E6=98=A0=E3=81=95=E3=82=8C=E3=81=AA=E3=81=84=E3=81=AE?= =?UTF-8?q?=E3=82=92=E4=BF=AE=E6=AD=A3=20(#14404)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * fix(backend): リバーシの設定変更が反映されないのを修正 * Update Changelog * add bindthis --- CHANGELOG.md | 1 + packages/backend/src/core/ReversiService.ts | 33 ++++++++++++++++--- .../api/stream/channels/reversi-game.ts | 8 +++-- packages/misskey-js/etc/misskey-js.api.md | 3 ++ packages/misskey-js/src/consts.ts | 13 +++++--- packages/misskey-js/src/index.ts | 1 + 6 files changed, 47 insertions(+), 12 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 89c90bb663..9385842d62 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -22,6 +22,7 @@ (Cherry-picked from https://github.com/MisskeyIO/misskey/pull/679) - Fix: ActivityPubのエンティティタイプ判定で不明なタイプを受け取った場合でも処理を継続するように - キュー処理のつまりが改善される可能性があります +- Fix: リバーシの対局設定の変更が反映されないのを修正 ## 2024.7.0 diff --git a/packages/backend/src/core/ReversiService.ts b/packages/backend/src/core/ReversiService.ts index 7f939b99c7..51dca3da59 100644 --- a/packages/backend/src/core/ReversiService.ts +++ b/packages/backend/src/core/ReversiService.ts @@ -6,6 +6,7 @@ import { Inject, Injectable } from '@nestjs/common'; import * as Redis from 'ioredis'; import { ModuleRef } from '@nestjs/core'; +import { reversiUpdateKeys } from 'misskey-js'; import * as Reversi from 'misskey-reversi'; import { IsNull, LessThan, MoreThan } from 'typeorm'; import type { @@ -399,7 +400,33 @@ export class ReversiService implements OnApplicationShutdown, OnModuleInit { } @bindThis - public async updateSettings(gameId: MiReversiGame['id'], user: MiUser, key: string, value: any) { + public isValidReversiUpdateKey(key: unknown): key is typeof reversiUpdateKeys[number] { + if (typeof key !== 'string') return false; + return (reversiUpdateKeys as string[]).includes(key); + } + + @bindThis + public isValidReversiUpdateValue(key: K, value: unknown): value is MiReversiGame[K] { + switch (key) { + case 'map': + return Array.isArray(value) && value.every(row => typeof row === 'string'); + case 'bw': + return typeof value === 'string' && ['random', '1', '2'].includes(value); + case 'isLlotheo': + return typeof value === 'boolean'; + case 'canPutEverywhere': + return typeof value === 'boolean'; + case 'loopedBoard': + return typeof value === 'boolean'; + case 'timeLimitForEachTurn': + return typeof value === 'number' && value >= 0; + default: + return false; + } + } + + @bindThis + public async updateSettings(gameId: MiReversiGame['id'], user: MiUser, key: K, value: MiReversiGame[K]) { const game = await this.get(gameId); if (game == null) throw new Error('game not found'); if (game.isStarted) return; @@ -407,10 +434,6 @@ export class ReversiService implements OnApplicationShutdown, OnModuleInit { if ((game.user1Id === user.id) && game.user1Ready) return; if ((game.user2Id === user.id) && game.user2Ready) return; - if (!['map', 'bw', 'isLlotheo', 'canPutEverywhere', 'loopedBoard', 'timeLimitForEachTurn'].includes(key)) return; - - // TODO: より厳格なバリデーション - const updatedGame = { ...game, [key]: value, diff --git a/packages/backend/src/server/api/stream/channels/reversi-game.ts b/packages/backend/src/server/api/stream/channels/reversi-game.ts index c6f4a4ae3b..7597a1cfa3 100644 --- a/packages/backend/src/server/api/stream/channels/reversi-game.ts +++ b/packages/backend/src/server/api/stream/channels/reversi-game.ts @@ -12,6 +12,7 @@ import { ReversiGameEntityService } from '@/core/entities/ReversiGameEntityServi import { isJsonObject } from '@/misc/json-value.js'; import type { JsonObject, JsonValue } from '@/misc/json-value.js'; import Channel, { type MiChannelService } from '../channel.js'; +import { reversiUpdateKeys } from 'misskey-js'; class ReversiGameChannel extends Channel { public readonly chName = 'reversiGame'; @@ -46,8 +47,9 @@ class ReversiGameChannel extends Channel { break; case 'updateSettings': if (!isJsonObject(body)) return; - if (typeof body.key !== 'string') return; - if (!isJsonObject(body.value)) return; + if (!this.reversiService.isValidReversiUpdateKey(body.key)) return; + if (!this.reversiService.isValidReversiUpdateValue(body.key, body.value)) return; + this.updateSettings(body.key, body.value); break; case 'cancel': @@ -64,7 +66,7 @@ class ReversiGameChannel extends Channel { } @bindThis - private async updateSettings(key: string, value: JsonObject) { + private async updateSettings(key: K, value: MiReversiGame[K]) { if (this.user == null) return; this.reversiService.updateSettings(this.gameId!, this.user, key, value); diff --git a/packages/misskey-js/etc/misskey-js.api.md b/packages/misskey-js/etc/misskey-js.api.md index 16cb560a52..77a3820f46 100644 --- a/packages/misskey-js/etc/misskey-js.api.md +++ b/packages/misskey-js/etc/misskey-js.api.md @@ -2829,6 +2829,9 @@ type ReversiShowGameResponse = operations['reversi___show-game']['responses']['2 // @public (undocumented) type ReversiSurrenderRequest = operations['reversi___surrender']['requestBody']['content']['application/json']; +// @public (undocumented) +export const reversiUpdateKeys: ["map", "bw", "isLlotheo", "canPutEverywhere", "loopedBoard", "timeLimitForEachTurn"]; + // @public (undocumented) type ReversiVerifyRequest = operations['reversi___verify']['requestBody']['content']['application/json']; diff --git a/packages/misskey-js/src/consts.ts b/packages/misskey-js/src/consts.ts index aa8eeb48cb..5863a0b1dd 100644 --- a/packages/misskey-js/src/consts.ts +++ b/packages/misskey-js/src/consts.ts @@ -1,11 +1,16 @@ import type { operations } from './autogen/types.js'; import type { - AbuseReportNotificationRecipient, Ad, + AbuseReportNotificationRecipient, + Ad, Announcement, - EmojiDetailed, InviteCode, + EmojiDetailed, + InviteCode, MetaDetailed, Note, - Role, SystemWebhook, UserLite, + Role, + ReversiGameDetailed, + SystemWebhook, + UserLite, } from './autogen/models.js'; export const notificationTypes = ['note', 'follow', 'mention', 'reply', 'renote', 'quote', 'reaction', 'pollVote', 'pollEnded', 'receiveFollowRequest', 'followRequestAccepted', 'groupInvited', 'app', 'roleAssigned', 'achievementEarned'] as const; @@ -159,7 +164,7 @@ export const reversiUpdateKeys = [ 'canPutEverywhere', 'loopedBoard', 'timeLimitForEachTurn', -] as const; +] as const satisfies (keyof ReversiGameDetailed)[]; export type ReversiUpdateKey = typeof reversiUpdateKeys[number]; diff --git a/packages/misskey-js/src/index.ts b/packages/misskey-js/src/index.ts index 28007a8ade..7e0165d20b 100644 --- a/packages/misskey-js/src/index.ts +++ b/packages/misskey-js/src/index.ts @@ -22,6 +22,7 @@ export const mutedNoteReasons = consts.mutedNoteReasons; export const followingVisibilities = consts.followingVisibilities; export const followersVisibilities = consts.followersVisibilities; export const moderationLogTypes = consts.moderationLogTypes; +export const reversiUpdateKeys = consts.reversiUpdateKeys; // api extractor not supported yet //export * as api from './api.js';