refactor: 调整加载顺序

This commit is contained in:
ningmengchongshui 2024-06-17 13:19:18 +08:00
parent 187f23cdea
commit 2f1b7f987b
26 changed files with 271 additions and 254 deletions

View File

@ -10,7 +10,7 @@ const child1 = spawn(
}
)
const child2 = spawn(
'node --no-warnings=ExperimentalWarning --loader ts-node/esm image/main.ts',
'node --no-warnings=ExperimentalWarning --loader ts-node/esm src/server.ts',
argvs.split(' '),
{
shell: true,

View File

@ -1,130 +0,0 @@
import '../src/init/require.js'
import '../src/init/config.js'
import '../src/init/logger.js'
import '../src/init/redis.js'
import Koa from 'koa'
import KoaStatic from 'koa-static'
import Router from 'koa-router'
import { Component } from 'yunzai/utils'
import { Dirent, readdirSync } from 'fs'
import { join } from 'path'
import mount from 'koa-mount'
const Com = new Component()
const app = new Koa()
const router = new Router()
const Port = 8080
const PATH = process.cwd().replace(/\\/g, '\\\\')
const Dynamic = async (Router: Dirent) => {
const modulePath = `file://${join(Router.parentPath, Router.name)}?update=${Date.now()}`
return (await import(modulePath))?.default
}
// 得到plugins目录
const flies = readdirSync(join(process.cwd(), 'plugins'), {
withFileTypes: true
})
.filter(flie => !flie.isFile())
.map(flie => {
const dir = flie?.path ?? flie?.parentPath
flie.parentPath = dir
return flie
}) // 增加兼容性
//
const Routers = []
// 解析路由
for (const flie of flies) {
const plugins = readdirSync(join(flie?.parentPath, flie.name), {
withFileTypes: true
})
.filter(
flie => flie.isFile() && /^(routes.jsx|routes.tsx)$/.test(flie.name)
)
.map(flie => {
const dir = flie?.path ?? flie?.parentPath
flie.parentPath = dir
return flie
}) // 增加兼容性
//
for (const plugin of plugins) {
const routes = await Dynamic(plugin)
// 不存在
if (!routes) continue
// 不是数组
if (!Array.isArray(routes)) continue
//
for (const item of routes) {
const url = `/${flie.name}${item.url}`
console.log(`http://127.0.0.1:${Port}${url}`)
Routers.push({
parentPath: plugin.parentPath,
name: plugin.name,
uri: url,
url: item.url
})
}
}
}
// 辅助函数:替换路径
const replacePaths = htmlContent => {
// 置换成 /file请求
htmlContent = htmlContent.replace(new RegExp(PATH, 'g'), '/file')
// 正则表达式匹配 src、href 和 url 中的路径
const regex = /(src|href|url)\s*=\s*["']([^"']*\\[^"']*)["']/g
const cssUrlRegex = /url\(["']?([^"'\)\\]*\\[^"'\)]*)["']?\)/g
htmlContent = htmlContent.replace(regex, (_, p1, p2) => {
const correctedPath = p2.replace(/\\/g, '/')
return `${p1}="${correctedPath}"`
})
return htmlContent.replace(cssUrlRegex, (_, p1) => {
const correctedPath = p1.replace(/\\/g, '/')
return `url(${correctedPath})`
})
}
for (const Router of Routers) {
router.get(Router.uri, async ctx => {
// 动态加载
const routes = await Dynamic(Router)
// 不存在
if (!routes) return
// 不是数组
if (!Array.isArray(routes)) return
// 查找
const item = routes.find(i => i.url == Router.url)
// 丢失了
if (!item) return
/**
* html
*/
const options = item?.options ?? {}
const HTML = Com.create(item.element, {
...options,
file_create: false
})
// 置换为file请求
ctx.body = replacePaths(HTML)
})
}
// static
app.use(mount('/file', KoaStatic(PATH)))
// routes
app.use(router.routes())
// listen 8000
app.listen(Port, () => {
console.log('______________')
console.log('Server is running on port ' + Port)
console.log('______________')
console.log('自行调整默认浏览器尺寸 800 X 1280 100%')
console.log('如果需要运行时重新计算className')
console.log('请确保一直打开此程序')
console.log('______________')
})

View File

@ -1,19 +1,7 @@
import { execSync, spawn } from 'child_process'
const argv = [...process.argv].splice(2)
const argvs = argv.join(' ').replace(/(\S+\.js|\S+\.ts)/g, '')
/**
* **********
* 生成css文件
* **********
*/
execSync('tailwindcss -i ./src/input.css -o ./public/output.css')
/**
* ***************
* 启动内部运行脚本
* ***************
*/
const child = spawn(
'node --no-warnings=ExperimentalWarning --loader ts-node/esm src/main.ts',
argvs.split(' '),
@ -22,11 +10,6 @@ const child = spawn(
stdio: 'inherit'
}
)
/**
* *************
* exit
* *************
*/
process.on('SIGINT', () => {
if (child.pid) process.kill(child.pid)
if (process.pid) process.exit()

View File

@ -16,7 +16,7 @@
"logs": "pm2 logs",
"monit": "pm2 monit",
"pm2": "pm2",
"image": "node image/index.js",
"image": "node image.js",
"css": "tailwindcss -i ./src/input.css -o ./public/output.css",
"format": "prettier --write .",
"prepare": "husky"
@ -98,8 +98,14 @@
"./core": {
"import": "./src/core/index.js"
},
"./init": {
"import": "./src/init/index.js"
},
"./image": {
"import": "./src/image/index.js"
},
"./image/types": {
"import": "./image/types.js"
"import": "./src/image/types.js"
}
},
"imports": {

View File

@ -48,18 +48,22 @@ export class Client extends IcqqClient {
/**
*
*/
if (cfg.bot.skip_login) return await this.skip_login(bot)
if (cfg.bot.skip_login) {
return await this.skip_login(bot)
}
/**
*
*/
await bot.login(cfg.qq, cfg.pwd)
bot[bot.uin] = bot
/**
* bot
*/
global.Bot = bot
return bot
}
@ -69,29 +73,39 @@ export class Client extends IcqqClient {
* @returns
*/
static async skip_login(bot) {
//
bot.uin = 88888
//
bot[bot.uin] = bot
/**
* bot
*/
global.Bot = bot
/**
*
*/
await PluginsLoader.load()
/**
*
*/
return
return bot
}
/**
*
* @param bot
* @returns
*/
static async PluginsLoader() {
await PluginsLoader.load()
}
//
}
/**
* Redis
* 使
* @deprecated
*/
export const Redis = global.redis
/**
*
*/
export const Bot = global.Bot as typeof Client.prototype
export const Bot = global.Bot

View File

@ -1,2 +1,7 @@
import { segment } from 'icqq'
/**
* global.segment
*/
global.segment = segment
export { segment } from 'icqq'
export { segment as Segment } from 'icqq'

View File

@ -163,7 +163,7 @@ class PluginsLoader {
logger.error(decodeURI(i.reason))
}
} catch (error) {
console.error(error)
logger.error(error)
if (packageErr && error.stack.includes('Cannot find package')) {
packageErr.push({ error, file })
} else {

View File

@ -1,5 +1,5 @@
import { Common } from '../../miao.js'
import { Common } from '../../mys/miao.js'
import { EventType } from './types.js'
import { type EventMap } from 'icqq'
@ -265,4 +265,9 @@ export class Plugin {
/**
* @deprecated
*/
export const plugin = Plugin
export const plugin = Plugin
/**
* global.plugin
*/
global.plugin = plugin

View File

@ -11,7 +11,7 @@ import puppeteer from '../../utils/puppeteer/puppeteer.js'
import * as common from '../../utils/common.js'
import cfg from '../../config/config.js'
import Handler from './handler.js'
import { Version } from '../../miao.js'
import { Version } from '../../mys/miao.js'
/**
* @deprecated

View File

@ -1,5 +1,5 @@
import { Sequelize, DataTypes, Model } from 'sequelize'
import { Data } from '../miao.js'
import { Data } from '../mys/miao.js'
Data.createDir('/data/db', 'root')

129
src/image/index.ts Normal file
View File

@ -0,0 +1,129 @@
import '../init/index'
import Koa from 'koa'
import KoaStatic from 'koa-static'
import Router from 'koa-router'
import { Dirent, readdirSync } from 'fs'
import { join } from 'path'
import mount from 'koa-mount'
import { Component } from '../utils/index.js'
export * from './types.js'
export async function createServer() {
//
const Com = new Component()
const app = new Koa()
const router = new Router()
const Port = 8080
const PATH = process.cwd().replace(/\\/g, '\\\\')
const Dynamic = async (Router: Dirent) => {
const modulePath = `file://${join(Router.parentPath, Router.name)}?update=${Date.now()}`
return (await import(modulePath))?.default
}
// 得到plugins目录
const flies = readdirSync(join(process.cwd(), 'plugins'), {
withFileTypes: true
})
.filter(flie => !flie.isFile())
.map(flie => {
const dir = flie?.path ?? flie?.parentPath
flie.parentPath = dir
return flie
}) // 增加兼容性
//
const Routers = []
// 解析路由
for (const flie of flies) {
const plugins = readdirSync(join(flie?.parentPath, flie.name), {
withFileTypes: true
})
.filter(
flie => flie.isFile() && /^(routes.jsx|routes.tsx)$/.test(flie.name)
)
.map(flie => {
const dir = flie?.path ?? flie?.parentPath
flie.parentPath = dir
return flie
}) // 增加兼容性
//
for (const plugin of plugins) {
const routes = await Dynamic(plugin)
// 不存在
if (!routes) continue
// 不是数组
if (!Array.isArray(routes)) continue
//
for (const item of routes) {
const url = `/${flie.name}${item.url}`
console.log(`http://127.0.0.1:${Port}${url}`)
Routers.push({
parentPath: plugin.parentPath,
name: plugin.name,
uri: url,
url: item.url
})
}
}
}
// 辅助函数:替换路径
const replacePaths = htmlContent => {
// 置换成 /file请求
htmlContent = htmlContent.replace(new RegExp(PATH, 'g'), '/file')
// 正则表达式匹配 src、href 和 url 中的路径
const regex = /(src|href|url)\s*=\s*["']([^"']*\\[^"']*)["']/g
const cssUrlRegex = /url\(["']?([^"'\)\\]*\\[^"'\)]*)["']?\)/g
htmlContent = htmlContent.replace(regex, (_, p1, p2) => {
const correctedPath = p2.replace(/\\/g, '/')
return `${p1}="${correctedPath}"`
})
return htmlContent.replace(cssUrlRegex, (_, p1) => {
const correctedPath = p1.replace(/\\/g, '/')
return `url(${correctedPath})`
})
}
for (const Router of Routers) {
router.get(Router.uri, async ctx => {
// 动态加载
const routes = await Dynamic(Router)
// 不存在
if (!routes) return
// 不是数组
if (!Array.isArray(routes)) return
// 查找
const item = routes.find(i => i.url == Router.url)
// 丢失了
if (!item) return
/**
* html
*/
const options = item?.options ?? {}
const HTML = Com.create(item.element, {
...options,
file_create: false
})
// 置换为file请求
ctx.body = replacePaths(HTML)
})
}
// static
app.use(mount('/file', KoaStatic(PATH)))
// routes
app.use(router.routes())
// listen 8000
app.listen(Port, () => {
console.log('______________')
console.log('Server is running on port ' + Port)
console.log('______________')
console.log('自行调整默认浏览器尺寸 800 X 1280 100%')
console.log('如果需要运行时重新计算className')
console.log('请确保一直打开此程序')
console.log('______________')
})
}

View File

@ -1,4 +1,4 @@
import { type ComponentCreateOpsionType } from 'yunzai/utils'
import { ComponentCreateOpsionType } from '../utils/component'
export type RouterType = {
url: string
element: React.ReactNode

View File

@ -1,6 +0,0 @@
import './init/require.js'
import './init/config.js'
import './init/logger.js'
import './init/redis.js'
import './init/process.js'
import './init/run.js'

6
src/init/index.ts Normal file
View File

@ -0,0 +1,6 @@
import './require.js'
import './config.js'
import './logger.js'
import './redis.js'
import './process.js'
import './run.js'

View File

@ -44,6 +44,8 @@ async function redisInit() {
})
/** 全局变量 redis */
global.redis = client as any
//
logger.info('Redis 连接成功')
return client
}

View File

@ -1,19 +1,6 @@
import './init.js'
import { plugin, segment, Client } from './core/index.js'
import { Renderer } from './utils/index.js'
import { createQQ } from './config/qq.js'
/**
* global.plugin
*/
global.plugin = plugin
/**
* global.segment
*/
global.segment = segment
/**
* global.Renderer
*/
global.Renderer = Renderer
import 'yunzai/init'
import { Client, Bot as bot } from 'yunzai/core'
import { createQQ } from './qq.js'
/**
*
*
@ -24,4 +11,12 @@ setTimeout(async () => {
* run
*/
await Client.run()
console.log('bot', bot)
console.log('Bot', Bot)
/**
* Loader
*/
await Client.PluginsLoader()
}, 0)

View File

@ -13,7 +13,7 @@ import NoteUser from './NoteUser.js'
import MysApi from './mysApi.js'
import MysUtil from './MysUtil.js'
import { MysUserDB } from '../db/index.js'
import { Data } from '../miao.js'
import { Data } from './miao.js'
const tables = {
// ltuid-uid 查询表

View File

@ -1,4 +1,4 @@
import { Data } from '../miao.js'
import { Data } from './miao.js'
/**
*

View File

@ -3,7 +3,7 @@ import lodash from 'lodash'
import MysUser from './MysUser.js'
import MysUtil from './MysUtil.js'
import { UserDB } from '../db/index.js'
import { Data } from '../miao.js'
import { Data } from './miao.js'
/**
* *******************
* Bot实际User用户类

View File

@ -4,7 +4,7 @@ import fs from 'node:fs'
import lodash from 'lodash'
import MysInfo from './mysInfo.js'
import NoteUser from './NoteUser.js'
import { Character, Weapon } from '../miao.js'
import { Character, Weapon } from './miao.js'
/**
* ***********
@ -350,7 +350,7 @@ class GsCfg {
* @returns
*/
getWeaponDataByWeaponHash(_) {
console.log('gsCfg.getWeaponDataByWeaponHash() 已废弃')
logger.info('gsCfg.getWeaponDataByWeaponHash() 已废弃')
return {}
}
@ -360,7 +360,7 @@ class GsCfg {
* @returns
*/
getAllAbbr() {
console.log('gsCfg.getAllAbbr() 已废弃')
logger.info('gsCfg.getAllAbbr() 已废弃')
return {}
}
@ -371,7 +371,7 @@ class GsCfg {
* @returns
*/
getBingCkSingle(_) {
console.log('gsCfg.getBingCkSingle() 已废弃')
logger.info('gsCfg.getBingCkSingle() 已废弃')
return {}
}
@ -382,7 +382,7 @@ class GsCfg {
* @param data
*/
saveBingCk(_, __) {
console.log('gsCfg.saveBingCk() 已废弃')
logger.info('gsCfg.saveBingCk() 已废弃')
}
/**
@ -392,7 +392,7 @@ class GsCfg {
* @returns
*/
getElementByRoleName(_) {
console.log('gsCfg.getElementByRoleName() 已废弃')
logger.info('gsCfg.getElementByRoleName() 已废弃')
return ''
}
@ -404,7 +404,7 @@ class GsCfg {
* @returns
*/
getSkillDataByskillId(_, __) {
console.log('gsCfg.getSkillDataByskillId() 已废弃')
logger.info('gsCfg.getSkillDataByskillId() 已废弃')
return {}
}
@ -415,7 +415,7 @@ class GsCfg {
* @returns
*/
fightPropIdToName(_) {
console.log('gsCfg.fightPropIdToName() 已废弃')
logger.info('gsCfg.fightPropIdToName() 已废弃')
return ''
}
@ -426,7 +426,7 @@ class GsCfg {
* @returns
*/
getRoleTalentByTalentId(_) {
console.log('gsCfg.getRoleTalentByTalentId 已废弃')
logger.info('gsCfg.getRoleTalentByTalentId 已废弃')
return {}
}
@ -435,7 +435,7 @@ class GsCfg {
* @deprecated
*/
getAbbr() {
console.log('gsCfg.getAbbr() 已经废弃')
logger.info('gsCfg.getAbbr() 已经废弃')
}
}

View File

@ -1,34 +1,36 @@
import fs from 'fs'
import inquirer from 'inquirer'
import chalk from 'chalk'
import { BOT_NAME, CONFIG_DEFAULT_PATH, CONFIG_INIT_PATH } from './system.js'
import cfg from './config.js'
import { sleep } from "./utils.js"
import {
BOT_NAME,
CONFIG_DEFAULT_PATH,
CONFIG_INIT_PATH,
ConfigController as cfg
} from 'yunzai/config'
import { sleep } from 'yunzai/utils'
/**
* qq配置文件 `config/bot/qq.yaml`
* Git Bash npm命令会无法选择列表
* @returns
* @returns
*/
export async function createQQ() {
/** 跳过登录ICQQ */
if (cfg.bot.skip_login) return
/**
*
*
*/
if (cfg.qq && !process.argv.includes('login')) {
return
}
/**
*
*
*/
console.log(`欢迎使用${chalk.green(`${BOT_NAME} v` + cfg.package.version)}\n请按提示输入完成QQ配置`)
logger.info(
`欢迎使用${chalk.green(`${BOT_NAME} v` + cfg.package.version)}\n请按提示输入完成QQ配置`
)
/**
*
*
*/
const propmtList = [
{
@ -51,22 +53,28 @@ export async function createQQ() {
name: 'platform',
default: '6',
choices: ['Tim', 'iPad', '安卓手机', '安卓手表', 'MacOS', 'aPad'],
filter: (val) => {
filter: val => {
switch (val) {
case 'Tim': return 6
case 'iPad': return 5
case 'MacOS': return 4
case '安卓手机': return 1
case '安卓手表': return 3
case 'aPad': return 2
default: return 6
case 'Tim':
return 6
case 'iPad':
return 5
case 'MacOS':
return 4
case '安卓手机':
return 1
case '安卓手表':
return 3
case 'aPad':
return 2
default:
return 6
}
}
}
]
/**
*
*
*/
if (!process.argv.includes('login')) {
propmtList.push({
@ -75,59 +83,49 @@ export async function createQQ() {
name: 'masterQQ'
})
}
/**
*
*
*/
propmtList.push({
type: 'input',
message: '请输入签名API地址可留空',
name: 'signAPI'
})
/**
*
*
*/
const ret = await inquirer.prompt(propmtList)
/**
*
*
*/
const file = `./${CONFIG_INIT_PATH}`
const fileDef = `./${CONFIG_DEFAULT_PATH}`
let qq = fs.readFileSync(`${fileDef}qq.yaml`, 'utf8')
qq = qq.replace(/qq:/g, 'qq: ' + ret.QQ)
qq = qq.replace(/pwd:/g, `pwd: '${ret.pwd}'`)
qq = qq.replace(/platform: [1-6]/g, 'platform: ' + Number(ret.platform))
fs.writeFileSync(`${file}qq.yaml`, qq, 'utf8')
let bot = fs.readFileSync(`${fileDef}bot.yaml`, 'utf8')
/**
*
*
*/
if (ret.masterQQ) {
let other = fs.readFileSync(`${fileDef}other.yaml`, 'utf8')
other = other.replace(/masterQQ:/g, `masterQQ:\n - ${ret.masterQQ}`)
fs.writeFileSync(`${file}other.yaml`, other, 'utf8')
}
/**
*
*
*/
if (ret.signAPI) {
bot = bot.replace(/sign_api_addr:/g, `sign_api_addr: ${ret.signAPI}`)
}
fs.writeFileSync(`${file}bot.yaml`, bot, 'utf8')
console.log(`\nQQ配置完成正在登录\n后续修改账号可以运行命令 ${chalk.green('npm run login')}\n`)
logger.info(
`\nQQ配置完成正在登录\n后续修改账号可以运行命令 ${chalk.green('npm run login')}\n`
)
/**
*
*
*/
await sleep(2000)
}
}

2
src/server.ts Normal file
View File

@ -0,0 +1,2 @@
import { createServer } from 'yunzai/image'
await createServer()

View File

@ -65,11 +65,11 @@ export class Puppeteer {
try {
this.browser = await puppeteer.launch(this.#launch)
this.#isBrowser = true
console.info('[puppeteer] open success')
logger.info('[puppeteer] open success')
return true
} catch (err) {
this.#isBrowser = false
console.error('[puppeteer] err', err)
logger.error('[puppeteer] err', err)
return false
}
}
@ -96,12 +96,12 @@ export class Puppeteer {
*
*/
this.#pic = 0
console.info('[puppeteer] close')
logger.info('[puppeteer] close')
this.#isBrowser = false
this.browser?.close().catch(err => {
console.error('[puppeteer] close', err)
logger.error('[puppeteer] close', err)
})
console.info('[puppeteer] reopen')
logger.info('[puppeteer] reopen')
if (!(await this.start())) return false
this.#pic++
}
@ -121,7 +121,7 @@ export class Puppeteer {
if (!(await this.isStart())) return false
try {
const page = await this.browser?.newPage().catch(err => {
console.error(err)
logger.error(err)
})
if (!page) return false
await page.goto(`file://${htmlPath}`, {
@ -129,7 +129,7 @@ export class Puppeteer {
})
const body = await page.$(Options?.tab ?? 'body')
if (!body) return false
console.info('[puppeteer] success')
logger.info('[puppeteer] success')
const buff: string | false | Buffer = await body
.screenshot(
Options?.SOptions ?? {
@ -137,19 +137,19 @@ export class Puppeteer {
}
)
.catch(err => {
console.error('[puppeteer]', 'screenshot', err)
logger.error('[puppeteer]', 'screenshot', err)
return false
})
await page.close().catch(err => {
console.error('[puppeteer]', 'page close', err)
logger.error('[puppeteer]', 'page close', err)
})
if (!buff) {
console.error('[puppeteer]', htmlPath)
logger.error('[puppeteer]', htmlPath)
return false
}
return buff
} catch (err) {
console.error('[puppeteer] newPage', err)
logger.error('[puppeteer] newPage', err)
return false
}
}

View File

@ -87,3 +87,8 @@ export default class Renderer {
this.watcher[tplFile] = watcher
}
}
/**
* global.Renderer
*/
global.Renderer = Renderer

View File

@ -34,12 +34,15 @@
//
"paths": {
//
"yunzai/image/types": ["./image/types.js"],
"yunzai/config": ["./src/config/index.js"],
"yunzai/db": ["./src/db/index.js"],
"yunzai/mys": ["./src/mys/index.js"],
"yunzai/utils": ["./src/utils/index.js"],
"yunzai/init": ["./src/init/index.js"],
"yunzai/core": ["./src/core/index.js"],
//
"yunzai/image/types": ["./src/image/types.js"],
"yunzai/image": ["./src/image/index.js"],
//
"#miao": ["./plugins/miao-plugin/components/index.js"],
"#miao.models": ["./plugins/miao-plugin/models/index.js"]
@ -50,5 +53,5 @@
"transpileOnly": true,
"experimentalSpecifierResolution": "node"
},
"include": ["src", "image", "lib", "renderers", "plugins"]
"include": ["src", "plugins", "lib", "renderers"]
}