From 85bc92bae95fe7ecccc7069e19ea6ca4089899da Mon Sep 17 00:00:00 2001 From: kozakura913 <98575220+kozakura913@users.noreply.github.com> Date: Tue, 27 Aug 2024 09:22:58 +0900 Subject: [PATCH 1/6] wip --- packages/backend/src/core/activitypub/models/ApGameService.ts | 1 + packages/backend/src/server/NodeinfoServerService.ts | 2 ++ 2 files changed, 3 insertions(+) diff --git a/packages/backend/src/core/activitypub/models/ApGameService.ts b/packages/backend/src/core/activitypub/models/ApGameService.ts index 1581904a7b..2ce38867af 100644 --- a/packages/backend/src/core/activitypub/models/ApGameService.ts +++ b/packages/backend/src/core/activitypub/models/ApGameService.ts @@ -21,6 +21,7 @@ import type { IApReversi } from '../type.js'; @Injectable() export class ApGameService { private logger: Logger; + static reversiVersion: string="1.0-yojo"; constructor( @Inject(DI.config) diff --git a/packages/backend/src/server/NodeinfoServerService.ts b/packages/backend/src/server/NodeinfoServerService.ts index d993598f5e..62b26d5d44 100644 --- a/packages/backend/src/server/NodeinfoServerService.ts +++ b/packages/backend/src/server/NodeinfoServerService.ts @@ -14,6 +14,7 @@ import { bindThis } from '@/decorators.js'; import NotesChart from '@/core/chart/charts/notes.js'; import UsersChart from '@/core/chart/charts/users.js'; import { DEFAULT_POLICIES } from '@/core/RoleService.js'; +import { ApGameService } from '@/core/activitypub/models/ApGameService.js'; import type { FastifyInstance, FastifyPluginOptions } from 'fastify'; const nodeinfo2_1path = '/nodeinfo/2.1'; @@ -131,6 +132,7 @@ export class NodeinfoServerService { enableServiceWorker: meta.enableServiceWorker, proxyAccountName: proxyAccount ? proxyAccount.username : null, themeColor: meta.themeColor ?? '#ffbcdc', + reversiVersion: ApGameService.reversiVersion, }, }; if (version >= 21) { From 9f23813d06fe654b782885f9d42470df38c12ca1 Mon Sep 17 00:00:00 2001 From: kozakura913 <98575220+kozakura913@users.noreply.github.com> Date: Tue, 27 Aug 2024 09:37:04 +0900 Subject: [PATCH 2/6] reversiVersion --- packages/backend/src/core/activitypub/models/ApGameService.ts | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/packages/backend/src/core/activitypub/models/ApGameService.ts b/packages/backend/src/core/activitypub/models/ApGameService.ts index 2ce38867af..20ca4954d2 100644 --- a/packages/backend/src/core/activitypub/models/ApGameService.ts +++ b/packages/backend/src/core/activitypub/models/ApGameService.ts @@ -21,7 +21,8 @@ import type { IApReversi } from '../type.js'; @Injectable() export class ApGameService { private logger: Logger; - static reversiVersion: string="1.0-yojo"; + //semverに従って割り当てる + static reversiVersion: string="1.0.0-yojo"; constructor( @Inject(DI.config) From f48260167f8d95133b9fd61cf0df7ef4b5a19236 Mon Sep 17 00:00:00 2001 From: kozakura913 <98575220+kozakura913@users.noreply.github.com> Date: Tue, 27 Aug 2024 10:55:11 +0900 Subject: [PATCH 3/6] wip --- .../src/core/FetchInstanceMetadataService.ts | 3 +- .../core/activitypub/models/ApGameService.ts | 33 +++++++++++++++++++ 2 files changed, 35 insertions(+), 1 deletion(-) diff --git a/packages/backend/src/core/FetchInstanceMetadataService.ts b/packages/backend/src/core/FetchInstanceMetadataService.ts index 3f3171327e..8848c109c2 100644 --- a/packages/backend/src/core/FetchInstanceMetadataService.ts +++ b/packages/backend/src/core/FetchInstanceMetadataService.ts @@ -34,6 +34,7 @@ type NodeInfo = { email?: unknown; }; themeColor?: unknown; + reversiVersion?: unknown; }; }; @@ -138,7 +139,7 @@ export class FetchInstanceMetadataService { } @bindThis - private async fetchNodeinfo(instance: MiInstance): Promise { + public async fetchNodeinfo(instance: MiInstance): Promise { this.logger.info(`Fetching nodeinfo of ${instance.host} ...`); try { diff --git a/packages/backend/src/core/activitypub/models/ApGameService.ts b/packages/backend/src/core/activitypub/models/ApGameService.ts index 20ca4954d2..49f2441ca1 100644 --- a/packages/backend/src/core/activitypub/models/ApGameService.ts +++ b/packages/backend/src/core/activitypub/models/ApGameService.ts @@ -13,6 +13,8 @@ import { NotificationService } from '@/core/NotificationService.js'; import { ReversiService } from '@/core/ReversiService.js'; import { GlobalEventService } from '@/core/GlobalEventService.js'; import type { ReversiGamesRepository } from '@/models/_.js'; +import { FetchInstanceMetadataService } from '@/core/FetchInstanceMetadataService.js'; +import { FederatedInstanceService } from '@/core/FederatedInstanceService.js'; import { ApLoggerService } from '../ApLoggerService.js'; import { ApResolverService } from '../ApResolverService.js'; import { UserEntityService } from '../../entities/UserEntityService.js'; @@ -41,6 +43,8 @@ export class ApGameService { private apLoggerService: ApLoggerService, //ReversiServiceを先に初期化するのでReversiServiceからApGameServiceを利用してはいけない private reversiService: ReversiService, + private federatedInstanceService: FederatedInstanceService, + private fetchInstanceMetadataService: FetchInstanceMetadataService, ) { this.logger = this.apLoggerService.logger; } @@ -91,10 +95,39 @@ export class ApGameService { this.reversiService.cancelGame(id, remote_user); } } + async reversiVersion(host:string): Promise { + const cache = await this.redisClient.get(`reversi:federation:version:${host}`); + if (cache !== null) { + return cache.length === 0 ? null : cache; + } + const instance = await this.federatedInstanceService.fetch(host); + const nodeinfo = await this.fetchInstanceMetadataService.fetchNodeinfo(instance); + const reversiVersion = nodeinfo.metadata?.reversiVersion; + if (typeof(reversiVersion) === 'string') { + //0.0.0-foo => 0.0.0 + const version = reversiVersion.split('-')[0]; + await this.redisClient.setex(`reversi:federation:version:${host}`, version, 5 * 60); + return version; + } + await this.redisClient.setex(`reversi:federation:version:${host}`, '', 5 * 60); + return null; + } async reversiInboxJoin(local_user: MiUser, remote_user: MiRemoteUser, game: IApReversi) { const targetUser = local_user; const fromUser = remote_user; if (!game.game_state.game_session_id) throw Error('bad session' + JSON.stringify(game)); + let version = await this.reversiVersion(remote_user.host); + if (version === null) { + //初期の実装はバージョンを返さない + version = '1.0.0'; + } + const versionElements = version.split('.'); + if (versionElements.length === 3) { + if (versionElements[0] !== ApGameService.reversiVersion.split('-')[0].split('.')[0]) { + //メジャーバージョン不一致 + return; + } + } const redisPipeline = this.redisClient.pipeline(); redisPipeline.zadd(`reversi:matchSpecific:${targetUser.id}`, Date.now(), JSON.stringify( { from_user_id: fromUser.id, From bf05ffc422ac33c88380b93b060ce856f4fe91f8 Mon Sep 17 00:00:00 2001 From: kozakura913 <98575220+kozakura913@users.noreply.github.com> Date: Tue, 27 Aug 2024 10:55:50 +0900 Subject: [PATCH 4/6] lint --- packages/backend/src/core/activitypub/models/ApGameService.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/backend/src/core/activitypub/models/ApGameService.ts b/packages/backend/src/core/activitypub/models/ApGameService.ts index 49f2441ca1..cd15610484 100644 --- a/packages/backend/src/core/activitypub/models/ApGameService.ts +++ b/packages/backend/src/core/activitypub/models/ApGameService.ts @@ -24,7 +24,7 @@ import type { IApReversi } from '../type.js'; export class ApGameService { private logger: Logger; //semverに従って割り当てる - static reversiVersion: string="1.0.0-yojo"; + static reversiVersion = '1.0.0-yojo'; constructor( @Inject(DI.config) From 7fda25a244721b1f5469b07917dddd44a1002bea Mon Sep 17 00:00:00 2001 From: kozakura913 <98575220+kozakura913@users.noreply.github.com> Date: Tue, 27 Aug 2024 11:12:43 +0900 Subject: [PATCH 5/6] mv --- packages/backend/src/core/ReversiService.ts | 42 +++++++++++++++++++ .../core/activitypub/models/ApGameService.ts | 38 ++--------------- .../src/server/NodeinfoServerService.ts | 5 ++- 3 files changed, 49 insertions(+), 36 deletions(-) diff --git a/packages/backend/src/core/ReversiService.ts b/packages/backend/src/core/ReversiService.ts index 1eba515d12..67f03b200d 100644 --- a/packages/backend/src/core/ReversiService.ts +++ b/packages/backend/src/core/ReversiService.ts @@ -24,6 +24,9 @@ import { NotificationService } from '@/core/NotificationService.js'; import { Serialized } from '@/types.js'; import { trackPromise } from '@/misc/promise-tracker.js'; import type Logger from '@/logger.js'; +import { FetchInstanceMetadataService } from '@/core/FetchInstanceMetadataService.js'; +import { FederatedInstanceService } from '@/core/FederatedInstanceService.js'; +import { NodeinfoServerService } from '@/server/NodeinfoServerService.js'; import { ReversiGameEntityService } from './entities/ReversiGameEntityService.js'; import { ApRendererService } from './activitypub/ApRendererService.js'; import { ApDeliverManagerService } from './activitypub/ApDeliverManagerService.js'; @@ -36,6 +39,8 @@ const INVITATION_TIMEOUT_MS = 1000 * 20; // 20sec export class ReversiService implements OnApplicationShutdown, OnModuleInit { private notificationService: NotificationService; private logger: Logger; + //semverに従って割り当てる + static federationVersion = '1.0.0-yojo'; constructor( private moduleRef: ModuleRef, @@ -54,6 +59,8 @@ export class ReversiService implements OnApplicationShutdown, OnModuleInit { private apDeliverManagerService: ApDeliverManagerService, private loggerService: LoggerService, private idService: IdService, + private federatedInstanceService: FederatedInstanceService, + private fetchInstanceMetadataService: FetchInstanceMetadataService, ) { this.logger = this.loggerService.getLogger('reversi'); } @@ -100,6 +107,41 @@ export class ReversiService implements OnApplicationShutdown, OnModuleInit { } satisfies Partial; } + @bindThis + public async remoteVersion(host:string): Promise { + const cache = await this.redisClient.get(`reversi:federation:version:${host}`); + if (cache !== null) { + return cache.length === 0 ? null : cache; + } + const instance = await this.federatedInstanceService.fetch(host); + const nodeinfo = await this.fetchInstanceMetadataService.fetchNodeinfo(instance); + const reversiVersion = nodeinfo.metadata?.reversiVersion; + if (typeof(reversiVersion) === 'string') { + //0.0.0-foo => 0.0.0 + const version = reversiVersion.split('-')[0]; + await this.redisClient.setex(`reversi:federation:version:${host}`, version, 5 * 60); + return version; + } + await this.redisClient.setex(`reversi:federation:version:${host}`, '', 5 * 60); + return null; + } + @bindThis + public async federationAvailable(host:string): Promise { + const version = await this.remoteVersion(host); + if (version === null) { + //初期の実装はバージョンを返さない + return null; + } + const versionElements = version.split('.'); + if (versionElements.length === 3) { + if (versionElements[0] !== NodeinfoServerService.reversiVersion.split('-')[0].split('.')[0]) { + //メジャーバージョン不一致 + return false; + } + } + return true; + } + @bindThis public async matchSpecificUser(me: MiUser, targetUser: MiUser, multiple = false, accept_only = false): Promise { if (targetUser.id === me.id) { diff --git a/packages/backend/src/core/activitypub/models/ApGameService.ts b/packages/backend/src/core/activitypub/models/ApGameService.ts index cd15610484..a89be674ca 100644 --- a/packages/backend/src/core/activitypub/models/ApGameService.ts +++ b/packages/backend/src/core/activitypub/models/ApGameService.ts @@ -13,8 +13,7 @@ import { NotificationService } from '@/core/NotificationService.js'; import { ReversiService } from '@/core/ReversiService.js'; import { GlobalEventService } from '@/core/GlobalEventService.js'; import type { ReversiGamesRepository } from '@/models/_.js'; -import { FetchInstanceMetadataService } from '@/core/FetchInstanceMetadataService.js'; -import { FederatedInstanceService } from '@/core/FederatedInstanceService.js'; +import { NodeinfoServerService } from '@/server/NodeinfoServerService.js'; import { ApLoggerService } from '../ApLoggerService.js'; import { ApResolverService } from '../ApResolverService.js'; import { UserEntityService } from '../../entities/UserEntityService.js'; @@ -23,8 +22,6 @@ import type { IApReversi } from '../type.js'; @Injectable() export class ApGameService { private logger: Logger; - //semverに従って割り当てる - static reversiVersion = '1.0.0-yojo'; constructor( @Inject(DI.config) @@ -43,8 +40,6 @@ export class ApGameService { private apLoggerService: ApLoggerService, //ReversiServiceを先に初期化するのでReversiServiceからApGameServiceを利用してはいけない private reversiService: ReversiService, - private federatedInstanceService: FederatedInstanceService, - private fetchInstanceMetadataService: FetchInstanceMetadataService, ) { this.logger = this.apLoggerService.logger; } @@ -95,38 +90,13 @@ export class ApGameService { this.reversiService.cancelGame(id, remote_user); } } - async reversiVersion(host:string): Promise { - const cache = await this.redisClient.get(`reversi:federation:version:${host}`); - if (cache !== null) { - return cache.length === 0 ? null : cache; - } - const instance = await this.federatedInstanceService.fetch(host); - const nodeinfo = await this.fetchInstanceMetadataService.fetchNodeinfo(instance); - const reversiVersion = nodeinfo.metadata?.reversiVersion; - if (typeof(reversiVersion) === 'string') { - //0.0.0-foo => 0.0.0 - const version = reversiVersion.split('-')[0]; - await this.redisClient.setex(`reversi:federation:version:${host}`, version, 5 * 60); - return version; - } - await this.redisClient.setex(`reversi:federation:version:${host}`, '', 5 * 60); - return null; - } async reversiInboxJoin(local_user: MiUser, remote_user: MiRemoteUser, game: IApReversi) { const targetUser = local_user; const fromUser = remote_user; if (!game.game_state.game_session_id) throw Error('bad session' + JSON.stringify(game)); - let version = await this.reversiVersion(remote_user.host); - if (version === null) { - //初期の実装はバージョンを返さない - version = '1.0.0'; - } - const versionElements = version.split('.'); - if (versionElements.length === 3) { - if (versionElements[0] !== ApGameService.reversiVersion.split('-')[0].split('.')[0]) { - //メジャーバージョン不一致 - return; - } + if (await this.reversiService.federationAvailable(remote_user.host) === false) { + //確実に利用できない時 + return; } const redisPipeline = this.redisClient.pipeline(); redisPipeline.zadd(`reversi:matchSpecific:${targetUser.id}`, Date.now(), JSON.stringify( { diff --git a/packages/backend/src/server/NodeinfoServerService.ts b/packages/backend/src/server/NodeinfoServerService.ts index 62b26d5d44..2d1deaa142 100644 --- a/packages/backend/src/server/NodeinfoServerService.ts +++ b/packages/backend/src/server/NodeinfoServerService.ts @@ -14,7 +14,6 @@ import { bindThis } from '@/decorators.js'; import NotesChart from '@/core/chart/charts/notes.js'; import UsersChart from '@/core/chart/charts/users.js'; import { DEFAULT_POLICIES } from '@/core/RoleService.js'; -import { ApGameService } from '@/core/activitypub/models/ApGameService.js'; import type { FastifyInstance, FastifyPluginOptions } from 'fastify'; const nodeinfo2_1path = '/nodeinfo/2.1'; @@ -23,6 +22,8 @@ const nodeinfo_homepage = 'https://misskey-hub.net'; @Injectable() export class NodeinfoServerService { + //semverに従って割り当てる + static reversiVersion = '1.0.0-yojo'; constructor( @Inject(DI.config) private config: Config, @@ -132,7 +133,7 @@ export class NodeinfoServerService { enableServiceWorker: meta.enableServiceWorker, proxyAccountName: proxyAccount ? proxyAccount.username : null, themeColor: meta.themeColor ?? '#ffbcdc', - reversiVersion: ApGameService.reversiVersion, + reversiVersion: NodeinfoServerService.reversiVersion, }, }; if (version >= 21) { From 82632c3dd720d3817d48f42238840072a7c2b326 Mon Sep 17 00:00:00 2001 From: kozakura913 <98575220+kozakura913@users.noreply.github.com> Date: Tue, 27 Aug 2024 12:10:36 +0900 Subject: [PATCH 6/6] rm --- packages/backend/src/core/ReversiService.ts | 2 -- 1 file changed, 2 deletions(-) diff --git a/packages/backend/src/core/ReversiService.ts b/packages/backend/src/core/ReversiService.ts index 67f03b200d..35c8b95cdf 100644 --- a/packages/backend/src/core/ReversiService.ts +++ b/packages/backend/src/core/ReversiService.ts @@ -39,8 +39,6 @@ const INVITATION_TIMEOUT_MS = 1000 * 20; // 20sec export class ReversiService implements OnApplicationShutdown, OnModuleInit { private notificationService: NotificationService; private logger: Logger; - //semverに従って割り当てる - static federationVersion = '1.0.0-yojo'; constructor( private moduleRef: ModuleRef,