205 lines
6.6 KiB
JavaScript
205 lines
6.6 KiB
JavaScript
import { fastify } from 'fastify'
|
|
import { mongoose } from 'mongoose'
|
|
import * as Hooks from './hooks.js'
|
|
import * as AuthenticateRoutings from './routes/authenticate.js'
|
|
import * as SessionServerRoutings from './routes/session.js'
|
|
import * as WebAPIRoutings from './routes/web-api.js'
|
|
import { config } from './config.js'
|
|
import { readFileSync } from 'fs'
|
|
import { Scenes, session, Telegraf } from 'telegraf'
|
|
import { registerAllPlayerCommands } from './telegram/player-commands.js'
|
|
import { Player } from './models/player.js'
|
|
import fastifySwagger from '@fastify/swagger'
|
|
import { S3Client } from '@aws-sdk/client-s3'
|
|
import pino from 'pino'
|
|
|
|
String.prototype._split = String.prototype.split
|
|
|
|
String.prototype.split = function(separator, limit) {
|
|
if (separator === undefined && limit === 0) return []
|
|
|
|
if(limit === undefined) {
|
|
return String.prototype._split.call(this, separator, limit)
|
|
}
|
|
|
|
const arr = []
|
|
let lastBegin = -1
|
|
for(let i = 0; i < limit - 1; i++) {
|
|
const end = String.prototype.indexOf.call(this, separator, ++lastBegin)
|
|
if(end == -1) {
|
|
arr.push(undefined)
|
|
continue
|
|
}
|
|
arr.push(String.prototype.substring.call(this, lastBegin, end))
|
|
lastBegin = end
|
|
}
|
|
arr.push(String.prototype.substring.call(this, ++lastBegin))
|
|
|
|
return arr
|
|
}
|
|
|
|
for(let i = 0; i < process.argv.length; i++) {
|
|
const curr = process.argv[i]
|
|
if(curr.startsWith('--')) {
|
|
switch(curr.substring(2)){
|
|
case 'override': {
|
|
const [next, value] = process.argv[i + 1].split(":", 2)
|
|
if(next || !next.startsWith('--')) {
|
|
eval(`config.${next} = '${value}'`)
|
|
}
|
|
continue
|
|
}
|
|
|
|
default: {
|
|
continue
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
export const serverLogger = pino({
|
|
transport: {
|
|
target: 'pino-pretty'
|
|
}
|
|
})
|
|
|
|
export const server = fastify({
|
|
logger: serverLogger
|
|
})
|
|
|
|
export const telegraf = new Telegraf(config.telegram.token)
|
|
|
|
export const s3Instance = new S3Client({
|
|
credentials: {
|
|
accessKeyId: config.storage.key,
|
|
secretAccessKey: config.storage.secret,
|
|
},
|
|
endpoint: config.storage.endpoint,
|
|
...config.storage.extra
|
|
})
|
|
|
|
|
|
export const setup = async () => {
|
|
server.log.info("老色批世界树 > 初始化中...")
|
|
|
|
await mongoose.connect(config.database.url)
|
|
const publicKey = readFileSync(config.signing.public).toString()
|
|
const privateKey = readFileSync(config.signing.private).toString()
|
|
|
|
server.decorate('keys', { publicKey, privateKey })
|
|
|
|
config.custom.preHooks(server)
|
|
|
|
server.addHook('preHandler', Hooks.headerValidation)
|
|
server.setErrorHandler(Hooks.handleError)
|
|
|
|
server.addContentTypeParser('image/png', (_, payload, done) => {
|
|
done(null, payload)
|
|
})
|
|
server.register(fastifySwagger, {
|
|
routePrefix: '/docs',
|
|
swagger: {
|
|
title: "lsp-yggdrasil 接口文档",
|
|
version: "1.0.0",
|
|
tags: [
|
|
{ name: "Authserver", description: "Yggdrasil Authserver 协议定义的接口"},
|
|
{ name: "Sessionserver", description: "Yggdrasil Authserver 协议定义的接口"},
|
|
{ name: "api", description: "Yggdrasil Authserver 协议定义的接口"},
|
|
{ name: "webapi", description: "web前端接口"},
|
|
]
|
|
},
|
|
exposeRoute: true,
|
|
})
|
|
|
|
config.custom.preRouting(server)
|
|
|
|
// Authserver routings
|
|
server.route(AuthenticateRoutings.authenticate)
|
|
server.route(AuthenticateRoutings.refresh)
|
|
server.route(AuthenticateRoutings.validate)
|
|
server.route(AuthenticateRoutings.invalidate)
|
|
server.route(AuthenticateRoutings.signout)
|
|
|
|
server.route(SessionServerRoutings.join)
|
|
server.route(SessionServerRoutings.hasJoined)
|
|
server.route(SessionServerRoutings.profile)
|
|
server.route(SessionServerRoutings.profiles)
|
|
|
|
server.route(WebAPIRoutings.CORS_BYPASS)
|
|
server.route(WebAPIRoutings.meta)
|
|
server.route(WebAPIRoutings.status)
|
|
server.route(WebAPIRoutings.telegramBind)
|
|
server.route(WebAPIRoutings.login)
|
|
server.route(WebAPIRoutings.register)
|
|
server.route(WebAPIRoutings.textures)
|
|
server.route(WebAPIRoutings.uploadTexture)
|
|
|
|
config.custom.postRouting(server)
|
|
|
|
if(process.env["UNIT_TEST"] || process.env["DEVEL_FIRST_RUN"]) {
|
|
// Create a test player
|
|
await new Player({
|
|
username: 'test',
|
|
password: '8d969eef6ecad3c29a3a629280e686cf0c3f5d5a86aff3ca12020c923adc6c92',
|
|
email: 'i@lama.icu',
|
|
uuid: '098f6bcd-4621-3373-8ade-4e832627b4f6',
|
|
textures: {
|
|
skin: 'assets.lama.icu/textures/skin/steve.png',
|
|
cape: 'assets.lama.icu/textures/cape/default.png'
|
|
},
|
|
registerDate: Date.now(),
|
|
permissions: ['login'],
|
|
binding: {
|
|
platform: 'telegram',
|
|
username: 'Qumolama',
|
|
verified: true,
|
|
}
|
|
}).save()
|
|
}
|
|
registerAllPlayerCommands()
|
|
}
|
|
|
|
const launch = async () => {
|
|
process.on('SIGINT', shutdown)
|
|
process.on('SIGTERM', shutdown)
|
|
|
|
await telegraf.launch()
|
|
|
|
await server.listen({ port: config.server.port, url: config.server.url })
|
|
|
|
server.log.info("老色批世界树 > 基于 fastify 的高性能 HTTP 服务器已启动")
|
|
}
|
|
|
|
export const shutdown = async () => {
|
|
await server.close()
|
|
server.log.info("老色批世界树 > HTTP 服务器已关闭")
|
|
try {
|
|
telegraf.stop()
|
|
server.log.info("老色批世界树 > Telegram Bot 已关闭")
|
|
} catch(err) {
|
|
server.log.info("老色批世界树 > Telegram Bot 未运行,已跳过")
|
|
}
|
|
mongoose.disconnect()
|
|
server.log.info("老色批世界树 > 数据库连接已断开,服务器已关闭")
|
|
}
|
|
|
|
(async () => {
|
|
if(!process.env["UNIT_TEST"]) {
|
|
console.log(`
|
|
================================================================
|
|
__ _____ ______ __ __ _ __
|
|
/ / / ___// __ \\ \\/ /___ _____ _____/ /________ ______(_) /
|
|
/ / \\__ \\/ /_/ /\\ / __ \`/ __ \`/ __ / ___/ __ \`/ ___/ / /
|
|
/ /______/ / ____/ / / /_/ / /_/ / /_/ / / / /_/ (__ ) / /
|
|
/_____/____/_/ /_/\\__, /\\__, /\\__,_/_/ \\__,_/____/_/_/
|
|
/____//____/
|
|
================================================================\n`)
|
|
|
|
if(typeof PROGRAM_PRODUCTION === 'undefined') {
|
|
console.warn("⚠ 警告: 您运行的不是正式版本,可能会不稳定,仅限开发环境运行!\n")
|
|
}
|
|
await setup()
|
|
await launch()
|
|
}
|
|
})()
|