lsp-yggdrasil/src/routes/session.js

177 lines
5.3 KiB
JavaScript

import { getOverrideHandler, getOverridePreHandler } from '../config.js'
import { toSymboUUID } from '../generator.js'
import { getPlayerSerialization, Player, PlayerSeriliazationSchema } from '../models/player.js'
import { Token } from '../models/token.js'
/*
Key: string Username
Value: {
accessToken: string,
serverId: string,
ip: string
}
*/
const joinServerRequest = new Map()
export const join = {
method: 'POST',
url: '/sessionserver/session/minecraft/join',
schema: {
summary: "加入服务器",
description: "详情请见 authlib-injector 文档。",
tags: [ "Sessionserver" ],
body: {
"accessToken": {
"type": "string"
},
"selectedProfile": {
"type": "string"
},
"serverId": {
"type": "string"
},
},
response: {
204: {
type: "null"
}
}
},
preHandler: getOverridePreHandler('/sessionserver/session/minecraft/join'),
handler: getOverrideHandler('/sessionserver/session/minecraft/join') ?? async function (req, rep) {
const { accessToken, selectedProfile, serverId } = req.body
const user = await await Player.findOne({ uuid: toSymboUUID(selectedProfile) })
if (!user) {
return await rep.code(400).send({
error: "IllegalArgumentException",
errorMessage: "请求内容不正确",
cause: "用户不存在"
})
}
const session = await Token.findOne({ token: accessToken })
if (!session) {
return await rep.code(401).send({
error: "IllegalArgumentException",
errorMessage: "无效会话",
cause: "无效会话"
})
}
if (Date.now() > session.expireDate) {
return await rep.code(401).send({
error: "IllegalArgumentException",
errorMessage: "无效会话",
cause: "会话已过期"
})
}
joinServerRequest.set(session.uuid, {
accessToken: accessToken,
serverId: serverId,
ip: req.headers['x-forwarded-for'] || req.ip
})
await rep.code(204).send()
}
}
export const hasJoined = {
method: 'GET',
url: '/sessionserver/session/minecraft/hasJoined',
schema: {
summary: "查询是否已加入服务器",
description: "详情请见 authlib-injector 文档。",
tags: [ "Sessionserver" ],
query: {
"username": {
"type": "string"
},
"serverId": {
"type": "string"
},
"ip": {
"type": "string"
}
},
response: {
200: PlayerSeriliazationSchema,
204: {
type: "null"
}
}
},
preHandler: getOverridePreHandler('/sessionserver/session/minecraft/hasJoined'),
handler: getOverrideHandler('/sessionserver/session/minecraft/hasJoined') ?? async function (req, rep) {
const { username, serverId, ip } = req.query
const player = await Player.findOne({ username })
if (!player) {
return await rep.code(400).send({
error: "IllegalArgumentException",
errorMessage: "请求内容不正确",
cause: "用户不存在"
})
}
const request = joinServerRequest.get(player.uuid)
this.log.info(request)
if(ip) {
if(ip !== request.ip) {
return await rep.code(401).send({
error: "IllegalArgumentException",
errorMessage: "无效会话",
cause: "IP 不匹配"
})
}
}
if(serverId !== request.serverId) {
return await rep.code(401).send({
error: "IllegalArgumentException",
errorMessage: "无效会话",
cause: "服务器 ID 不匹配"
})
}
await rep.code(200).send(getPlayerSerialization(player))
}
}
export const profile = {
method: 'GET',
url: '/sessionserver/session/minecraft/profile/:uuid',
schema: {
summary: "获取玩家 Profile",
description: "详情请见 authlib-injector 文档。",
tags: [ "Sessionserver" ],
params: {
"uuid": {
"type": "string"
},
unsigned: {
"type": "boolean",
"optional": true
},
},
response: {
200: PlayerSeriliazationSchema,
204: {
type: "null"
}
}
},
preHandler: getOverridePreHandler('/sessionserver/session/minecraft/profile/:uuid'),
handler: getOverrideHandler('/sessionserver/session/minecraft/profile/:uuid') ?? async function (req, rep) {
const { uuid } = req.params
const player = await Player.findOne({ uuid: toSymboUUID(uuid) })
if (!player) {
return await rep.code(204).send()
}
await rep.code(200).send(getPlayerSerialization(player))
}
}