release: v0.23.0
1. add item api 2. support rollup source map 3. fix database drvice error 4. support loliserver 5. support 1.19 bukkit chat 6. config add migrate options 7. Signed-off-by: MiaoWoo <admin@yumc.pw>
This commit is contained in:
		@@ -5,7 +5,7 @@ import * as base64 from 'base64-js'
 | 
			
		||||
const Arrays = Java.type('java.util.Arrays')
 | 
			
		||||
const Level = Java.type('java.util.logging.Level')
 | 
			
		||||
const Paths = Java.type('java.nio.file.Paths')
 | 
			
		||||
const ignoreLogPrefix = ['java.', 'javax.', 'sun.', 'net.minecraft.', 'org.bukkit.', 'jdk.nashorn.', 'org.openjdk.nashorn', 'io.netty.', 'org.spongepowered.', 'org.apache', 'org.springframework']
 | 
			
		||||
const ignoreLogPrefix = ['java.', 'javax.', 'sun.', 'net.minecraft.', 'org.bukkit.', 'jdk.internal.dynalink.', 'jdk.nashorn.', 'org.openjdk.nashorn', 'io.netty.', 'org.spongepowered.', 'org.apache', 'org.springframework']
 | 
			
		||||
 | 
			
		||||
enum LogLevel {
 | 
			
		||||
    ALL,
 | 
			
		||||
@@ -18,12 +18,114 @@ enum LogLevel {
 | 
			
		||||
    OFF
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
const sourceMaps: { [key: string]: SourceMapBuilder } = {}
 | 
			
		||||
const sourceFileMaps: { [key: string]: string } = {}
 | 
			
		||||
 | 
			
		||||
global.setGlobal('MiaoScriptSourceMaps', sourceMaps)
 | 
			
		||||
global.setGlobal('MiaoScriptSourceFileMaps', sourceFileMaps)
 | 
			
		||||
 | 
			
		||||
export namespace jsconsole {
 | 
			
		||||
    export function readSourceMap(fileName: string, lineNumber: any) {
 | 
			
		||||
        try {
 | 
			
		||||
            if (fileName.endsWith('js') || fileName.endsWith('ms')) {
 | 
			
		||||
                if (sourceMaps[fileName] === undefined) {
 | 
			
		||||
                    sourceMaps[fileName] = null
 | 
			
		||||
                    let sourceLine = base.read(fileName).split('\n')
 | 
			
		||||
                    let lastLine = sourceLine[sourceLine.length - 1] || sourceLine[sourceLine.length - 2]
 | 
			
		||||
                    // lastLine is similar //# sourceMappingURL=data:application/json;base64,
 | 
			
		||||
                    if (lastLine.startsWith('//# sourceMappingURL=')) {
 | 
			
		||||
                        let sourceContent = null
 | 
			
		||||
                        let sourceMappingURL = lastLine.split('sourceMappingURL=', 2)[1]
 | 
			
		||||
                        if (sourceMappingURL.startsWith('data:application/json;base64,')) {
 | 
			
		||||
                            sourceContent = String.fromCharCode(...Array.from(base64.toByteArray(sourceMappingURL.split(',', 2)[1])))
 | 
			
		||||
                        } else if (sourceMappingURL.startsWith('http://') || sourceMappingURL.startsWith('https://')) {
 | 
			
		||||
                            // TODO
 | 
			
		||||
                        } else {
 | 
			
		||||
                            let file = Paths.get(Paths.get(fileName, '..', sourceMappingURL).toFile().getCanonicalPath()).toFile()
 | 
			
		||||
                            if (file.exists()) {
 | 
			
		||||
                                sourceContent = base.read(file)
 | 
			
		||||
                            } else if (global.debug) {
 | 
			
		||||
                                console.debug('readSourceMap can\'t found', fileName, 'source map file', sourceMappingURL)
 | 
			
		||||
                            }
 | 
			
		||||
                        }
 | 
			
		||||
                        if (sourceContent) {
 | 
			
		||||
                            sourceMaps[fileName] = new SourceMapBuilder(JSON.parse(sourceContent))
 | 
			
		||||
                            sourceFileMaps[fileName] = Paths.get(fileName, '..', sourceMaps[fileName].sources[0]).toFile().getCanonicalPath()
 | 
			
		||||
                        }
 | 
			
		||||
                    }
 | 
			
		||||
                }
 | 
			
		||||
                if (sourceMaps[fileName]) {
 | 
			
		||||
                    let sourceMapping = sourceMaps[fileName].getSource(lineNumber, 25, true, true)
 | 
			
		||||
                    if (sourceMapping) {
 | 
			
		||||
                        fileName = Paths.get(fileName, '..', sourceMapping.sourcePath).toFile().getCanonicalPath()
 | 
			
		||||
                        lineNumber = sourceMapping.mapping.sourceLine
 | 
			
		||||
                    }
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
        } catch (error: any) {
 | 
			
		||||
            console.debug('search source map', fileName, 'line', lineNumber, 'error:', error)
 | 
			
		||||
            if (global.debug) {
 | 
			
		||||
                console.ex(error)
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
        return {
 | 
			
		||||
            fileName,
 | 
			
		||||
            lineNumber
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    export function getStackTrace(ex: Error, color: boolean = true): string[] {
 | 
			
		||||
        if (!ex) return []
 | 
			
		||||
        let stack = ex.getStackTrace()
 | 
			
		||||
        let cache = [(color ? '§c' : '') + ex]
 | 
			
		||||
        //@ts-ignore
 | 
			
		||||
        if (stack.class) {
 | 
			
		||||
            stack = Arrays.asList(stack)
 | 
			
		||||
        }
 | 
			
		||||
        stack.forEach(trace => {
 | 
			
		||||
            if (!trace.fileName || trace.fileName.startsWith('jar:file:') || trace.fileName.startsWith('file:')) { return }
 | 
			
		||||
            if (trace.className.startsWith('<')) {
 | 
			
		||||
                let { fileName, lineNumber } = readSourceMap(trace.fileName, trace.lineNumber)
 | 
			
		||||
                if (fileName.startsWith(root)) { fileName = fileName.split(root)[1] }
 | 
			
		||||
                if (color) {
 | 
			
		||||
                    cache.push(`    §e->§c ${fileName}:${lineNumber} => §4${trace.methodName}`)
 | 
			
		||||
                } else {
 | 
			
		||||
                    cache.push(`    -> ${fileName}:${lineNumber} => ${trace.methodName}`)
 | 
			
		||||
                }
 | 
			
		||||
            } else {
 | 
			
		||||
                let className = trace.className
 | 
			
		||||
                var fileName = trace.fileName as string
 | 
			
		||||
                var lineNumber = trace.lineNumber
 | 
			
		||||
                if (className.startsWith('jdk.nashorn.internal.scripts') || className.startsWith('org.openjdk.nashorn.internal.scripts')) {
 | 
			
		||||
                    className = className.substr(className.lastIndexOf('$') + 1)
 | 
			
		||||
                    var { fileName, lineNumber } = readSourceMap(fileName, lineNumber)
 | 
			
		||||
                    if (fileName.startsWith(root)) { fileName = fileName.split(root)[1] }
 | 
			
		||||
                } else {
 | 
			
		||||
                    if (!global.debug) {
 | 
			
		||||
                        for (let prefix in ignoreLogPrefix) {
 | 
			
		||||
                            if (className.startsWith(ignoreLogPrefix[prefix])) {
 | 
			
		||||
                                return
 | 
			
		||||
                            }
 | 
			
		||||
                        }
 | 
			
		||||
                    } else if (className.startsWith('jdk.nashorn.internal.') || className.startsWith('org.openjdk.nashorn.internal.')) {
 | 
			
		||||
                        return
 | 
			
		||||
                    }
 | 
			
		||||
                }
 | 
			
		||||
                if (color) {
 | 
			
		||||
                    cache.push(`    §e->§c ${className}.${trace.methodName}(§4${fileName}:${lineNumber}§c)`)
 | 
			
		||||
                } else {
 | 
			
		||||
                    cache.push(`    -> ${className}.${trace.methodName}(${fileName}:${lineNumber})`)
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
        })
 | 
			
		||||
        return cache
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
export class MiaoScriptConsole implements Console {
 | 
			
		||||
    Console: any
 | 
			
		||||
    memory: any
 | 
			
		||||
 | 
			
		||||
    private static sourceMaps: { [key: string]: SourceMapBuilder } = {}
 | 
			
		||||
    private static sourceFileMaps: { [key: string]: string } = {}
 | 
			
		||||
    private _name: string = ''
 | 
			
		||||
    private _level: LogLevel = LogLevel.INFO
 | 
			
		||||
 | 
			
		||||
@@ -92,91 +194,8 @@ export class MiaoScriptConsole implements Console {
 | 
			
		||||
    ex(ex: Error) {
 | 
			
		||||
        this.stack(ex).forEach(line => this.console(line))
 | 
			
		||||
    }
 | 
			
		||||
    readSourceMap(fileName: string, lineNumber: any) {
 | 
			
		||||
        try {
 | 
			
		||||
            if (fileName.endsWith('js')) {
 | 
			
		||||
                if (MiaoScriptConsole.sourceMaps[fileName] === undefined) {
 | 
			
		||||
                    MiaoScriptConsole.sourceMaps[fileName] = null
 | 
			
		||||
                    let sourceLine = base.read(fileName).split('\n')
 | 
			
		||||
                    let lastLine = sourceLine[sourceLine.length - 1]
 | 
			
		||||
                    // lastLine is similar //# sourceMappingURL=data:application/json;base64,
 | 
			
		||||
                    if (lastLine.startsWith('//# sourceMappingURL=')) {
 | 
			
		||||
                        let sourceContent = null
 | 
			
		||||
                        let sourceMappingURL = lastLine.split('sourceMappingURL=', 2)[1]
 | 
			
		||||
                        if (sourceMappingURL.startsWith('data:application/json;base64,')) {
 | 
			
		||||
                            sourceContent = String.fromCharCode(...Array.from(base64.toByteArray(sourceMappingURL.split(',', 2)[1])))
 | 
			
		||||
                        } else if (sourceMappingURL.startsWith('http://') || sourceMappingURL.startsWith('https://')) {
 | 
			
		||||
                            // TODO
 | 
			
		||||
                        } else {
 | 
			
		||||
                            let file = Paths.get(Paths.get(fileName, '..', sourceMappingURL).toFile().getCanonicalPath()).toFile()
 | 
			
		||||
                            if (file.exists()) { sourceContent = base.read(file) }
 | 
			
		||||
                        }
 | 
			
		||||
                        if (sourceContent) {
 | 
			
		||||
                            MiaoScriptConsole.sourceMaps[fileName] = new SourceMapBuilder(JSON.parse(sourceContent))
 | 
			
		||||
                            MiaoScriptConsole.sourceFileMaps[fileName] = Paths.get(fileName, '..', MiaoScriptConsole.sourceMaps[fileName].sources[0]).toFile().getCanonicalPath()
 | 
			
		||||
                        }
 | 
			
		||||
                    }
 | 
			
		||||
                }
 | 
			
		||||
                if (MiaoScriptConsole.sourceMaps[fileName]) {
 | 
			
		||||
                    let sourceMapping = MiaoScriptConsole.sourceMaps[fileName].getSource(lineNumber, 25, true, true)
 | 
			
		||||
                    fileName = MiaoScriptConsole.sourceFileMaps[fileName]
 | 
			
		||||
                    if (sourceMapping && lineNumber != sourceMapping.mapping.sourceLine) { lineNumber = sourceMapping.mapping.sourceLine }
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
        } catch (error: any) {
 | 
			
		||||
            console.debug('search source map', fileName, 'line', lineNumber, 'error:', error)
 | 
			
		||||
            if (global.debug) {
 | 
			
		||||
                console.ex(error)
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
        return {
 | 
			
		||||
            fileName,
 | 
			
		||||
            lineNumber
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
    stack(ex: Error, color: boolean = true): string[] {
 | 
			
		||||
        if (!ex) return []
 | 
			
		||||
        let stack = ex.getStackTrace()
 | 
			
		||||
        let cache = [(color ? '§c' : '') + ex]
 | 
			
		||||
        //@ts-ignore
 | 
			
		||||
        if (stack.class) {
 | 
			
		||||
            stack = Arrays.asList(stack)
 | 
			
		||||
        }
 | 
			
		||||
        stack.forEach(trace => {
 | 
			
		||||
            if (!trace.fileName || trace.fileName.startsWith('jar:file:') || trace.fileName.startsWith('file:')) { return }
 | 
			
		||||
            if (trace.className.startsWith('<')) {
 | 
			
		||||
                let { fileName, lineNumber } = this.readSourceMap(trace.fileName, trace.lineNumber)
 | 
			
		||||
                if (fileName.startsWith(root)) { fileName = fileName.split(root)[1] }
 | 
			
		||||
                if (color) {
 | 
			
		||||
                    cache.push(`    §e->§c ${fileName}:${lineNumber} => §4${trace.methodName}`)
 | 
			
		||||
                } else {
 | 
			
		||||
                    cache.push(`    -> ${fileName}:${lineNumber} => ${trace.methodName}`)
 | 
			
		||||
                }
 | 
			
		||||
            } else {
 | 
			
		||||
                let className = trace.className
 | 
			
		||||
                var fileName = trace.fileName as string
 | 
			
		||||
                var lineNumber = trace.lineNumber
 | 
			
		||||
                if (className.startsWith('jdk.nashorn.internal.scripts') || className.startsWith('org.openjdk.nashorn.internal.scripts')) {
 | 
			
		||||
                    className = className.substr(className.lastIndexOf('$') + 1)
 | 
			
		||||
                    var { fileName, lineNumber } = this.readSourceMap(fileName, lineNumber)
 | 
			
		||||
                    if (fileName.startsWith(root)) { fileName = fileName.split(root)[1] }
 | 
			
		||||
                } else {
 | 
			
		||||
                    if (!global.debug) {
 | 
			
		||||
                        for (let prefix in ignoreLogPrefix) {
 | 
			
		||||
                            if (className.startsWith(ignoreLogPrefix[prefix])) {
 | 
			
		||||
                                return
 | 
			
		||||
                            }
 | 
			
		||||
                        }
 | 
			
		||||
                    }
 | 
			
		||||
                }
 | 
			
		||||
                if (color) {
 | 
			
		||||
                    cache.push(`    §e->§c ${className}.${trace.methodName}(§4${fileName}:${lineNumber}§c)`)
 | 
			
		||||
                } else {
 | 
			
		||||
                    cache.push(`    -> ${className}.${trace.methodName}(${fileName}:${lineNumber})`)
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
        })
 | 
			
		||||
        return cache
 | 
			
		||||
        return jsconsole.getStackTrace(ex, color)
 | 
			
		||||
    }
 | 
			
		||||
    assert(value: any, message?: string, ...optionalParams: any[]): void {
 | 
			
		||||
        throw new Error("Method not implemented.")
 | 
			
		||||
 
 | 
			
		||||
@@ -11,10 +11,21 @@ export namespace constants {
 | 
			
		||||
    }
 | 
			
		||||
    export namespace Reflect {
 | 
			
		||||
        export const Method = {
 | 
			
		||||
            getServerConnection: [/*spigot 1.8.8*/'aq',/*spigot 1.12.2*/ 'an', /*spigot 1.14.4+*/'getServerConnection', /*catserver 1.12.2*/'func_147137_ag']
 | 
			
		||||
            getServerConnection: [
 | 
			
		||||
                /*spigot 1.8.8*/'aq',
 | 
			
		||||
                /*spigot 1.12.2*/ 'an',
 | 
			
		||||
                /*spigot 1.14.4+*/'getServerConnection',
 | 
			
		||||
                /*spigot 1.19+*/'ad',
 | 
			
		||||
                /*catserver 1.12.2*/'func_147137_ag'
 | 
			
		||||
            ]
 | 
			
		||||
        }
 | 
			
		||||
        export const Field = {
 | 
			
		||||
            listeningChannels: [/*spigot 1.8.8-1.12.2*/'g', /*spigot 1.14.4*/'f', /*spigot 1.15.2+*/'listeningChannels', /*catserver 1.12.2*/'field_151274_e']
 | 
			
		||||
            listeningChannels: [
 | 
			
		||||
                /*spigot 1.8.8-1.12.2*/'g',
 | 
			
		||||
                /*spigot 1.14.4*/'f',
 | 
			
		||||
                /*spigot 1.15.2+*/'listeningChannels',
 | 
			
		||||
                /*catserver 1.12.2*/'field_151274_e'
 | 
			
		||||
            ]
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
    export enum ServerType {
 | 
			
		||||
 
 | 
			
		||||
@@ -6,6 +6,10 @@ export namespace database {
 | 
			
		||||
     * 数据库配置
 | 
			
		||||
     */
 | 
			
		||||
    export interface DataBaseConfig {
 | 
			
		||||
        /**
 | 
			
		||||
         * 数据库类型
 | 
			
		||||
         */
 | 
			
		||||
        type: 'h2' | 'mysql' | 'mongodb' | 'sqlite' | 'postgres' | 'redis'
 | 
			
		||||
        /**
 | 
			
		||||
         * 数据库连接串
 | 
			
		||||
         */
 | 
			
		||||
 
 | 
			
		||||
@@ -4,11 +4,13 @@ export * from './web'
 | 
			
		||||
export * from './amqp'
 | 
			
		||||
export * from './chat'
 | 
			
		||||
export * from './task'
 | 
			
		||||
export * from './item'
 | 
			
		||||
export * from './event'
 | 
			
		||||
export * from './proxy'
 | 
			
		||||
export * from './plugin'
 | 
			
		||||
export * from './server'
 | 
			
		||||
export * from './console'
 | 
			
		||||
export { jsconsole as console } from './console'
 | 
			
		||||
export * from './channel'
 | 
			
		||||
export * from './command'
 | 
			
		||||
export * from './database'
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										20
									
								
								packages/api/src/item.ts
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										20
									
								
								packages/api/src/item.ts
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,20 @@
 | 
			
		||||
import { injectable } from '@ccms/container'
 | 
			
		||||
 | 
			
		||||
export namespace item {
 | 
			
		||||
    @injectable()
 | 
			
		||||
    export abstract class Item {
 | 
			
		||||
        abstract builder(): ItemBuilder
 | 
			
		||||
        abstract toJson(item: any): string
 | 
			
		||||
        abstract fromJSON(json: string): any
 | 
			
		||||
    }
 | 
			
		||||
    export interface ItemBuilder {
 | 
			
		||||
        from(item: any): ItemBuilder
 | 
			
		||||
        create(type: string | number): ItemBuilder
 | 
			
		||||
        name(name: string): ItemBuilder
 | 
			
		||||
        lore(...lores: string[]): ItemBuilder
 | 
			
		||||
        amount(amount: number): ItemBuilder
 | 
			
		||||
        durability(durability: number): ItemBuilder
 | 
			
		||||
        clone(): any
 | 
			
		||||
        build(): any
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
@@ -149,7 +149,15 @@ export namespace plugin {
 | 
			
		||||
        /**
 | 
			
		||||
         * 插件名称 不填默认为类名
 | 
			
		||||
         */
 | 
			
		||||
        name?: string
 | 
			
		||||
        name: string
 | 
			
		||||
        /**
 | 
			
		||||
         * 插件中文名称
 | 
			
		||||
         */
 | 
			
		||||
        cname?: string
 | 
			
		||||
        /**
 | 
			
		||||
         * 插件等级 付费插件自动注入
 | 
			
		||||
         */
 | 
			
		||||
        level?: number
 | 
			
		||||
        /**
 | 
			
		||||
         * 前缀
 | 
			
		||||
         */
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user