Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fixes a client-side bug with users' avatars missing resources. #7962

Merged
merged 1 commit into from
May 4, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
28 changes: 21 additions & 7 deletions packages/client-core/src/components/World/EngineHooks.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@ import { NotificationService } from '../../common/services/NotificationService'
import { useRouter } from '../../common/services/RouterService'
import { useLocationState } from '../../social/services/LocationService'
import { SocketWebRTCClientNetwork } from '../../transports/SocketWebRTCClientFunctions'
import { AvatarService } from '../../user/services/AvatarService'
import { startClientSystems } from '../../world/startClientSystems'

const logger = multiLogger.child({ component: 'client-core:world' })
Expand All @@ -57,6 +58,24 @@ export const useLoadEngine = () => {
}, [])
}

const fetchMissingAvatar = async (user, avatarSpawnPose) => {
const avatar = await AvatarService.getAvatar(user.avatar.id.value)
if (avatar && (avatar.modelResource?.LOD0_url || (avatar.modelResource as any)?.src))
spawnLocalAvatarInWorld({
avatarSpawnPose,
avatarDetail: {
avatarURL: avatar.modelResource?.LOD0_url || (avatar.modelResource as any)?.src,
thumbnailURL: avatar.thumbnailResource?.LOD0_url || (avatar.thumbnailResource as any)?.src
},
name: user.name.value
})
else
NotificationService.dispatchNotify(
'Your avatar is missing its model. Please change your avatar from the user menu.',
{ variant: 'error' }
)
}

export const useLocationSpawnAvatar = (spectate = false) => {
const sceneLoaded = useHookstate(getMutableState(EngineState).sceneLoaded)
const authState = useAuthState()
Expand Down Expand Up @@ -89,7 +108,7 @@ export const useLocationSpawnAvatar = (spectate = false) => {
? getSpawnPoint(spawnPoint, Engine.instance.userId)
: getRandomSpawnPoint(Engine.instance.userId)

if (avatarDetails.modelResource?.LOD0_url || (avatarDetails.modelResource as any).src)
if (avatarDetails.modelResource?.LOD0_url || (avatarDetails.modelResource as any)?.src)
spawnLocalAvatarInWorld({
avatarSpawnPose,
avatarDetail: {
Expand All @@ -98,12 +117,7 @@ export const useLocationSpawnAvatar = (spectate = false) => {
},
name: user.name.value
})
else {
NotificationService.dispatchNotify(
'Your avatar is missing its model. Please change your avatar from the user menu.',
{ variant: 'error' }
)
}
else fetchMissingAvatar(user, avatarSpawnPose)
}, [sceneLoaded, authState.user, authState.user?.avatar, spectateParam])
}

Expand Down
9 changes: 9 additions & 0 deletions packages/client-core/src/user/services/AvatarService.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import { AvatarInterface } from '@etherealengine/common/src/interfaces/AvatarInt
import { StaticResourceInterface } from '@etherealengine/common/src/interfaces/StaticResourceInterface'
import { UserId } from '@etherealengine/common/src/interfaces/UserId'
import { matches, Validator } from '@etherealengine/engine/src/common/functions/MatchesUtils'
import { Engine } from '@etherealengine/engine/src/ecs/classes/Engine'
import { WorldNetworkAction } from '@etherealengine/engine/src/networking/functions/WorldNetworkAction'
import { defineAction, defineState, dispatchAction, getMutableState, useState } from '@etherealengine/hyperflux'

Expand Down Expand Up @@ -191,6 +192,14 @@ export const AvatarService = {
isPublic
}
}).promise as Promise<StaticResourceInterface[]>
},

async getAvatar(id: string) {
try {
return Engine.instance.api.service('avatar').get(id)
} catch (err) {
return null
}
}
}

Expand Down
147 changes: 140 additions & 7 deletions packages/server-core/src/user/user/user.hooks.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import addAssociations from '@etherealengine/server-core/src/hooks/add-associati
import addScopeToUser from '../../hooks/add-scope-to-user'
import authenticate from '../../hooks/authenticate'
import verifyScope from '../../hooks/verify-scope'
import logger from '../../ServerLogger'

const restrictUserPatch = (context: HookContext) => {
if (context.params.isInternal) return context
Expand Down Expand Up @@ -89,29 +90,161 @@ const addAvatarResources = () => {
return async (context: HookContext): Promise<HookContext> => {
const { app, result } = context

if (result.avatar) {
// if (!result.data) console.log('result.avatar', result, result.avatar, result.avatar?.dataValues, result.dataValues, result.dataValues?.avatar?.dataValues,)

if (result.dataValues?.avatar) {
if (result.dataValues?.avatar.modelResourceId)
try {
result.dataValues.avatar.modelResource = await app
.service('static-resource')
.get(result.dataValues.avatar.modelResourceId)
} catch (err) {
logger.error('error getting avatar model %o', err)
}
if (result.dataValues?.avatar.dataValues?.modelResourceId)
try {
result.dataValues.avatar.dataValues.modelResource = await app
.service('static-resource')
.get(result.dataValues.avatar.dataValues.modelResourceId)
} catch (err) {
logger.error('error getting avatar model %o', err)
}
if (result.dataValues?.avatar.thumbnailResourceId)
try {
result.dataValues.avatar.thumbnailResource = await app
.service('static-resource')
.get(result.dataValues.avatar.thumbnailResourceId)
} catch (err) {
logger.error('error getting avatar model %o', err)
}
if (result.dataValues?.avatar.dataValues?.thumbnailResourceId)
try {
result.dataValues.avatar.dataValues.thumbnailResource = await app
.service('static-resource')
.get(result.dataValues.avatar.dataValues.thumbnailResourceId)
} catch (err) {
logger.error('error getting avatar model %o', err)
}
} else if (result.avatar) {
if (result.avatar.modelResourceId)
try {
result.avatar.modelResource = await app.service('static-resource').get(result.avatar.modelResourceId)
} catch (err) {}
if (result.avatar.dataValues.modelResourceId)
} catch (err) {
logger.error('error getting avatar model %o', err)
}
if (result.avatar.dataValues?.modelResourceId)
try {
result.avatar.dataValues.modelResource = await app
.service('static-resource')
.get(result.avatar.dataValues.modelResourceId)
} catch (err) {}
} catch (err) {
logger.error('error getting avatar model %o', err)
}
if (result.avatar.thumbnailResourceId)
try {
result.avatar.thumbnailResource = await app.service('static-resource').get(result.avatar.thumbnailResourceId)
} catch (err) {}
if (result.avatar.dataValues.thumbnailResourceId)
} catch (err) {
logger.error('error getting avatar model %o', err)
}
if (result.avatar.dataValues?.thumbnailResourceId)
try {
result.avatar.dataValues.thumbnailResource = await app
.service('static-resource')
.get(result.avatar.dataValues.thumbnailResourceId)
} catch (err) {}
} catch (err) {
logger.error('error getting avatar model %o', err)
}
}

// if (result.data) {
// const mappedUsers = result.data.map(user => {
// return new Promise(async (resolve, reject) => {
// if (user.avatar) {
// if (user.avatar.modelResourceId)
// try {
// user.avatar.modelResource = await app.service('static-resource').get(user.avatar.modelResourceId)
// resolve(user)
// } catch (err) {
// logger.error('error getting avatar model %o', err)
// reject(err)
// }
// if (user.avatar.dataValues?.modelResourceId)
// try {
// user.avatar.dataValues.modelResource = await app
// .service('static-resource')
// .get(user.avatar.dataValues.modelResourceId)
// resolve(user)
// } catch (err) {
// logger.error('error getting avatar model %o', err)
// reject(err)
// }
// if (user.avatar.thumbnailResourceId)
// try {
// user.avatar.thumbnailResource = await app.service('static-resource').get(user.avatar.thumbnailResourceId)
// resolve(user)
// } catch (err) {
// logger.error('error getting avatar model %o', err)
// reject(err)
// }
// if (user.avatar.dataValues?.thumbnailResourceId)
// try {
// user.avatar.dataValues.thumbnailResource = await app
// .service('static-resource')
// .get(user.avatar.dataValues.thumbnailResourceId)
// resolve(user)
// } catch (err) {
// logger.error('error getting avatar model %o', err)
// reject(err)
// }
// }
// if (user.dataValues.avatar) {
// if (user.dataValues.avatar.modelResourceId)
// try {
// user.dataValues.avatar.modelResource = await app.service('static-resource').get(user.dataValues.avatar.modelResourceId)
// resolve(user)
// } catch (err) {
// logger.error('error getting avatar model %o', err)
// reject(err)
// }
// try {
// console.log('POPULATING MUTLI DATAVALUES MODELRESOURCE')
// user.dataValues.avatar.dataValues.modelResource = await app
// .service('static-resource')
// .get(user.dataValues.avatar.dataValues.modelResourceId)
// console.log('DONE POPULATED MUTLI DATAVALUES MODELRESOURCE', user, user.dataValues.avatar.dataValues)
// resolve(user)
// } catch (err) {
// logger.error('error getting avatar model %o', err)
// reject(err)
// }
// if (user.dataValues.avatar.thumbnailResourceId)
// try {
// user.dataValues.avatar.thumbnailResource = await app.service('static-resource').get(user.dataValues.avatar.thumbnailResourceId)
// resolve(user)
// } catch (err) {
// logger.error('error getting avatar model %o', err)
// reject(err)
// }
// if (user.dataValues.avatar.dataValues?.thumbnailResourceId)
// try {
// user.dataValues.avatar.dataValues.thumbnailResource = await app
// .service('static-resource')
// .get(user.dataValues.avatar.dataValues.thumbnailResourceId)
// resolve(user)
// } catch (err) {
// logger.error('error getting avatar model %o', err)
// reject(err)
// }
// }
// })
// })
// console.log('promises', mappedUsers)
// await Promise.all(mappedUsers)
// result.data = mappedUsers
// }

// if (!result.data) console.log('Returned result.avatar', result, result.avatar, result.avatar?.dataValues, result.dataValues?.avatar?.dataValues)
// if (result.data && result.total > 0) console.log('nested user', result.data[0].avatar.dataValues)
return context
}
}
Expand Down
Loading