From 74753135c752b7a6c173645ce822e5d3d6155036 Mon Sep 17 00:00:00 2001 From: MoizAdnan Date: Thu, 5 Oct 2023 23:29:33 +0500 Subject: [PATCH 1/4] Updated match-ticket hooks --- .../match-ticket/match-ticket.class.ts | 54 +----------------- .../match-ticket/match-ticket.hooks.ts | 55 ++++++++++++++++++- .../matchmaking/match-ticket/match-ticket.ts | 2 +- 3 files changed, 56 insertions(+), 55 deletions(-) diff --git a/packages/server-core/src/matchmaking/match-ticket/match-ticket.class.ts b/packages/server-core/src/matchmaking/match-ticket/match-ticket.class.ts index 4b797157eb9..9aab93d60e9 100755 --- a/packages/server-core/src/matchmaking/match-ticket/match-ticket.class.ts +++ b/packages/server-core/src/matchmaking/match-ticket/match-ticket.class.ts @@ -23,17 +23,12 @@ All portions of the code written by the Ethereal Engine team are Copyright © 20 Ethereal Engine. All Rights Reserved. */ -import { BadRequest, NotFound } from '@feathersjs/errors' -import { Id, Params } from '@feathersjs/feathers' -import { KnexAdapter, KnexAdapterOptions } from '@feathersjs/knex/lib' +import { Params } from '@feathersjs/feathers' +import { KnexService } from '@feathersjs/knex/lib' -import { createTicket, deleteTicket, getTicket } from '@etherealengine/matchmaking/src/functions' import { MatchTicketData, MatchTicketQuery, MatchTicketType } from '@etherealengine/matchmaking/src/match-ticket.schema' -import config from '@etherealengine/server-core/src/appconfig' -import { Application } from '../../../declarations' import { RootParams } from '../../api/root-params' -import { emulate_createTicket, emulate_getTicket } from '../emulate' // eslint-disable-next-line @typescript-eslint/no-empty-interface export interface MatchTicketParams extends RootParams {} @@ -44,47 +39,4 @@ export interface MatchTicketParams extends RootParams {} export class MatchTicketService< T = MatchTicketType, ServiceParams extends Params = MatchTicketParams -> extends KnexAdapter { - app: Application - - constructor(options: KnexAdapterOptions, app: Application) { - super(options) - this.app = app - } - - async get(id: Id, params: MatchTicketParams): Promise { - if (typeof id !== 'string' || id.length === 0) { - throw new BadRequest('Invalid ticket id, not empty string is expected') - } - - let ticket - if (config.server.matchmakerEmulationMode) { - // emulate response from open-match-api - ticket = await emulate_getTicket(this.app, id, params.user!.id) - } else { - ticket = getTicket(String(id)) - } - - if (!ticket) { - throw new NotFound() - } - return ticket as MatchTicketType - } - - async create(data: MatchTicketData) { - if (config.server.matchmakerEmulationMode) { - // emulate response from open-match-api - return emulate_createTicket(data.gameMode) - } - - return await createTicket(data.gameMode, data.attributes) - } - - async remove(id: Id) { - // skip delete in emulation, user-match will be deleted in hook - if (!config.server.matchmakerEmulationMode) { - await deleteTicket(String(id)) - } - return { id } - } -} +> extends KnexService {} diff --git a/packages/server-core/src/matchmaking/match-ticket/match-ticket.hooks.ts b/packages/server-core/src/matchmaking/match-ticket/match-ticket.hooks.ts index 0ba9a08e0b9..5c864f94aa3 100755 --- a/packages/server-core/src/matchmaking/match-ticket/match-ticket.hooks.ts +++ b/packages/server-core/src/matchmaking/match-ticket/match-ticket.hooks.ts @@ -27,6 +27,7 @@ import { hooks as schemaHooks } from '@feathersjs/schema' import { disallow, iff, isProvider } from 'feathers-hooks-common' import { + MatchTicketType, matchTicketDataValidator, matchTicketQueryValidator } from '@etherealengine/matchmaking/src/match-ticket.schema' @@ -35,7 +36,12 @@ import matchmakingRestrictMultipleQueueing from '@etherealengine/server-core/src import matchmakingSaveTicket from '@etherealengine/server-core/src/hooks/matchmaking-save-ticket' import setLoggedInUser from '@etherealengine/server-core/src/hooks/set-loggedin-user-in-body' +import { createTicket, deleteTicket, getTicket } from '@etherealengine/matchmaking/src/functions' +import { BadRequest, NotFound } from '@feathersjs/errors' +import { HookContext } from '@feathersjs/feathers' +import config from '../../appconfig' import authenticate from '../../hooks/authenticate' +import { emulate_createTicket, emulate_getTicket } from '../emulate' import { matchTicketDataResolver, matchTicketExternalResolver, @@ -43,6 +49,44 @@ import { matchTicketResolver } from './match-ticket.resolvers' +const ensureId = async (context: HookContext) => { + if (typeof context.id !== 'string' || context.id.length === 0) { + throw new BadRequest('Invalid ticket id, not empty string is expected') + } +} + +const getEmulationTicket = async (context: HookContext) => { + let ticket + if (config.server.matchmakerEmulationMode) { + // emulate response from open-match-api + ticket = await emulate_getTicket(context.service, context.id, context.params.user!.id) + } else { + ticket = getTicket(String(context.id!)) + } + + if (!ticket) { + throw new NotFound() + } + context.result = ticket as MatchTicketType +} + +const createInEmulation = async (context: HookContext) => { + if (config.server.matchmakerEmulationMode) { + // emulate response from open-match-api + return emulate_createTicket(context.data.gameMode) + } + + context.result = await createTicket(context.data.gameMode, context.data.attributes) +} + +const skipDeleteInEmulation = async (context: HookContext) => { + if (!config.server.matchmakerEmulationMode) { + await deleteTicket(String(context.id)) + } + + context.result = undefined +} + export default { around: { all: [schemaHooks.resolveExternal(matchTicketExternalResolver), schemaHooks.resolveResult(matchTicketResolver)] @@ -54,17 +98,22 @@ export default { schemaHooks.resolveQuery(matchTicketQueryResolver) ], find: [], - get: [iff(isProvider('external'), authenticate() as any, setLoggedInUser('userId') as any)], + get: [ + iff(isProvider('external'), authenticate() as any, setLoggedInUser('userId') as any), + ensureId, + getEmulationTicket + ], create: [ iff(isProvider('external'), authenticate() as any, setLoggedInUser('userId') as any), matchmakingRestrictMultipleQueueing(), // addUUID(), () => schemaHooks.validateData(matchTicketDataValidator), - schemaHooks.resolveData(matchTicketDataResolver) + schemaHooks.resolveData(matchTicketDataResolver), + createInEmulation ], update: [disallow()], patch: [disallow()], - remove: [iff(isProvider('external'))] + remove: [iff(isProvider('external')), skipDeleteInEmulation] }, after: { diff --git a/packages/server-core/src/matchmaking/match-ticket/match-ticket.ts b/packages/server-core/src/matchmaking/match-ticket/match-ticket.ts index 79478e709d0..54b98c45da6 100755 --- a/packages/server-core/src/matchmaking/match-ticket/match-ticket.ts +++ b/packages/server-core/src/matchmaking/match-ticket/match-ticket.ts @@ -44,7 +44,7 @@ export default (app: Application): void => { multi: true } - app.use(matchTicketPath, new MatchTicketService(options, app), { + app.use(matchTicketPath, new MatchTicketService(options), { // A list of all methods this service exposes externally methods: matchTicketMethods, // You can add additional custom events to be sent to clients here From 7180bc40356f5c5b70e6e3f4884279b160a25bae Mon Sep 17 00:00:00 2001 From: MoizAdnan Date: Thu, 5 Oct 2023 23:34:42 +0500 Subject: [PATCH 2/4] Updated match-ticket-assignment hooks --- .../match-ticket-assignment.class.ts | 35 ++----------------- .../match-ticket-assignment.hooks.ts | 33 +++++++++++++++-- .../match-ticket-assignment.ts | 2 +- 3 files changed, 35 insertions(+), 35 deletions(-) diff --git a/packages/server-core/src/matchmaking/match-ticket-assignment/match-ticket-assignment.class.ts b/packages/server-core/src/matchmaking/match-ticket-assignment/match-ticket-assignment.class.ts index e39a95866cc..ed0e89c5e99 100755 --- a/packages/server-core/src/matchmaking/match-ticket-assignment/match-ticket-assignment.class.ts +++ b/packages/server-core/src/matchmaking/match-ticket-assignment/match-ticket-assignment.class.ts @@ -23,21 +23,15 @@ All portions of the code written by the Ethereal Engine team are Copyright © 20 Ethereal Engine. All Rights Reserved. */ -import { NotFound } from '@feathersjs/errors' -import { Id, Params } from '@feathersjs/feathers' -import { KnexAdapter, KnexAdapterOptions } from '@feathersjs/knex/lib' +import { Params } from '@feathersjs/feathers' +import { KnexService } from '@feathersjs/knex/lib' -import { getTicketsAssignment } from '@etherealengine/matchmaking/src/functions' import { MatchTicketAssignmentQuery, MatchTicketAssignmentType } from '@etherealengine/matchmaking/src/match-ticket-assignment.schema' -import config from '@etherealengine/server-core/src/appconfig' -import { identityProviderPath } from '@etherealengine/engine/src/schemas/user/identity-provider.schema' -import { Application } from '../../../declarations' import { RootParams } from '../../api/root-params' -import { emulate_getTicketsAssignment } from '../emulate' // eslint-disable-next-line @typescript-eslint/no-empty-interface export interface MatchTicketAssignmentParams extends RootParams {} @@ -48,27 +42,4 @@ export interface MatchTicketAssignmentParams extends RootParams extends KnexAdapter { - app: Application - - constructor(options: KnexAdapterOptions, app: Application) { - super(options) - this.app = app - } - - async get(id: Id, params: MatchTicketAssignmentParams) { - let assignment: MatchTicketAssignmentType - try { - if (config.server.matchmakerEmulationMode) { - assignment = await emulate_getTicketsAssignment(this.app, id, params[identityProviderPath].userId) - } else { - assignment = await getTicketsAssignment(String(id)) - } - } catch (e) { - // todo: handle other errors. like no connection, etc.... - throw new NotFound(e.message, e) - } - - return assignment - } -} +> extends KnexService {} diff --git a/packages/server-core/src/matchmaking/match-ticket-assignment/match-ticket-assignment.hooks.ts b/packages/server-core/src/matchmaking/match-ticket-assignment/match-ticket-assignment.hooks.ts index 428504f0b8e..f768cbc118d 100755 --- a/packages/server-core/src/matchmaking/match-ticket-assignment/match-ticket-assignment.hooks.ts +++ b/packages/server-core/src/matchmaking/match-ticket-assignment/match-ticket-assignment.hooks.ts @@ -26,15 +26,44 @@ Ethereal Engine. All Rights Reserved. import { hooks as schemaHooks } from '@feathersjs/schema' import { disallow } from 'feathers-hooks-common' -import { matchTicketAssignmentQueryValidator } from '@etherealengine/matchmaking/src/match-ticket-assignment.schema' +import { + MatchTicketAssignmentType, + matchTicketAssignmentQueryValidator +} from '@etherealengine/matchmaking/src/match-ticket-assignment.schema' import linkMatchUserToMatch from '@etherealengine/server-core/src/hooks/matchmaking-link-match-user-to-match' +import { identityProviderPath } from '@etherealengine/engine/src/schemas/user/identity-provider.schema' +import { getTicketsAssignment } from '@etherealengine/matchmaking/src/functions' +import { NotFound } from '@feathersjs/errors' +import { HookContext } from '@feathersjs/feathers' +import config from '../../appconfig' +import { emulate_getTicketsAssignment } from '../emulate' import { matchTicketAssignmentExternalResolver, matchTicketAssignmentQueryResolver, matchTicketAssignmentResolver } from './match-ticket-assignment.resolvers' +const getTicketAssigment = async (context: HookContext) => { + let assignment: MatchTicketAssignmentType + try { + if (config.server.matchmakerEmulationMode) { + assignment = await emulate_getTicketsAssignment( + context.service, + context.id, + context.params[identityProviderPath].userId + ) + } else { + assignment = await getTicketsAssignment(String(context.id)) + } + } catch (e) { + // todo: handle other errors. like no connection, etc.... + throw new NotFound(e.message, e) + } + + context.result = assignment +} + export default { around: { all: [ @@ -49,7 +78,7 @@ export default { schemaHooks.resolveQuery(matchTicketAssignmentQueryResolver) ], find: [], - get: [], + get: [getTicketAssigment], create: [disallow()], update: [disallow()], patch: [disallow()], diff --git a/packages/server-core/src/matchmaking/match-ticket-assignment/match-ticket-assignment.ts b/packages/server-core/src/matchmaking/match-ticket-assignment/match-ticket-assignment.ts index 652594252aa..baef0a4311a 100755 --- a/packages/server-core/src/matchmaking/match-ticket-assignment/match-ticket-assignment.ts +++ b/packages/server-core/src/matchmaking/match-ticket-assignment/match-ticket-assignment.ts @@ -47,7 +47,7 @@ export default (app: Application): void => { multi: true } - app.use(matchTicketAssignmentPath, new MatchTicketAssignmentService(options, app), { + app.use(matchTicketAssignmentPath, new MatchTicketAssignmentService(options), { // A list of all methods this service exposes externally methods: matchTicketAssignmentMethods, // You can add additional custom events to be sent to clients here From 396354867f5ad4cc1b2124d8246c7d80e0fc63ce Mon Sep 17 00:00:00 2001 From: MoizAdnan Date: Wed, 18 Oct 2023 07:39:35 +0500 Subject: [PATCH 3/4] Added typed hook context --- .../match-ticket-assignment.hooks.ts | 5 ++-- .../match-ticket/match-ticket.hooks.ts | 30 +++++++++++++------ 2 files changed, 24 insertions(+), 11 deletions(-) diff --git a/packages/server-core/src/matchmaking/match-ticket-assignment/match-ticket-assignment.hooks.ts b/packages/server-core/src/matchmaking/match-ticket-assignment/match-ticket-assignment.hooks.ts index f768cbc118d..834b15742bf 100755 --- a/packages/server-core/src/matchmaking/match-ticket-assignment/match-ticket-assignment.hooks.ts +++ b/packages/server-core/src/matchmaking/match-ticket-assignment/match-ticket-assignment.hooks.ts @@ -35,16 +35,17 @@ import linkMatchUserToMatch from '@etherealengine/server-core/src/hooks/matchmak import { identityProviderPath } from '@etherealengine/engine/src/schemas/user/identity-provider.schema' import { getTicketsAssignment } from '@etherealengine/matchmaking/src/functions' import { NotFound } from '@feathersjs/errors' -import { HookContext } from '@feathersjs/feathers' +import { HookContext } from '../../../declarations' import config from '../../appconfig' import { emulate_getTicketsAssignment } from '../emulate' +import { MatchTicketAssignmentService } from './match-ticket-assignment.class' import { matchTicketAssignmentExternalResolver, matchTicketAssignmentQueryResolver, matchTicketAssignmentResolver } from './match-ticket-assignment.resolvers' -const getTicketAssigment = async (context: HookContext) => { +const getTicketAssigment = async (context: HookContext) => { let assignment: MatchTicketAssignmentType try { if (config.server.matchmakerEmulationMode) { diff --git a/packages/server-core/src/matchmaking/match-ticket/match-ticket.hooks.ts b/packages/server-core/src/matchmaking/match-ticket/match-ticket.hooks.ts index 5c864f94aa3..25f1be3abfd 100755 --- a/packages/server-core/src/matchmaking/match-ticket/match-ticket.hooks.ts +++ b/packages/server-core/src/matchmaking/match-ticket/match-ticket.hooks.ts @@ -27,6 +27,7 @@ import { hooks as schemaHooks } from '@feathersjs/schema' import { disallow, iff, isProvider } from 'feathers-hooks-common' import { + MatchTicketData, MatchTicketType, matchTicketDataValidator, matchTicketQueryValidator @@ -38,10 +39,11 @@ import setLoggedInUser from '@etherealengine/server-core/src/hooks/set-loggedin- import { createTicket, deleteTicket, getTicket } from '@etherealengine/matchmaking/src/functions' import { BadRequest, NotFound } from '@feathersjs/errors' -import { HookContext } from '@feathersjs/feathers' +import { HookContext } from '../../../declarations' import config from '../../appconfig' import authenticate from '../../hooks/authenticate' import { emulate_createTicket, emulate_getTicket } from '../emulate' +import { MatchTicketService } from './match-ticket.class' import { matchTicketDataResolver, matchTicketExternalResolver, @@ -49,13 +51,13 @@ import { matchTicketResolver } from './match-ticket.resolvers' -const ensureId = async (context: HookContext) => { +const ensureId = async (context: HookContext) => { if (typeof context.id !== 'string' || context.id.length === 0) { throw new BadRequest('Invalid ticket id, not empty string is expected') } } -const getEmulationTicket = async (context: HookContext) => { +const getEmulationTicket = async (context: HookContext) => { let ticket if (config.server.matchmakerEmulationMode) { // emulate response from open-match-api @@ -70,16 +72,26 @@ const getEmulationTicket = async (context: HookContext) => { context.result = ticket as MatchTicketType } -const createInEmulation = async (context: HookContext) => { - if (config.server.matchmakerEmulationMode) { - // emulate response from open-match-api - return emulate_createTicket(context.data.gameMode) +const createInEmulation = async (context: HookContext) => { + if (!context.data || context.method !== 'create') { + throw new BadRequest(`${context.path} service only works for data in ${context.method}`) } - context.result = await createTicket(context.data.gameMode, context.data.attributes) + const data: MatchTicketData[] = Array.isArray(context.data) ? context.data : [context.data] + const result: MatchTicketType[] = [] + + for (const item of data) { + if (config.server.matchmakerEmulationMode) { + // emulate response from open-match-api + return emulate_createTicket(item.gameMode) + } + + result.push(await createTicket(item.gameMode, item.attributes)) + } + context.result = result } -const skipDeleteInEmulation = async (context: HookContext) => { +const skipDeleteInEmulation = async (context: HookContext) => { if (!config.server.matchmakerEmulationMode) { await deleteTicket(String(context.id)) } From e6b31b8dc121acd044afd0d77ec786c303f4c738 Mon Sep 17 00:00:00 2001 From: MoizAdnan Date: Sun, 22 Oct 2023 13:34:00 +0500 Subject: [PATCH 4/4] Added disallow non id --- .../src/matchmaking/match-ticket/match-ticket.hooks.ts | 9 ++------- 1 file changed, 2 insertions(+), 7 deletions(-) diff --git a/packages/server-core/src/matchmaking/match-ticket/match-ticket.hooks.ts b/packages/server-core/src/matchmaking/match-ticket/match-ticket.hooks.ts index a79d2a5526b..9dc24410914 100755 --- a/packages/server-core/src/matchmaking/match-ticket/match-ticket.hooks.ts +++ b/packages/server-core/src/matchmaking/match-ticket/match-ticket.hooks.ts @@ -41,6 +41,7 @@ import { createTicket, deleteTicket, getTicket } from '@etherealengine/matchmaki import { BadRequest, NotFound } from '@feathersjs/errors' import { HookContext } from '../../../declarations' import config from '../../appconfig' +import disallowNonId from '../../hooks/disallow-non-id' import { emulate_createTicket, emulate_getTicket } from '../emulate' import { MatchTicketService } from './match-ticket.class' import { @@ -50,12 +51,6 @@ import { matchTicketResolver } from './match-ticket.resolvers' -const ensureId = async (context: HookContext) => { - if (typeof context.id !== 'string' || context.id.length === 0) { - throw new BadRequest('Invalid ticket id, not empty string is expected') - } -} - const getEmulationTicket = async (context: HookContext) => { let ticket if (config.server.matchmakerEmulationMode) { @@ -109,7 +104,7 @@ export default { schemaHooks.resolveQuery(matchTicketQueryResolver) ], find: [], - get: [iff(isProvider('external'), setLoggedInUser('userId') as any), ensureId, getEmulationTicket], + get: [iff(isProvider('external'), setLoggedInUser('userId') as any), disallowNonId, getEmulationTicket], create: [ iff(isProvider('external'), setLoggedInUser('userId') as any), matchmakingRestrictMultipleQueueing(),