UNPKG

@xrengine/server-core

Version:

Shared components for XREngine server

108 lines (93 loc) 3.4 kB
import { Hook, HookContext } from '@feathersjs/feathers' import { OpenMatchTicketAssignment } from '@xrengine/matchmaking/src/interfaces' import logger from '../ServerLogger' interface AssignmentResponse extends OpenMatchTicketAssignment { instanceId: string locationName: string } export default (): Hook => { return async (context: HookContext): Promise<HookContext> => { const app = context.app const result: AssignmentResponse = context.result const userId = context.params['identity-provider']?.userId if (!result.connection) { // if connection is empty, match is not found yet return context } const matchUserResult = await app.service('match-user').find({ query: { ticketId: context.id, $limit: 1 } }) if (!matchUserResult.data.length) { logger.info('match user not found?!') return context } const matchUser = matchUserResult.data[0] await app.service('match-user').patch(matchUser.id, { connection: result.connection }) let [matchServerInstance] = await app.service('match-instance').find({ query: { connection: result.connection } }) if (!matchServerInstance) { // try to create server instance, ignore error and try to search again, possibly someone just created same server try { matchServerInstance = await app.service('match-instance').create({ connection: result.connection, gamemode: matchUser.gamemode }) } catch (e) { logger.error('Failed to create new match-instance') const isConnectionDuplicateError = e.errors?.[0]?.type === 'unique violation' && e.errors?.[0]?.path === 'connection' if (!isConnectionDuplicateError) { // ignore only duplicate error throw e } logger.warn('^-- Server instance probably exists but not provisioned: ' + matchServerInstance) } } else { logger.info('Server instance probably exists but not provisioned: ' + matchServerInstance) } if (!matchServerInstance?.instanceserver) { for (let i = 0; i < 20 && !matchServerInstance?.instanceserver; i++) { // retry search await new Promise((resolve) => setTimeout(resolve, 10)) matchServerInstance = ( await app.service('match-instance').find({ query: { connection: result.connection } }) )[0] } } if (!matchServerInstance?.instanceserver) { // say that no connection yet, on next query it will have instanceserver and same connection logger.info('Failed to find provisioned server. Need to retry again.') result.connection = '' return context } // add user to server instance const existingInstanceAuthorizedUser = await app.service('instance-authorized-user').find({ query: { userId: userId, instanceId: matchServerInstance.instanceserver, $limit: 0 } }) if (existingInstanceAuthorizedUser.total === 0) { await app.service('instance-authorized-user').create({ userId: userId, instanceId: matchServerInstance.instanceserver }) } result.instanceId = matchServerInstance.instanceserver result.locationName = 'game-' + matchServerInstance.gamemode return context } }