From bd8b866f076fbac2f2a45ef88d955a9a5f50b0d1 Mon Sep 17 00:00:00 2001 From: "Qumolama.d" Date: Wed, 4 May 2022 21:04:44 +0800 Subject: [PATCH] =?UTF-8?q?=E4=BC=98=E5=8C=96=E9=A1=B9=E7=9B=AE=E7=BB=93?= =?UTF-8?q?=E6=9E=84=EF=BC=8C=E4=BC=98=E5=8C=96=E6=9E=84=E5=BB=BA=E8=84=9A?= =?UTF-8?q?=E6=9C=AC=EF=BC=8C=E4=BC=98=E5=8C=96README.MD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .drone.yml | 16 +++++------ README.MD | 56 +++++++++++++++++++++++++------------- build.js | 18 ++++++++---- src/config.js | 37 +++++++++++++++++-------- src/index.js | 22 ++++++++++++--- src/routes/authenticate.js | 33 ++++++++-------------- 6 files changed, 113 insertions(+), 69 deletions(-) diff --git a/.drone.yml b/.drone.yml index 3c08099..f82fe54 100644 --- a/.drone.yml +++ b/.drone.yml @@ -7,12 +7,12 @@ kind: pipeline name: test steps: - - name: installgit p + - name: test image: node:16 commands: - yarn install - yarn test - - name: telgram_notify + - name: notify image: appleboy/drone-telegram when: status: @@ -25,19 +25,19 @@ steps: format: markdown message: > {{#success build.status}} - ✅ `{{repo.name}}` #{{build.number}} 号构建测试已通过 . - 📝 {{commit.author}} 在 `{{commit.branch}}` 的提交: + ✅ `{{repo.name}}` #{{build.number}} 号构建测试已通过\n + 📝 {{commit.author}} 在 `{{commit.branch}}` 的提交:\n ``` {{commit.message}} ``` - 🌐 {{ build.link }} + \n🌐 {{ build.link }} {{else}} - ❌ `{{repo.name}}` #{{build.number}} 号构建测试已失败 . - 📝 {{commit.author}} 在 `{{commit.branch}}` 的提交: + ❌ `{{repo.name}}` #{{build.number}} 号构建测试已失败\n + 📝 {{commit.author}} 在 `{{commit.branch}}` 的提交:\n ``` {{commit.message}} ``` - 🌐 {{ build.link }} + \n🌐 {{ build.link }} {{/success}} diff --git a/README.MD b/README.MD index 5b137fd..c1a1a6c 100644 --- a/README.MD +++ b/README.MD @@ -2,26 +2,31 @@ 老色批世界树 —— 一个高性能麻将、奥苏力不-印寨克托接口的实现。使用fastify来把处理速度加速到老色批的速度( +具体有多快呢?登录处理从数据包发出到接收到服务端响应仅需要 __***6ms***__(根据机器不同可能会有浮动,以实际情况为准)! + [![996.icu](https://img.shields.io/badge/link-996.icu-red.svg)](https://996.icu) [![LICENSE](https://img.shields.io/badge/license-Anti%20996-blue.svg)](https://github.com/996icu/996.ICU/blob/master/LICENSE) [![Build Status](https://ci.186526.xyz/api/badges/Lama3L9R/lsp-yggdrasil/status.svg)](https://ci.186526.xyz/Lama3L9R/lsp-yggdrasil) --- -TODO: +## 开发计划: -- [ ] Basic API +#### Beta 1.0: +- [ ] 基础世界树 API + [x] /authserver + [ ] /sessionserver + [ ] /api -- [ ] Advanced API - - [ ] Skin uploading & security checks for texture - + [ ] Texture RSAsigning - - [ ] S3 Storage backend - - [ ] Server status - - [ ] Authlib meta -- [ ] Telegram Bot -- [ ] Unit test +- [ ] 进阶 API + - [ ] 皮肤上传和安全检查 + + [ ] 皮肤数据的RSA签名 + - [ ] 兼容S3后端 + - [ ] 服务器状态接口 + - [ ] authlib-injector 元数据接口 + +#### Release 1.0 +- [ ] TGbot前端 +- [ ] 单元测试 + [ ] API - [ ] /authserver - [ ] /sessionserver @@ -29,16 +34,29 @@ TODO: - [ ] Advanced API + [ ] Utils -## WIP +#### 未来的版本: -推荐 Node.js 版本:`16.15.0 LTS (Latest LTS)` +- [ ] 完整 web 管理 -*因为魔法,在 Node14 也能跑* +--- -构建方法 -``` -$ yarn install && node ./build.js -``` +## 使用方法 -**记得手动复制`config.js`!放在和主程序一个目录就行,构建完了看`./production`** -**因为我设置了项目为`module`,构建出来的是`cjs`因此不能直接在项目目录下跑,扔到别的地方跑** \ No newline at end of file +1. 安装Node.js、yarn、并下载源代码 + + 推荐 Node.js 版本:`16.15.0 LTS (Latest LTS)`,最低兼容 `14 LTS` + + 使用 `$ npm install -g yarn` 来安装yarn + + 使用 `$ git clone https://git.186526.xyz/Lama3L9R/lsp-yggdrasil.git` 下载源代码 +2. 使用 `$ yarn install` 安装依赖库 +3. 配置 `src/config.js` +4. 使用 `$ node build.js` 创建运行时构建 +5. 使用 `$ node path/to/lsp-yggdrasil.full.cjs` 起飞 + +## 常见问题 + +- Q:支持 `https` 嘛? +- A:不支持,请使用反代来使用`https`,或者您也可以修改 `index.js` 中初始化代码。 + +## 内置的 yarn 指令 + ++ `dev` —— 启动开发环境服务器 ++ `test` —— 单元测试 \ No newline at end of file diff --git a/build.js b/build.js index 3f9041f..c4fb6b7 100644 --- a/build.js +++ b/build.js @@ -3,9 +3,11 @@ import exec from 'shelljs.exec' const productionVersion = "1.0" -const build = exec('git log -n 1 --pretty=format:"%h on %as with key %GK"', { async: false }).stdout +const build = exec('git log -n 1 --pretty=format:"%h-%GK"', { async: false }).stdout +const type = exec('git log -n 1 --pretty=format:"%D"', { async: false }).stdout const buildDate = new Date().toTimeString() + const banner = ` ========================================================================== __ _____ ______ __ __ _ __ @@ -24,18 +26,22 @@ const banner = ` ` console.log(banner) -console.log("Creating a production build...") + +if(type.indexOf('stable') === -1) { + console.warn("⚠ 警告: 此版本不是正式版,运行可能会存在性能、安全、稳定度等严重风险,请谨慎使用!\n") +} + +console.log("正在创建运行时文件...") esbuild.build({ entryPoints: ['./src/index.js'], - outfile: './production/lsp-yggdrasil.full.js', + outfile: './production/lsp-yggdrasil.full.cjs', bundle: true, platform: 'node', target: 'es2018', - external: ['./config.js'], banner: { - js: `/*\n${banner}\n*/` + js: `/*\n${banner}\n*/;const PROGRAM_PRODUCTION = true;` }, }).then(() => { - console.log("Done! Enjoy the yggdrasil server as FAST as LSP") + console.log("一份运行时文件已保存在 production/lsp-yggdrasil.full.js,您可以尽情的体验和LSP一样快的世界树服务器了!") }) \ No newline at end of file diff --git a/src/config.js b/src/config.js index b78916a..46c32ce 100644 --- a/src/config.js +++ b/src/config.js @@ -1,23 +1,38 @@ -const defaultPrehandler = async function (req, rep) { } - export const config = { - database: { + database: { // MONGODB IS THE BEST DATABASE url: 'mongodb://localhost:27017/yggdrasil?readPreference=primary&appname=MongoDB%20Compass&directConnection=true&ssl=false', }, server: { - port: 3000, - url: '', + port: 3000 }, - signing: { + signing: { // 签名材质信息使用 public: '/path/to/public.pem', private: '/path/to/private.key' }, custom: { - overridePrehandler: (url) => { - return defaultPrehandler + override: { + preHandler: { + /* + "/example/route": async function(req, rep) {} + */ + }, + + handler: { + /* + "/example/route": async function(req, rep) {} + */ + } }, - preHooks: (fastify) => {}, - preRouting: (fastify) => {}, - postRouting: (fastify) => {}, + preHooks: (fastify) => {}, // 在这里添加自定义hook + preRouting: (fastify) => {}, // 在这里添加自定义路由 + postRouting: (fastify) => {}, // IDK what u want to do at here } } + +export function getOverrideHandler(route) { + return config.custom.override.handler[route] +} + +export function getOverridePreHandler(route) { + return config.custom.override.preHandler[route] +} \ No newline at end of file diff --git a/src/index.js b/src/index.js index 87eb2c1..c689002 100644 --- a/src/index.js +++ b/src/index.js @@ -3,6 +3,21 @@ import { mongoose } from 'mongoose' import { registerModels } from './models/index.js'; import * as Hooks from './hooks.js' import * as AuthenticateRoutings from './routes/authenticate.js' +import { config } from './config.js' + +console.log(` + ================================================================ + __ _____ ______ __ __ _ __ + / / / ___// __ \\ \\/ /___ _____ _____/ /________ ______(_) / + / / \\__ \\/ /_/ /\\ / __ \`/ __ \`/ __ / ___/ __ \`/ ___/ / / + / /______/ / ____/ / / /_/ / /_/ / /_/ / / / /_/ (__ ) / / +/_____/____/_/ /_/\\__, /\\__, /\\__,_/_/ \\__,_/____/_/_/ + /____//____/ +================================================================\n`) + +if(typeof PROGRAM_PRODUCTION === 'undefined') { + console.warn("⚠ 警告: 您运行的不是正式版本,可能会不稳定,仅限开发环境运行!\n") +} export const server = fastify({ logger: { @@ -14,10 +29,6 @@ export const server = fastify({ //export const logger = server.log ;(async () => { - const { config } = await import('./config.js') - - server.decorate('conf', config) - const mongooseClient = await mongoose.connect(config.database.url) const models = registerModels(mongooseClient) @@ -28,11 +39,14 @@ export const server = fastify({ server.addHook('preHandler', Hooks.headerValidation) 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) + config.custom.postRouting(server) /* diff --git a/src/routes/authenticate.js b/src/routes/authenticate.js index a48fc9f..1d27b84 100644 --- a/src/routes/authenticate.js +++ b/src/routes/authenticate.js @@ -1,6 +1,7 @@ import * as PlayerModel from '../models/player.js' import { createHash } from 'crypto' import { generateToken, uuidToNoSymboUUID } from '../generator.js' +import { getOverrideHandler, getOverridePreHandler } from '../config.js' export const authenticate = { method: 'POST', @@ -46,7 +47,7 @@ export const authenticate = { }, "availableProfiles": { "type": "array", - "items": [{...PlayerModel.PlayerSeriliazationSchema}] + "items": [PlayerModel.PlayerSeriliazationSchema] }, "selectedProfile": PlayerModel.PlayerSeriliazationSchema, "user": PlayerModel.PlayerAccountSerializationSchema @@ -54,10 +55,8 @@ export const authenticate = { } } }, - preHandler: async function(req, rep) { - this.conf.custom.overridePrehandler('/authserver/authenticate', req, rep) - }, - handler: async function (req, rep) { + preHandler: getOverridePreHandler("/authserver/authenticate"), + handler: getOverrideHandler("/authserver/authenticate") ?? async function (req, rep) { let { username, password, clientToken, requestUser, agent } = req.body if(!username || !password || !agent || agent.name.toLowerCase() !== 'minecraft') { @@ -185,10 +184,8 @@ export const refresh = { } } }, - preHandler: async function(req, rep) { - this.conf.custom.overridePrehandler('/authserver/refresh', req, rep) - }, - handler: async function (req, rep) { + preHandler: getOverridePreHandler("/authserver/refresh"), + handler: getOverrideHandler("/authserver/authenticate") ?? async function (req, rep) { const { accessToken, clientToken, requestUser, selectedProfile } = req.body const query = { @@ -320,10 +317,8 @@ export const validate = { } } }, - preHandler: async function(req, rep) { - this.conf.custom.overridePrehandler('/authserver/validate', req, rep) - }, - handler: async function (req, rep) { + preHandler: getOverridePreHandler("/authserver/validate"), + handler: getOverrideHandler("/authserver/validate") ?? async function (req, rep) { const { accessToken, clientToken } = req.body const query = { @@ -380,10 +375,8 @@ export const invalidate = { } } , - preHandler: async function(req, rep) { - this.conf.custom.overridePrehandler('/authserver/invalidate', req, rep) - }, - handler: async function (req, rep) { + preHandler: getOverridePreHandler("/authserver/invalidate"), + handler: getOverrideHandler("/authserver/authenticate") ?? async function (req, rep) { const { accessToken } = req.body const { modifiedCount } = await this.models.Token.updateOne({ @@ -428,10 +421,8 @@ export const signout = { } } }, - preHandler: async function(req, rep) { - this.conf.custom.overridePrehandler('/authserver/logout', req, rep) - }, - handler: async function (req, rep) { + preHandler: getOverridePreHandler("/authserver/signout"), + handler: getOverrideHandler("/authserver/signout") ?? async function (req, rep) { const { username, password } = req.body const player = await this.models.Player.findOne({ email: username, password: createHash('sha256').update(password).digest().toString('hex').toLowerCase() })