优化项目结构,优化构建脚本,优化README.MD
All checks were successful
continuous-integration/drone/push Build is passing
All checks were successful
continuous-integration/drone/push Build is passing
This commit is contained in:
parent
99d304899d
commit
bd8b866f07
16
.drone.yml
16
.drone.yml
@ -7,12 +7,12 @@ kind: pipeline
|
|||||||
name: test
|
name: test
|
||||||
|
|
||||||
steps:
|
steps:
|
||||||
- name: installgit p
|
- name: test
|
||||||
image: node:16
|
image: node:16
|
||||||
commands:
|
commands:
|
||||||
- yarn install
|
- yarn install
|
||||||
- yarn test
|
- yarn test
|
||||||
- name: telgram_notify
|
- name: notify
|
||||||
image: appleboy/drone-telegram
|
image: appleboy/drone-telegram
|
||||||
when:
|
when:
|
||||||
status:
|
status:
|
||||||
@ -25,19 +25,19 @@ steps:
|
|||||||
format: markdown
|
format: markdown
|
||||||
message: >
|
message: >
|
||||||
{{#success build.status}}
|
{{#success build.status}}
|
||||||
✅ `{{repo.name}}` #{{build.number}} 号构建测试已通过 .
|
✅ `{{repo.name}}` #{{build.number}} 号构建测试已通过\n
|
||||||
📝 {{commit.author}} 在 `{{commit.branch}}` 的提交:
|
📝 {{commit.author}} 在 `{{commit.branch}}` 的提交:\n
|
||||||
```
|
```
|
||||||
{{commit.message}}
|
{{commit.message}}
|
||||||
```
|
```
|
||||||
🌐 {{ build.link }}
|
\n🌐 {{ build.link }}
|
||||||
{{else}}
|
{{else}}
|
||||||
❌ `{{repo.name}}` #{{build.number}} 号构建测试已失败 .
|
❌ `{{repo.name}}` #{{build.number}} 号构建测试已失败\n
|
||||||
📝 {{commit.author}} 在 `{{commit.branch}}` 的提交:
|
📝 {{commit.author}} 在 `{{commit.branch}}` 的提交:\n
|
||||||
```
|
```
|
||||||
{{commit.message}}
|
{{commit.message}}
|
||||||
```
|
```
|
||||||
🌐 {{ build.link }}
|
\n🌐 {{ build.link }}
|
||||||
{{/success}}
|
{{/success}}
|
||||||
|
|
||||||
|
|
||||||
|
56
README.MD
56
README.MD
@ -2,26 +2,31 @@
|
|||||||
|
|
||||||
老色批世界树 —— 一个高性能麻将、奥苏力不-印寨克托接口的实现。使用fastify来把处理速度加速到老色批的速度(
|
老色批世界树 —— 一个高性能麻将、奥苏力不-印寨克托接口的实现。使用fastify来把处理速度加速到老色批的速度(
|
||||||
|
|
||||||
|
具体有多快呢?登录处理从数据包发出到接收到服务端响应仅需要 __***6ms***__(根据机器不同可能会有浮动,以实际情况为准)!
|
||||||
|
|
||||||
[](https://996.icu)
|
[](https://996.icu)
|
||||||
[](https://github.com/996icu/996.ICU/blob/master/LICENSE)
|
[](https://github.com/996icu/996.ICU/blob/master/LICENSE)
|
||||||
[](https://ci.186526.xyz/Lama3L9R/lsp-yggdrasil)
|
[](https://ci.186526.xyz/Lama3L9R/lsp-yggdrasil)
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
TODO:
|
## 开发计划:
|
||||||
|
|
||||||
- [ ] Basic API
|
#### Beta 1.0:
|
||||||
|
- [ ] 基础世界树 API
|
||||||
+ [x] /authserver
|
+ [x] /authserver
|
||||||
+ [ ] /sessionserver
|
+ [ ] /sessionserver
|
||||||
+ [ ] /api
|
+ [ ] /api
|
||||||
- [ ] Advanced API
|
- [ ] 进阶 API
|
||||||
- [ ] Skin uploading & security checks for texture
|
- [ ] 皮肤上传和安全检查
|
||||||
+ [ ] Texture RSAsigning
|
+ [ ] 皮肤数据的RSA签名
|
||||||
- [ ] S3 Storage backend
|
- [ ] 兼容S3后端
|
||||||
- [ ] Server status
|
- [ ] 服务器状态接口
|
||||||
- [ ] Authlib meta
|
- [ ] authlib-injector 元数据接口
|
||||||
- [ ] Telegram Bot
|
|
||||||
- [ ] Unit test
|
#### Release 1.0
|
||||||
|
- [ ] TGbot前端
|
||||||
|
- [ ] 单元测试
|
||||||
+ [ ] API
|
+ [ ] API
|
||||||
- [ ] /authserver
|
- [ ] /authserver
|
||||||
- [ ] /sessionserver
|
- [ ] /sessionserver
|
||||||
@ -29,16 +34,29 @@ TODO:
|
|||||||
- [ ] Advanced API
|
- [ ] Advanced API
|
||||||
+ [ ] Utils
|
+ [ ] Utils
|
||||||
|
|
||||||
## WIP
|
#### 未来的版本:
|
||||||
|
|
||||||
推荐 Node.js 版本:`16.15.0 LTS (Latest LTS)`
|
- [ ] 完整 web 管理
|
||||||
|
|
||||||
*因为魔法,在 Node14 也能跑*
|
---
|
||||||
|
|
||||||
构建方法
|
## 使用方法
|
||||||
```
|
|
||||||
$ yarn install && node ./build.js
|
|
||||||
```
|
|
||||||
|
|
||||||
**记得手动复制`config.js`!放在和主程序一个目录就行,构建完了看`./production`**
|
1. 安装Node.js、yarn、并下载源代码
|
||||||
**因为我设置了项目为`module`,构建出来的是`cjs`因此不能直接在项目目录下跑,扔到别的地方跑**
|
+ 推荐 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` —— 单元测试
|
18
build.js
18
build.js
@ -3,9 +3,11 @@ import exec from 'shelljs.exec'
|
|||||||
|
|
||||||
const productionVersion = "1.0"
|
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 buildDate = new Date().toTimeString()
|
||||||
|
|
||||||
|
|
||||||
const banner = `
|
const banner = `
|
||||||
==========================================================================
|
==========================================================================
|
||||||
__ _____ ______ __ __ _ __
|
__ _____ ______ __ __ _ __
|
||||||
@ -24,18 +26,22 @@ const banner = `
|
|||||||
`
|
`
|
||||||
|
|
||||||
console.log(banner)
|
console.log(banner)
|
||||||
console.log("Creating a production build...")
|
|
||||||
|
if(type.indexOf('stable') === -1) {
|
||||||
|
console.warn("⚠ 警告: 此版本不是正式版,运行可能会存在性能、安全、稳定度等严重风险,请谨慎使用!\n")
|
||||||
|
}
|
||||||
|
|
||||||
|
console.log("正在创建运行时文件...")
|
||||||
|
|
||||||
esbuild.build({
|
esbuild.build({
|
||||||
entryPoints: ['./src/index.js'],
|
entryPoints: ['./src/index.js'],
|
||||||
outfile: './production/lsp-yggdrasil.full.js',
|
outfile: './production/lsp-yggdrasil.full.cjs',
|
||||||
bundle: true,
|
bundle: true,
|
||||||
platform: 'node',
|
platform: 'node',
|
||||||
target: 'es2018',
|
target: 'es2018',
|
||||||
external: ['./config.js'],
|
|
||||||
banner: {
|
banner: {
|
||||||
js: `/*\n${banner}\n*/`
|
js: `/*\n${banner}\n*/;const PROGRAM_PRODUCTION = true;`
|
||||||
},
|
},
|
||||||
}).then(() => {
|
}).then(() => {
|
||||||
console.log("Done! Enjoy the yggdrasil server as FAST as LSP")
|
console.log("一份运行时文件已保存在 production/lsp-yggdrasil.full.js,您可以尽情的体验和LSP一样快的世界树服务器了!")
|
||||||
})
|
})
|
@ -1,23 +1,38 @@
|
|||||||
const defaultPrehandler = async function (req, rep) { }
|
|
||||||
|
|
||||||
export const config = {
|
export const config = {
|
||||||
database: {
|
database: { // MONGODB IS THE BEST DATABASE
|
||||||
url: 'mongodb://localhost:27017/yggdrasil?readPreference=primary&appname=MongoDB%20Compass&directConnection=true&ssl=false',
|
url: 'mongodb://localhost:27017/yggdrasil?readPreference=primary&appname=MongoDB%20Compass&directConnection=true&ssl=false',
|
||||||
},
|
},
|
||||||
server: {
|
server: {
|
||||||
port: 3000,
|
port: 3000
|
||||||
url: '',
|
|
||||||
},
|
},
|
||||||
signing: {
|
signing: { // 签名材质信息使用
|
||||||
public: '/path/to/public.pem',
|
public: '/path/to/public.pem',
|
||||||
private: '/path/to/private.key'
|
private: '/path/to/private.key'
|
||||||
},
|
},
|
||||||
custom: {
|
custom: {
|
||||||
overridePrehandler: (url) => {
|
override: {
|
||||||
return defaultPrehandler
|
preHandler: {
|
||||||
|
/*
|
||||||
|
"/example/route": async function(req, rep) {}
|
||||||
|
*/
|
||||||
},
|
},
|
||||||
preHooks: (fastify) => {},
|
|
||||||
preRouting: (fastify) => {},
|
handler: {
|
||||||
postRouting: (fastify) => {},
|
/*
|
||||||
|
"/example/route": async function(req, rep) {}
|
||||||
|
*/
|
||||||
|
}
|
||||||
|
},
|
||||||
|
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]
|
||||||
|
}
|
22
src/index.js
22
src/index.js
@ -3,6 +3,21 @@ import { mongoose } from 'mongoose'
|
|||||||
import { registerModels } from './models/index.js';
|
import { registerModels } from './models/index.js';
|
||||||
import * as Hooks from './hooks.js'
|
import * as Hooks from './hooks.js'
|
||||||
import * as AuthenticateRoutings from './routes/authenticate.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({
|
export const server = fastify({
|
||||||
logger: {
|
logger: {
|
||||||
@ -14,10 +29,6 @@ export const server = fastify({
|
|||||||
//export const logger = server.log
|
//export const logger = server.log
|
||||||
|
|
||||||
;(async () => {
|
;(async () => {
|
||||||
const { config } = await import('./config.js')
|
|
||||||
|
|
||||||
server.decorate('conf', config)
|
|
||||||
|
|
||||||
const mongooseClient = await mongoose.connect(config.database.url)
|
const mongooseClient = await mongoose.connect(config.database.url)
|
||||||
const models = registerModels(mongooseClient)
|
const models = registerModels(mongooseClient)
|
||||||
|
|
||||||
@ -28,11 +39,14 @@ export const server = fastify({
|
|||||||
server.addHook('preHandler', Hooks.headerValidation)
|
server.addHook('preHandler', Hooks.headerValidation)
|
||||||
|
|
||||||
config.custom.preRouting(server)
|
config.custom.preRouting(server)
|
||||||
|
|
||||||
|
// Authserver routings
|
||||||
server.route(AuthenticateRoutings.authenticate)
|
server.route(AuthenticateRoutings.authenticate)
|
||||||
server.route(AuthenticateRoutings.refresh)
|
server.route(AuthenticateRoutings.refresh)
|
||||||
server.route(AuthenticateRoutings.validate)
|
server.route(AuthenticateRoutings.validate)
|
||||||
server.route(AuthenticateRoutings.invalidate)
|
server.route(AuthenticateRoutings.invalidate)
|
||||||
server.route(AuthenticateRoutings.signout)
|
server.route(AuthenticateRoutings.signout)
|
||||||
|
|
||||||
config.custom.postRouting(server)
|
config.custom.postRouting(server)
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -1,6 +1,7 @@
|
|||||||
import * as PlayerModel from '../models/player.js'
|
import * as PlayerModel from '../models/player.js'
|
||||||
import { createHash } from 'crypto'
|
import { createHash } from 'crypto'
|
||||||
import { generateToken, uuidToNoSymboUUID } from '../generator.js'
|
import { generateToken, uuidToNoSymboUUID } from '../generator.js'
|
||||||
|
import { getOverrideHandler, getOverridePreHandler } from '../config.js'
|
||||||
|
|
||||||
export const authenticate = {
|
export const authenticate = {
|
||||||
method: 'POST',
|
method: 'POST',
|
||||||
@ -46,7 +47,7 @@ export const authenticate = {
|
|||||||
},
|
},
|
||||||
"availableProfiles": {
|
"availableProfiles": {
|
||||||
"type": "array",
|
"type": "array",
|
||||||
"items": [{...PlayerModel.PlayerSeriliazationSchema}]
|
"items": [PlayerModel.PlayerSeriliazationSchema]
|
||||||
},
|
},
|
||||||
"selectedProfile": PlayerModel.PlayerSeriliazationSchema,
|
"selectedProfile": PlayerModel.PlayerSeriliazationSchema,
|
||||||
"user": PlayerModel.PlayerAccountSerializationSchema
|
"user": PlayerModel.PlayerAccountSerializationSchema
|
||||||
@ -54,10 +55,8 @@ export const authenticate = {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
preHandler: async function(req, rep) {
|
preHandler: getOverridePreHandler("/authserver/authenticate"),
|
||||||
this.conf.custom.overridePrehandler('/authserver/authenticate', req, rep)
|
handler: getOverrideHandler("/authserver/authenticate") ?? async function (req, rep) {
|
||||||
},
|
|
||||||
handler: async function (req, rep) {
|
|
||||||
let { username, password, clientToken, requestUser, agent } = req.body
|
let { username, password, clientToken, requestUser, agent } = req.body
|
||||||
|
|
||||||
if(!username || !password || !agent || agent.name.toLowerCase() !== 'minecraft') {
|
if(!username || !password || !agent || agent.name.toLowerCase() !== 'minecraft') {
|
||||||
@ -185,10 +184,8 @@ export const refresh = {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
preHandler: async function(req, rep) {
|
preHandler: getOverridePreHandler("/authserver/refresh"),
|
||||||
this.conf.custom.overridePrehandler('/authserver/refresh', req, rep)
|
handler: getOverrideHandler("/authserver/authenticate") ?? async function (req, rep) {
|
||||||
},
|
|
||||||
handler: async function (req, rep) {
|
|
||||||
const { accessToken, clientToken, requestUser, selectedProfile } = req.body
|
const { accessToken, clientToken, requestUser, selectedProfile } = req.body
|
||||||
|
|
||||||
const query = {
|
const query = {
|
||||||
@ -320,10 +317,8 @@ export const validate = {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
preHandler: async function(req, rep) {
|
preHandler: getOverridePreHandler("/authserver/validate"),
|
||||||
this.conf.custom.overridePrehandler('/authserver/validate', req, rep)
|
handler: getOverrideHandler("/authserver/validate") ?? async function (req, rep) {
|
||||||
},
|
|
||||||
handler: async function (req, rep) {
|
|
||||||
const { accessToken, clientToken } = req.body
|
const { accessToken, clientToken } = req.body
|
||||||
|
|
||||||
const query = {
|
const query = {
|
||||||
@ -380,10 +375,8 @@ export const invalidate = {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
,
|
,
|
||||||
preHandler: async function(req, rep) {
|
preHandler: getOverridePreHandler("/authserver/invalidate"),
|
||||||
this.conf.custom.overridePrehandler('/authserver/invalidate', req, rep)
|
handler: getOverrideHandler("/authserver/authenticate") ?? async function (req, rep) {
|
||||||
},
|
|
||||||
handler: async function (req, rep) {
|
|
||||||
const { accessToken } = req.body
|
const { accessToken } = req.body
|
||||||
|
|
||||||
const { modifiedCount } = await this.models.Token.updateOne({
|
const { modifiedCount } = await this.models.Token.updateOne({
|
||||||
@ -428,10 +421,8 @@ export const signout = {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
preHandler: async function(req, rep) {
|
preHandler: getOverridePreHandler("/authserver/signout"),
|
||||||
this.conf.custom.overridePrehandler('/authserver/logout', req, rep)
|
handler: getOverrideHandler("/authserver/signout") ?? async function (req, rep) {
|
||||||
},
|
|
||||||
handler: async function (req, rep) {
|
|
||||||
const { username, password } = req.body
|
const { username, password } = req.body
|
||||||
|
|
||||||
const player = await this.models.Player.findOne({ email: username, password: createHash('sha256').update(password).digest().toString('hex').toLowerCase() })
|
const player = await this.models.Player.findOne({ email: username, password: createHash('sha256').update(password).digest().toString('hex').toLowerCase() })
|
||||||
|
Loading…
x
Reference in New Issue
Block a user