Compare commits
6 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| afb72a6794 | |||
| 40fb2869d5 | |||
| 8f3c0cc0bc | |||
| 2d281a13d1 | |||
| cf3016e27e | |||
| ba3ef49ee5 |
@@ -4,3 +4,8 @@
|
|||||||
- 更新日志 [](https://docs.yumc.pw/MiaoScript/CHANGELOG.html)
|
- 更新日志 [](https://docs.yumc.pw/MiaoScript/CHANGELOG.html)
|
||||||
- 安装文档 [](https://docs.yumc.pw/MiaoScript/1-user/1.1-check-env.html)
|
- 安装文档 [](https://docs.yumc.pw/MiaoScript/1-user/1.1-check-env.html)
|
||||||
- 开发文档 [](https://docs.yumc.pw/MiaoScript/2-develop/1.1-check-env.html)
|
- 开发文档 [](https://docs.yumc.pw/MiaoScript/2-develop/1.1-check-env.html)
|
||||||
|
- 兼容服务端 Spigot CatServer Sponge BungeeCord Nukkit(没错 他还兼容Nukkit)
|
||||||
|
|
||||||
|
### 腐竹版本(开发中)
|
||||||
|
|
||||||
|
- 先上几张图
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
{
|
{
|
||||||
"version": "0.6.7",
|
"version": "0.7.0",
|
||||||
"useWorkspaces": true,
|
"useWorkspaces": true,
|
||||||
"npmClient": "yarn",
|
"npmClient": "yarn",
|
||||||
"packages": [
|
"packages": [
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "@ccms/api",
|
"name": "@ccms/api",
|
||||||
"version": "0.6.7",
|
"version": "0.7.0",
|
||||||
"description": "MiaoScript api package",
|
"description": "MiaoScript api package",
|
||||||
"keywords": [
|
"keywords": [
|
||||||
"miaoscript",
|
"miaoscript",
|
||||||
@@ -19,8 +19,8 @@
|
|||||||
"test": "echo \"Error: run tests from root\" && exit 1"
|
"test": "echo \"Error: run tests from root\" && exit 1"
|
||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@ccms/container": "^0.6.7",
|
"@ccms/container": "^0.7.0",
|
||||||
"@ccms/ployfill": "^0.6.7",
|
"@ccms/ployfill": "^0.7.0",
|
||||||
"base64-js": "^1.3.1",
|
"base64-js": "^1.3.1",
|
||||||
"source-map-builder": "^0.0.7"
|
"source-map-builder": "^0.0.7"
|
||||||
},
|
},
|
||||||
|
|||||||
@@ -140,7 +140,7 @@ export class MiaoScriptConsole implements Console {
|
|||||||
if (trace.className.startsWith('<')) {
|
if (trace.className.startsWith('<')) {
|
||||||
let { fileName, lineNumber } = this.readSourceMap(trace.fileName, trace.lineNumber)
|
let { fileName, lineNumber } = this.readSourceMap(trace.fileName, trace.lineNumber)
|
||||||
if (fileName.startsWith(root)) { fileName = fileName.split(root)[1] }
|
if (fileName.startsWith(root)) { fileName = fileName.split(root)[1] }
|
||||||
cache.push(` §e->§c ${fileName} => §4${trace.methodName}:${lineNumber}`)
|
cache.push(` §e->§c ${fileName}:${lineNumber} => §4${trace.methodName}`)
|
||||||
} else {
|
} else {
|
||||||
let className = trace.className;
|
let className = trace.className;
|
||||||
var fileName = trace.fileName as string;
|
var fileName = trace.fileName as string;
|
||||||
|
|||||||
@@ -11,6 +11,7 @@ export namespace constants {
|
|||||||
Bukkit = 'bukkit',
|
Bukkit = 'bukkit',
|
||||||
Sponge = 'sponge',
|
Sponge = 'sponge',
|
||||||
Nukkit = 'nukkit',
|
Nukkit = 'nukkit',
|
||||||
Bungee = 'bungee'
|
Bungee = 'bungee',
|
||||||
|
Spring = 'spring'
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -33,5 +33,6 @@ export namespace server {
|
|||||||
getNettyPipeline(): any;
|
getNettyPipeline(): any;
|
||||||
getRootLogger(): any;
|
getRootLogger(): any;
|
||||||
sendJson(sender: string | any, json: object | string): void;
|
sendJson(sender: string | any, json: object | string): void;
|
||||||
|
tabComplete?(sender: string | any, input: string, index?: number);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "@ccms/bukkit",
|
"name": "@ccms/bukkit",
|
||||||
"version": "0.6.7",
|
"version": "0.7.0",
|
||||||
"description": "MiaoScript bukkit package",
|
"description": "MiaoScript bukkit package",
|
||||||
"keywords": [
|
"keywords": [
|
||||||
"miaoscript",
|
"miaoscript",
|
||||||
@@ -24,8 +24,8 @@
|
|||||||
"typescript": "^3.9.2"
|
"typescript": "^3.9.2"
|
||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@ccms/api": "^0.6.7",
|
"@ccms/api": "^0.7.0",
|
||||||
"@ccms/common": "^0.6.7",
|
"@ccms/common": "^0.7.0",
|
||||||
"@ccms/container": "^0.6.7"
|
"@ccms/container": "^0.7.0"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "@ccms/bungee",
|
"name": "@ccms/bungee",
|
||||||
"version": "0.6.7",
|
"version": "0.7.0",
|
||||||
"description": "MiaoScript bungee package",
|
"description": "MiaoScript bungee package",
|
||||||
"keywords": [
|
"keywords": [
|
||||||
"miaoscript",
|
"miaoscript",
|
||||||
@@ -24,8 +24,8 @@
|
|||||||
"typescript": "^3.9.2"
|
"typescript": "^3.9.2"
|
||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@ccms/api": "^0.6.7",
|
"@ccms/api": "^0.7.0",
|
||||||
"@ccms/common": "^0.6.7",
|
"@ccms/common": "^0.7.0",
|
||||||
"@ccms/container": "^0.6.7"
|
"@ccms/container": "^0.7.0"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
{
|
{
|
||||||
"private": true,
|
"private": true,
|
||||||
"name": "@ccms/client",
|
"name": "@ccms/client",
|
||||||
"version": "0.6.7",
|
"version": "0.7.0",
|
||||||
"description": "MiaoScript client package",
|
"description": "MiaoScript client package",
|
||||||
"keywords": [
|
"keywords": [
|
||||||
"miaoscript",
|
"miaoscript",
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "@ccms/common",
|
"name": "@ccms/common",
|
||||||
"version": "0.6.7",
|
"version": "0.7.0",
|
||||||
"description": "MiaoScript api package",
|
"description": "MiaoScript api package",
|
||||||
"keywords": [
|
"keywords": [
|
||||||
"miaoscript",
|
"miaoscript",
|
||||||
@@ -24,7 +24,7 @@
|
|||||||
"typescript": "^3.9.2"
|
"typescript": "^3.9.2"
|
||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@ccms/nashorn": "^0.6.7"
|
"@ccms/nashorn": "^0.7.0"
|
||||||
},
|
},
|
||||||
"gitHead": "562e2d00175c9d3a99c8b672aa07e6d92706a027"
|
"gitHead": "562e2d00175c9d3a99c8b672aa07e6d92706a027"
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "@ccms/compile",
|
"name": "@ccms/compile",
|
||||||
"version": "0.6.7",
|
"version": "0.7.0",
|
||||||
"description": "MiaoScript compile package",
|
"description": "MiaoScript compile package",
|
||||||
"keywords": [
|
"keywords": [
|
||||||
"miaoscript",
|
"miaoscript",
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "@ccms/container",
|
"name": "@ccms/container",
|
||||||
"version": "0.6.7",
|
"version": "0.7.0",
|
||||||
"description": "MiaoScript container package",
|
"description": "MiaoScript container package",
|
||||||
"keywords": [
|
"keywords": [
|
||||||
"miaoscript",
|
"miaoscript",
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "@ccms/core",
|
"name": "@ccms/core",
|
||||||
"version": "0.6.7",
|
"version": "0.7.0",
|
||||||
"description": "MiaoScript api package",
|
"description": "MiaoScript api package",
|
||||||
"keywords": [
|
"keywords": [
|
||||||
"miaoscript",
|
"miaoscript",
|
||||||
@@ -24,8 +24,8 @@
|
|||||||
"typescript": "^3.9.2"
|
"typescript": "^3.9.2"
|
||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@ccms/api": "^0.6.7",
|
"@ccms/api": "^0.7.0",
|
||||||
"@ccms/container": "^0.6.7"
|
"@ccms/container": "^0.7.0"
|
||||||
},
|
},
|
||||||
"gitHead": "781524f83e52cad26d7c480513e3c525df867121"
|
"gitHead": "781524f83e52cad26d7c480513e3c525df867121"
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -80,6 +80,11 @@ function detectServer(): constants.ServerType {
|
|||||||
return constants.ServerType.Bungee
|
return constants.ServerType.Bungee
|
||||||
} catch (ex) {
|
} catch (ex) {
|
||||||
}
|
}
|
||||||
|
try {
|
||||||
|
Java.type("org.springframework.boot.SpringApplication")
|
||||||
|
return constants.ServerType.Spring
|
||||||
|
} catch (ex) {
|
||||||
|
}
|
||||||
throw Error('Unknow Server Type...')
|
throw Error('Unknow Server Type...')
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "@ccms/i18n",
|
"name": "@ccms/i18n",
|
||||||
"version": "0.6.7",
|
"version": "0.7.0",
|
||||||
"description": "MiaoScript i18n package",
|
"description": "MiaoScript i18n package",
|
||||||
"keywords": [
|
"keywords": [
|
||||||
"miaoscript",
|
"miaoscript",
|
||||||
@@ -25,7 +25,7 @@
|
|||||||
"typescript": "^3.9.2"
|
"typescript": "^3.9.2"
|
||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@ccms/nashorn": "^0.6.7",
|
"@ccms/nashorn": "^0.7.0",
|
||||||
"js-yaml": "^3.13.1"
|
"js-yaml": "^3.13.1"
|
||||||
},
|
},
|
||||||
"gitHead": "781524f83e52cad26d7c480513e3c525df867121"
|
"gitHead": "781524f83e52cad26d7c480513e3c525df867121"
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "@ccms/nashorn",
|
"name": "@ccms/nashorn",
|
||||||
"version": "0.6.7",
|
"version": "0.7.0",
|
||||||
"description": "MiaoScript api package",
|
"description": "MiaoScript api package",
|
||||||
"keywords": [
|
"keywords": [
|
||||||
"miaoscript",
|
"miaoscript",
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "@ccms/nodejs",
|
"name": "@ccms/nodejs",
|
||||||
"version": "0.6.7",
|
"version": "0.7.0",
|
||||||
"description": "MiaoScript nodejs package",
|
"description": "MiaoScript nodejs package",
|
||||||
"keywords": [
|
"keywords": [
|
||||||
"miaoscript",
|
"miaoscript",
|
||||||
@@ -24,7 +24,7 @@
|
|||||||
"typescript": "^3.9.2"
|
"typescript": "^3.9.2"
|
||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@ccms/nashorn": "^0.6.7"
|
"@ccms/nashorn": "^0.7.0"
|
||||||
},
|
},
|
||||||
"gitHead": "781524f83e52cad26d7c480513e3c525df867121"
|
"gitHead": "781524f83e52cad26d7c480513e3c525df867121"
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "@ccms/nukkit",
|
"name": "@ccms/nukkit",
|
||||||
"version": "0.6.7",
|
"version": "0.7.0",
|
||||||
"description": "MiaoScript nukkit package",
|
"description": "MiaoScript nukkit package",
|
||||||
"keywords": [
|
"keywords": [
|
||||||
"miaoscript",
|
"miaoscript",
|
||||||
@@ -24,8 +24,8 @@
|
|||||||
"typescript": "^3.9.2"
|
"typescript": "^3.9.2"
|
||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@ccms/api": "^0.6.7",
|
"@ccms/api": "^0.7.0",
|
||||||
"@ccms/common": "^0.6.7",
|
"@ccms/common": "^0.7.0",
|
||||||
"@ccms/container": "^0.6.7"
|
"@ccms/container": "^0.7.0"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "@ccms/ployfill",
|
"name": "@ccms/ployfill",
|
||||||
"version": "0.6.7",
|
"version": "0.7.0",
|
||||||
"description": "MiaoScript ployfill package",
|
"description": "MiaoScript ployfill package",
|
||||||
"author": "MiaoWoo <admin@yumc.pw>",
|
"author": "MiaoWoo <admin@yumc.pw>",
|
||||||
"homepage": "https://github.com/circlecloud/ms.git",
|
"homepage": "https://github.com/circlecloud/ms.git",
|
||||||
@@ -14,8 +14,8 @@
|
|||||||
"test": "echo \"Error: run tests from root\" && exit 1"
|
"test": "echo \"Error: run tests from root\" && exit 1"
|
||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@ccms/i18n": "^0.6.7",
|
"@ccms/i18n": "^0.7.0",
|
||||||
"@ccms/nashorn": "^0.6.7",
|
"@ccms/nashorn": "^0.7.0",
|
||||||
"core-js": "^3.6.5"
|
"core-js": "^3.6.5"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "@ccms/plugin",
|
"name": "@ccms/plugin",
|
||||||
"version": "0.6.7",
|
"version": "0.7.0",
|
||||||
"description": "MiaoScript api package",
|
"description": "MiaoScript api package",
|
||||||
"keywords": [
|
"keywords": [
|
||||||
"miaoscript",
|
"miaoscript",
|
||||||
@@ -25,10 +25,10 @@
|
|||||||
"typescript": "^3.9.2"
|
"typescript": "^3.9.2"
|
||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@ccms/api": "^0.6.7",
|
"@ccms/api": "^0.7.0",
|
||||||
"@ccms/common": "^0.6.7",
|
"@ccms/common": "^0.7.0",
|
||||||
"@ccms/container": "^0.6.7",
|
"@ccms/container": "^0.7.0",
|
||||||
"@ccms/i18n": "^0.6.7",
|
"@ccms/i18n": "^0.7.0",
|
||||||
"js-yaml": "^3.13.1"
|
"js-yaml": "^3.13.1"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
import { injectable, decorate } from "@ccms/container";
|
import { injectable, decorate } from "@ccms/container"
|
||||||
import { interfaces } from './interfaces'
|
import { interfaces } from './interfaces'
|
||||||
import { METADATA_KEY } from './constants'
|
import { METADATA_KEY } from './constants'
|
||||||
import { getPluginMetadatas, getPluginCommandMetadata, getPluginListenerMetadata, getPluginTabCompleterMetadata, getPluginConfigMetadata, getPluginStageMetadata, getPluginSources } from './utils'
|
import { getPluginMetadatas, getPluginCommandMetadata, getPluginListenerMetadata, getPluginTabCompleterMetadata, getPluginConfigMetadata, getPluginStageMetadata, getPluginSources } from './utils'
|
||||||
@@ -9,17 +9,17 @@ import { getPluginMetadatas, getPluginCommandMetadata, getPluginListenerMetadata
|
|||||||
*/
|
*/
|
||||||
export function plugin(metadata: interfaces.PluginMetadata) {
|
export function plugin(metadata: interfaces.PluginMetadata) {
|
||||||
return function (target: any) {
|
return function (target: any) {
|
||||||
metadata.target = target;
|
metadata.target = target
|
||||||
metadata.type = "ioc";
|
metadata.type = "ioc"
|
||||||
decorate(injectable(), target);
|
decorate(injectable(), target)
|
||||||
Reflect.defineMetadata(METADATA_KEY.plugin, metadata, target);
|
Reflect.defineMetadata(METADATA_KEY.plugin, metadata, target)
|
||||||
const previousMetadata: Map<string, interfaces.PluginMetadata> = getPluginMetadatas();
|
const previousMetadata: Map<string, interfaces.PluginMetadata> = getPluginMetadatas()
|
||||||
previousMetadata.set(metadata.name, metadata);
|
previousMetadata.set(metadata.name, metadata)
|
||||||
Reflect.defineMetadata(METADATA_KEY.plugin, previousMetadata, Reflect);
|
Reflect.defineMetadata(METADATA_KEY.plugin, previousMetadata, Reflect)
|
||||||
const previousSources: Map<string, interfaces.PluginMetadata> = getPluginSources();
|
const previousSources: Map<string, interfaces.PluginMetadata> = getPluginSources()
|
||||||
previousSources.set(metadata.source.toString(), metadata);
|
previousSources.set(metadata.source.toString(), metadata)
|
||||||
Reflect.defineMetadata(METADATA_KEY.souece, previousSources, Reflect);
|
Reflect.defineMetadata(METADATA_KEY.souece, previousSources, Reflect)
|
||||||
};
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -28,13 +28,13 @@ export function plugin(metadata: interfaces.PluginMetadata) {
|
|||||||
*/
|
*/
|
||||||
export function cmd(metadata: interfaces.CommandMetadata = {}) {
|
export function cmd(metadata: interfaces.CommandMetadata = {}) {
|
||||||
return function (target: any, key: string, value: any) {
|
return function (target: any, key: string, value: any) {
|
||||||
metadata.name = metadata.name || key;
|
metadata.name = metadata.name || key
|
||||||
metadata.executor = key;
|
metadata.executor = key
|
||||||
metadata.paramtypes = Reflect.getMetadata("design:paramtypes", target, key)
|
metadata.paramtypes = Reflect.getMetadata("design:paramtypes", target, key)
|
||||||
const previousMetadata: Map<string, interfaces.CommandMetadata> = getPluginCommandMetadata(target)
|
const previousMetadata: Map<string, interfaces.CommandMetadata> = getPluginCommandMetadata(target)
|
||||||
previousMetadata.set(metadata.name, metadata);
|
previousMetadata.set(metadata.name, metadata)
|
||||||
Reflect.defineMetadata(METADATA_KEY.cmd, previousMetadata, target.constructor);
|
Reflect.defineMetadata(METADATA_KEY.cmd, previousMetadata, target.constructor)
|
||||||
};
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -43,14 +43,14 @@ export function cmd(metadata: interfaces.CommandMetadata = {}) {
|
|||||||
*/
|
*/
|
||||||
export function tab(metadata: interfaces.CommandMetadata = {}) {
|
export function tab(metadata: interfaces.CommandMetadata = {}) {
|
||||||
return function (target: any, key: string, value: any) {
|
return function (target: any, key: string, value: any) {
|
||||||
metadata.name = metadata.name || (key.startsWith('tab') ? key.split('tab', 2)[1] : key);
|
metadata.name = metadata.name || (key.startsWith('tab') ? key.split('tab', 2)[1] : key)
|
||||||
if (!metadata.name) { return; }
|
if (!metadata.name) { return }
|
||||||
metadata.executor = key;
|
metadata.executor = key
|
||||||
metadata.paramtypes = Reflect.getMetadata("design:paramtypes", target, key)
|
metadata.paramtypes = Reflect.getMetadata("design:paramtypes", target, key)
|
||||||
const previousMetadata: Map<string, interfaces.CommandMetadata> = getPluginTabCompleterMetadata(target)
|
const previousMetadata: Map<string, interfaces.CommandMetadata> = getPluginTabCompleterMetadata(target)
|
||||||
previousMetadata.set(metadata.name, metadata)
|
previousMetadata.set(metadata.name, metadata)
|
||||||
Reflect.defineMetadata(METADATA_KEY.tab, previousMetadata, target.constructor);
|
Reflect.defineMetadata(METADATA_KEY.tab, previousMetadata, target.constructor)
|
||||||
};
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -59,30 +59,32 @@ export function tab(metadata: interfaces.CommandMetadata = {}) {
|
|||||||
*/
|
*/
|
||||||
export function listener(metadata: interfaces.ListenerMetadata = {}) {
|
export function listener(metadata: interfaces.ListenerMetadata = {}) {
|
||||||
return function (target: any, key: string, value: any) {
|
return function (target: any, key: string, value: any) {
|
||||||
metadata.name = metadata.name || key;
|
metadata.name = metadata.name || key
|
||||||
metadata.executor = key;
|
metadata.executor = key
|
||||||
const previousMetadata: interfaces.ListenerMetadata[] = getPluginListenerMetadata(target)
|
const previousMetadata: interfaces.ListenerMetadata[] = getPluginListenerMetadata(target)
|
||||||
Reflect.defineMetadata(METADATA_KEY.listener, [metadata, ...previousMetadata], target.constructor);
|
Reflect.defineMetadata(METADATA_KEY.listener, [metadata, ...previousMetadata], target.constructor)
|
||||||
};
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
export function config(metadata: interfaces.ConfigMetadata = { version: 1, format: 'yml' }) {
|
export function config(metadata: interfaces.ConfigMetadata = {}) {
|
||||||
return function (target: any, key: string) {
|
return function (target: any, key: string) {
|
||||||
metadata.name = metadata.name || key;
|
metadata.name = metadata.name || key
|
||||||
metadata.variable = key;
|
metadata.variable = key
|
||||||
|
metadata.version = metadata.version ?? 1
|
||||||
|
metadata.format = metadata.format ?? 'yml'
|
||||||
const previousMetadata: Map<string, interfaces.ConfigMetadata> = getPluginConfigMetadata(target)
|
const previousMetadata: Map<string, interfaces.ConfigMetadata> = getPluginConfigMetadata(target)
|
||||||
previousMetadata.set(metadata.name, metadata);
|
previousMetadata.set(metadata.name, metadata)
|
||||||
Reflect.defineMetadata(METADATA_KEY.config, previousMetadata, target.constructor);
|
Reflect.defineMetadata(METADATA_KEY.config, previousMetadata, target.constructor)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function stage(metadata: interfaces.ExecMetadata = {}, stage: string) {
|
function stage(metadata: interfaces.ExecMetadata = {}, stage: string) {
|
||||||
return function (target: any, key: string, value: any) {
|
return function (target: any, key: string, value: any) {
|
||||||
metadata.name = metadata.name || key;
|
metadata.name = metadata.name || key
|
||||||
metadata.executor = key;
|
metadata.executor = key
|
||||||
const previousMetadata: interfaces.ExecMetadata[] = getPluginStageMetadata(target, stage)
|
const previousMetadata: interfaces.ExecMetadata[] = getPluginStageMetadata(target, stage)
|
||||||
Reflect.defineMetadata(METADATA_KEY.stage[stage], [metadata, ...previousMetadata], target.constructor);
|
Reflect.defineMetadata(METADATA_KEY.stage[stage], [metadata, ...previousMetadata], target.constructor)
|
||||||
};
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
export function load(metadata: interfaces.ExecMetadata = {}) {
|
export function load(metadata: interfaces.ExecMetadata = {}) {
|
||||||
|
|||||||
@@ -30,8 +30,8 @@ export class PluginManagerImpl implements plugin.PluginManager {
|
|||||||
private pluginMetadataMap: Map<string, interfaces.PluginMetadata>
|
private pluginMetadataMap: Map<string, interfaces.PluginMetadata>
|
||||||
|
|
||||||
initialize() {
|
initialize() {
|
||||||
if (this.pluginInstance !== null && this.initialized !== true) {
|
if (this.pluginInstance === undefined) { throw new Error("Can't found Plugin Instance!") }
|
||||||
// 如果plugin不等于null 则代表是正式环境
|
if (this.initialized !== true) {
|
||||||
console.i18n('ms.plugin.initialize', { plugin: this.pluginInstance, loader: Thread.currentThread().contextClassLoader })
|
console.i18n('ms.plugin.initialize', { plugin: this.pluginInstance, loader: Thread.currentThread().contextClassLoader })
|
||||||
console.i18n('ms.plugin.event.map', { count: this.EventManager.mapEventName().toFixed(0), type: this.serverType })
|
console.i18n('ms.plugin.event.map', { count: this.EventManager.mapEventName().toFixed(0), type: this.serverType })
|
||||||
this.pluginRequireMap = new Map()
|
this.pluginRequireMap = new Map()
|
||||||
@@ -262,7 +262,12 @@ export class PluginManagerImpl implements plugin.PluginManager {
|
|||||||
console.i18n("ms.plugin.manager.config.save.default", { plugin: plugin.description.name, name: config.name, format: config.format })
|
console.i18n("ms.plugin.manager.config.save.default", { plugin: plugin.description.name, name: config.name, format: config.format })
|
||||||
} else {
|
} else {
|
||||||
plugin[config.variable] = configFactory.load(base.read(configFile))
|
plugin[config.variable] = configFactory.load(base.read(configFile))
|
||||||
plugin[config.variable].save = () => base.save(configFile, configFactory.dump(plugin[config.variable]))
|
plugin[config.variable].save = () => {
|
||||||
|
let result = configFactory.dump(plugin[config.variable])
|
||||||
|
base.save(configFile, result)
|
||||||
|
console.debug(`[${plugin.description.name}] Save Config ${config.variable} to file ${configFile} result ${result}`)
|
||||||
|
}
|
||||||
|
console.debug(`[${plugin.description.name}] Load Config ${config.variable} from file ${configFile} result ${JSON.stringify(plugin[config.variable])}`)
|
||||||
}
|
}
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.i18n("ms.plugin.manager.config.load.error", { plugin: plugin.description.name, name: config.name, format: config.format, error })
|
console.i18n("ms.plugin.manager.config.load.error", { plugin: plugin.description.name, name: config.name, format: config.format, error })
|
||||||
|
|||||||
60
packages/plugins/docs/MiaoConsole.md
Normal file
60
packages/plugins/docs/MiaoConsole.md
Normal file
@@ -0,0 +1,60 @@
|
|||||||
|
## 前言
|
||||||
|
|
||||||
|
> 各位开发 在调试Minecraft插件的时候 是不是经常面临下列情况
|
||||||
|
- 编译等半天 重启等半天 测试找不到问题
|
||||||
|
- 后台 IDE SCP/FTP 来回切换
|
||||||
|
|
||||||
|
### 什么是MiaoConsole
|
||||||
|
- MiaoConsole 是 基于 MiaoScript 开发的 在线调试工具
|
||||||
|
- 通过复用 Minecraft的Netty 通道 实现服务器端口 在线调试(并不是Java的调试哦)
|
||||||
|
|
||||||
|
### 工具动图
|
||||||
|
|
||||||
|

|
||||||
|

|
||||||
|
|
||||||
|
### MiaoConsole 有哪些功能
|
||||||
|
- 无需编译 上传等步骤 实时在线debug
|
||||||
|
- 实时转发服务端日志 无需来回切换
|
||||||
|
- 基于Nashorn的动态脚本语言
|
||||||
|
- 基于TypeScript的自动补全逻辑(以实现BungeeCord Sponge Bukkit的API全自动补全)
|
||||||
|
|
||||||
|
### MiaoConsole 的兼容性
|
||||||
|
- 跨端兼容 Sponge Bukkit BungeeCord
|
||||||
|
- Bukkit 支持 1.12.2 +(由于1.12.2以下版本Netty版本过老需要适配 后续兼容到1.7.10)
|
||||||
|
- Sponge 理论上全兼容
|
||||||
|
- CatServer 暂未测试 理论上兼容 1.12.2
|
||||||
|
- BungeeCord ~~终端转发暂未兼容~~ 已经能兼容了
|
||||||
|
|
||||||
|
### 安装教程
|
||||||
|
- 安装MiaoScript [下载地址](http://w.yumc.pw/free.html#MiaoScript-download)
|
||||||
|
- 首次启动 等待加载基础环境类库
|
||||||
|
- 执行 `mpm i MiaoConsole`
|
||||||
|
|
||||||
|
### 使用教程
|
||||||
|
- 执行 `mconsole token` 获得临时Token
|
||||||
|
- 打开 `http://ms.yumc.pw/console.html`
|
||||||
|
- 在地址栏输入服务器地址 需要带上端口
|
||||||
|
- 在Token栏输入获取到的Token
|
||||||
|
- 点击链接即可
|
||||||
|
|
||||||
|
### 终端使用
|
||||||
|
- 支持实时传输服务器日志到终端
|
||||||
|
- 直接在终端输入命令 会转发到服务器
|
||||||
|
- 目前暂不支持命令自动补全
|
||||||
|
- 支持命令历史
|
||||||
|
|
||||||
|
### 代码编辑器使用
|
||||||
|
- 支持 Java 的 lang包和util包自动补全
|
||||||
|
- 支持服务端所有代码补全
|
||||||
|
- 注意 暂时不支持自动导入包 所以需要手动输入全类名
|
||||||
|
- 快捷键说明(选中代码后 只会执行选中部分)
|
||||||
|
- Ctrl + R 执行代码
|
||||||
|
- Ctrl + E 执行命令
|
||||||
|
- Ctrl + Q 切换代码页
|
||||||
|
|
||||||
|
### RoadMap
|
||||||
|
- 支持命令自动补全
|
||||||
|
- 支持常用的开发脚本
|
||||||
|
- 支持快捷操作服务器数据
|
||||||
|
- 支持在线编辑服务器文件(开发了一半)
|
||||||
0
packages/plugins/docs/MiaoScript.md
Normal file
0
packages/plugins/docs/MiaoScript.md
Normal file
@@ -1,7 +1,7 @@
|
|||||||
{
|
{
|
||||||
"private": true,
|
"private": true,
|
||||||
"name": "@ccms/plugins",
|
"name": "@ccms/plugins",
|
||||||
"version": "0.6.7",
|
"version": "0.7.0",
|
||||||
"description": "MiaoScript plugins package",
|
"description": "MiaoScript plugins package",
|
||||||
"keywords": [
|
"keywords": [
|
||||||
"miaoscript",
|
"miaoscript",
|
||||||
@@ -25,8 +25,8 @@
|
|||||||
"typescript": "^3.9.2"
|
"typescript": "^3.9.2"
|
||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@ccms/api": "^0.6.7",
|
"@ccms/api": "^0.7.0",
|
||||||
"@ccms/container": "^0.6.7",
|
"@ccms/container": "^0.7.0",
|
||||||
"@ccms/plugin": "^0.6.7"
|
"@ccms/plugin": "^0.7.0"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -37,7 +37,7 @@ export class MiaoConsole extends interfaces.Plugin {
|
|||||||
private pluginFolder: string
|
private pluginFolder: string
|
||||||
|
|
||||||
private token: string
|
private token: string
|
||||||
private pipeline: any
|
private instance: any
|
||||||
private socketIOServer: SocketIOServer
|
private socketIOServer: SocketIOServer
|
||||||
private rootLogger: any
|
private rootLogger: any
|
||||||
private appender: any
|
private appender: any
|
||||||
@@ -49,7 +49,7 @@ export class MiaoConsole extends interfaces.Plugin {
|
|||||||
load() {
|
load() {
|
||||||
if (this.secret.token) {
|
if (this.secret.token) {
|
||||||
this.token = this.secret.token
|
this.token = this.secret.token
|
||||||
this.logger.console(`§4已从配置文件加载永久Token 请注意服务器安全!`)
|
this.logger.console(`§c已从配置文件加载永久Token §4请注意服务器安全!`)
|
||||||
} else {
|
} else {
|
||||||
this.token = Java.type('java.util.UUID').randomUUID().toString()
|
this.token = Java.type('java.util.UUID').randomUUID().toString()
|
||||||
this.logger.console(`§6已生成随机Token: §3${this.token} §c重启后或重新生成后失效!`)
|
this.logger.console(`§6已生成随机Token: §3${this.token} §c重启后或重新生成后失效!`)
|
||||||
@@ -98,14 +98,17 @@ export class MiaoConsole extends interfaces.Plugin {
|
|||||||
enable() {
|
enable() {
|
||||||
let count = 0
|
let count = 0
|
||||||
let wait = this.task.create(() => {
|
let wait = this.task.create(() => {
|
||||||
this.pipeline = this.server.getNettyPipeline()
|
this.instance = this.server.getNettyPipeline()
|
||||||
if (this.pipeline) {
|
if (this.instance) {
|
||||||
wait.cancel()
|
wait?.cancel()
|
||||||
this.createSocketIOServer()
|
this.createSocketIOServer()
|
||||||
this.startSocketIOServer()
|
this.startSocketIOServer()
|
||||||
}
|
}
|
||||||
if (count > 30) { wait.cancel() }
|
if (count++ > 30) {
|
||||||
count++
|
wait?.cancel()
|
||||||
|
this.logger.console('§cNetty通道注入失败 §4所有功能将无法使用!')
|
||||||
|
return
|
||||||
|
}
|
||||||
}).later(20).timer(40).submit()
|
}).later(20).timer(40).submit()
|
||||||
this.rootLogger = this.server.getRootLogger()
|
this.rootLogger = this.server.getRootLogger()
|
||||||
}
|
}
|
||||||
@@ -125,7 +128,7 @@ export class MiaoConsole extends interfaces.Plugin {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@enable({ servers: [constants.ServerType.Bungee] })
|
@enable({ servers: [constants.ServerType.Bungee] })
|
||||||
addJavaLoggerForward() {
|
addLoggerForward() {
|
||||||
if (this.rootLogger) {
|
if (this.rootLogger) {
|
||||||
let AbstractHandler = Java.type('java.util.logging.Handler')
|
let AbstractHandler = Java.type('java.util.logging.Handler')
|
||||||
let ProxyHandler = Java.extend(AbstractHandler, {
|
let ProxyHandler = Java.extend(AbstractHandler, {
|
||||||
@@ -138,6 +141,20 @@ export class MiaoConsole extends interfaces.Plugin {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@enable({ servers: [constants.ServerType.Spring] })
|
||||||
|
addLogbackForward() {
|
||||||
|
if (this.rootLogger) {
|
||||||
|
let AppenderBase = Java.type('ch.qos.logback.core.AppenderBase')
|
||||||
|
let ProxyAppender = Java.extend(AppenderBase, {
|
||||||
|
append: (logEvent) => global.eventCenter.emit('log', logEvent.getFormattedMessage())
|
||||||
|
})
|
||||||
|
this.appender = new ProxyAppender()
|
||||||
|
this.appender.setName("NashornProxyAppender")
|
||||||
|
this.appender.setContext(this.rootLogger.getLoggerContext())
|
||||||
|
this.rootLogger.addAppender(this.appender)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
disable() {
|
disable() {
|
||||||
if (this.socketIOServer) {
|
if (this.socketIOServer) {
|
||||||
this.socketIOServer.close()
|
this.socketIOServer.close()
|
||||||
@@ -159,7 +176,7 @@ export class MiaoConsole extends interfaces.Plugin {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@disable({ servers: [constants.ServerType.Bungee] })
|
@disable({ servers: [constants.ServerType.Bungee] })
|
||||||
removeJavaLoggerForward() {
|
removeLoggerForward() {
|
||||||
try {
|
try {
|
||||||
this.rootLogger.removeHandler(this.handler)
|
this.rootLogger.removeHandler(this.handler)
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
@@ -167,8 +184,17 @@ export class MiaoConsole extends interfaces.Plugin {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@disable({ servers: [constants.ServerType.Spring] })
|
||||||
|
removeLogbackForward() {
|
||||||
|
try {
|
||||||
|
this.rootLogger.detachAppender("NashornProxyAppender")
|
||||||
|
} catch (error) {
|
||||||
|
console.ex(error)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
createSocketIOServer() {
|
createSocketIOServer() {
|
||||||
this.socketIOServer = io(this.pipeline, {
|
this.socketIOServer = io(this.instance, {
|
||||||
path: '/ws',
|
path: '/ws',
|
||||||
root: fs.concat(root, 'wwwroot')
|
root: fs.concat(root, 'wwwroot')
|
||||||
})
|
})
|
||||||
@@ -224,6 +250,13 @@ export class MiaoConsole extends interfaces.Plugin {
|
|||||||
fn('§6插件 §a' + name + ' §4更新异常 错误: ' + error)
|
fn('§6插件 §a' + name + ' §4更新异常 错误: ' + error)
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
client.on('ls', (file: string, fn) => {
|
||||||
|
let dir = fs.file(file);
|
||||||
|
if (!dir.isDirectory()) {
|
||||||
|
return fn(undefined, `${file} 不是一个目录!`)
|
||||||
|
}
|
||||||
|
fn(fs.list(dir))
|
||||||
|
})
|
||||||
client.on('error', (error) => {
|
client.on('error', (error) => {
|
||||||
this.logger.console(`§6客户端 §b${client.id} §c触发异常: ${error}`)
|
this.logger.console(`§6客户端 §b${client.id} §c触发异常: ${error}`)
|
||||||
this.logger.error(error)
|
this.logger.error(error)
|
||||||
@@ -232,7 +265,6 @@ export class MiaoConsole extends interfaces.Plugin {
|
|||||||
this.logger.console(`§6客户端 §b${client.id} §c断开连接...`)
|
this.logger.console(`§6客户端 §b${client.id} §c断开连接...`)
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
this.logger.info('Netty Channel Pipeline Inject MiaoDetectHandler Successful!')
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private runCode(code: string, namespace: any, client: any) {
|
private runCode(code: string, namespace: any, client: any) {
|
||||||
@@ -243,7 +275,7 @@ export class MiaoConsole extends interfaces.Plugin {
|
|||||||
tempconcent += text + "\\n"
|
tempconcent += text + "\\n"
|
||||||
}
|
}
|
||||||
var result = eval(${JSON.stringify(code)});
|
var result = eval(${JSON.stringify(code)});
|
||||||
return tempconcent + result
|
return tempconcent + '§a返回结果: §r'+ result
|
||||||
`)
|
`)
|
||||||
return this.task.callSyncMethod(() => tfunc.apply(this, [namespace, client])) + ''
|
return this.task.callSyncMethod(() => tfunc.apply(this, [namespace, client])) + ''
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "@ccms/sponge",
|
"name": "@ccms/sponge",
|
||||||
"version": "0.6.7",
|
"version": "0.7.0",
|
||||||
"description": "MiaoScript api package",
|
"description": "MiaoScript api package",
|
||||||
"keywords": [
|
"keywords": [
|
||||||
"miaoscript",
|
"miaoscript",
|
||||||
@@ -24,8 +24,8 @@
|
|||||||
"typescript": "^3.9.2"
|
"typescript": "^3.9.2"
|
||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@ccms/api": "^0.6.7",
|
"@ccms/api": "^0.7.0",
|
||||||
"@ccms/common": "^0.6.7",
|
"@ccms/common": "^0.7.0",
|
||||||
"@ccms/container": "^0.6.7"
|
"@ccms/container": "^0.7.0"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
1
packages/spring/.npmignore
Symbolic link
1
packages/spring/.npmignore
Symbolic link
@@ -0,0 +1 @@
|
|||||||
|
../../.npmignore
|
||||||
31
packages/spring/package.json
Normal file
31
packages/spring/package.json
Normal file
@@ -0,0 +1,31 @@
|
|||||||
|
{
|
||||||
|
"name": "@ccms/spring",
|
||||||
|
"version": "0.7.0",
|
||||||
|
"description": "MiaoScript spring package",
|
||||||
|
"keywords": [
|
||||||
|
"miaoscript",
|
||||||
|
"minecraft",
|
||||||
|
"bukkit",
|
||||||
|
"sponge"
|
||||||
|
],
|
||||||
|
"author": "MiaoWoo <admin@yumc.pw>",
|
||||||
|
"homepage": "https://github.com/circlecloud/ms.git",
|
||||||
|
"license": "ISC",
|
||||||
|
"main": "dist/index.js",
|
||||||
|
"scripts": {
|
||||||
|
"clean": "rimraf dist",
|
||||||
|
"watch": "tsc --watch",
|
||||||
|
"build": "yarn clean && tsc",
|
||||||
|
"test": "echo \"Error: run tests from root\" && exit 1"
|
||||||
|
},
|
||||||
|
"devDependencies": {
|
||||||
|
"reflect-metadata": "^0.1.13",
|
||||||
|
"rimraf": "^3.0.2",
|
||||||
|
"typescript": "^3.9.2"
|
||||||
|
},
|
||||||
|
"dependencies": {
|
||||||
|
"@ccms/api": "^0.7.0",
|
||||||
|
"@ccms/common": "^0.7.0",
|
||||||
|
"@ccms/container": "^0.7.0"
|
||||||
|
}
|
||||||
|
}
|
||||||
23
packages/spring/src/command.ts
Normal file
23
packages/spring/src/command.ts
Normal file
@@ -0,0 +1,23 @@
|
|||||||
|
import '@ccms/nashorn'
|
||||||
|
|
||||||
|
import { command, plugin } from '@ccms/api'
|
||||||
|
import { inject, provideSingleton, postConstruct } from '@ccms/container'
|
||||||
|
|
||||||
|
@provideSingleton(command.Command)
|
||||||
|
export class SpringCommand extends command.Command {
|
||||||
|
@inject(plugin.PluginInstance)
|
||||||
|
private pluginInstance: any
|
||||||
|
|
||||||
|
protected create(plugin: any, command: string) {
|
||||||
|
console.console('§4Spring暂不支持create命令!')
|
||||||
|
}
|
||||||
|
protected remove(plugin: any, command: string) {
|
||||||
|
console.console('§4Spring暂不支持remove命令!')
|
||||||
|
}
|
||||||
|
protected onCommand(plugin: any, command: any, executor: Function) {
|
||||||
|
console.console('§4Spring暂不支持onCommand!')
|
||||||
|
}
|
||||||
|
protected onTabComplete(plugin: any, command: any, tabCompleter: Function) {
|
||||||
|
console.console('§4Spring暂不支持onTabComplete!')
|
||||||
|
}
|
||||||
|
}
|
||||||
41
packages/spring/src/console.ts
Normal file
41
packages/spring/src/console.ts
Normal file
@@ -0,0 +1,41 @@
|
|||||||
|
import { MiaoScriptConsole } from '@ccms/api'
|
||||||
|
|
||||||
|
var colorMap = []
|
||||||
|
colorMap['0'] = '38;5;0'
|
||||||
|
colorMap['1'] = '38;5;4'
|
||||||
|
colorMap['2'] = '38;5;2'
|
||||||
|
colorMap['3'] = '38;5;6'
|
||||||
|
colorMap['4'] = '38;5;1'
|
||||||
|
colorMap['5'] = '38;5;5'
|
||||||
|
colorMap['6'] = '38;5;3'
|
||||||
|
colorMap['7'] = '38;5;7'
|
||||||
|
colorMap['8'] = '38;5;8'
|
||||||
|
colorMap['9'] = '38;5;12'
|
||||||
|
colorMap['a'] = '38;5;10'
|
||||||
|
colorMap['b'] = '38;5;14'
|
||||||
|
colorMap['c'] = '38;5;9'
|
||||||
|
colorMap['d'] = '38;5;13'
|
||||||
|
colorMap['e'] = '38;5;11'
|
||||||
|
colorMap['f'] = '38;5;15'
|
||||||
|
colorMap['r'] = '0'
|
||||||
|
colorMap['l'] = '1'
|
||||||
|
colorMap['n'] = '4'
|
||||||
|
var regexMap = []
|
||||||
|
for (const c in colorMap) {
|
||||||
|
regexMap[colorMap[c]] = new RegExp(`§${c}`, "g")
|
||||||
|
}
|
||||||
|
function mcColor2ANSI(str: string) {
|
||||||
|
for (const regex in regexMap) {
|
||||||
|
str = str.replace(regexMap[regex], `\u001b[${regex}m`)
|
||||||
|
}
|
||||||
|
return str;
|
||||||
|
}
|
||||||
|
|
||||||
|
export class SpringConsole extends MiaoScriptConsole {
|
||||||
|
sender(sender: any, ...args: any[]) {
|
||||||
|
this.console(args.join(' '))
|
||||||
|
}
|
||||||
|
console(...args: string[]): void {
|
||||||
|
this.logger.info(mcColor2ANSI(args.join(' ') + '§r'))
|
||||||
|
}
|
||||||
|
}
|
||||||
24
packages/spring/src/event.ts
Normal file
24
packages/spring/src/event.ts
Normal file
@@ -0,0 +1,24 @@
|
|||||||
|
import { event, plugin } from '@ccms/api'
|
||||||
|
import { inject, provideSingleton } from '@ccms/container'
|
||||||
|
|
||||||
|
@provideSingleton(event.Event)
|
||||||
|
export class SpringEvent extends event.Event {
|
||||||
|
@inject(plugin.PluginInstance)
|
||||||
|
private pluginInstance: any
|
||||||
|
|
||||||
|
constructor() {
|
||||||
|
super('');
|
||||||
|
}
|
||||||
|
mapEventName() {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
isValidEvent(clazz: any): boolean {
|
||||||
|
throw new Error("Method not implemented.");
|
||||||
|
}
|
||||||
|
register(eventCls: any, exec: Function, priority: any, ignoreCancel: boolean) {
|
||||||
|
throw new Error("Method not implemented.");
|
||||||
|
}
|
||||||
|
unregister(event: any, listener: any): void {
|
||||||
|
throw new Error("Method not implemented.");
|
||||||
|
}
|
||||||
|
}
|
||||||
14
packages/spring/src/index.ts
Normal file
14
packages/spring/src/index.ts
Normal file
@@ -0,0 +1,14 @@
|
|||||||
|
import { server, plugin } from '@ccms/api'
|
||||||
|
import { Container } from '@ccms/container'
|
||||||
|
|
||||||
|
import { SpringConsole } from './console';
|
||||||
|
import './event';
|
||||||
|
import './server';
|
||||||
|
import './command';
|
||||||
|
import './task';
|
||||||
|
|
||||||
|
const BeanKit = Java.type('com.sixi.micro.common.kits.BeanKit')
|
||||||
|
|
||||||
|
export default function SpringImpl(container: Container) {
|
||||||
|
container.bind(server.Console).toConstantValue(SpringConsole)
|
||||||
|
}
|
||||||
50
packages/spring/src/server.ts
Normal file
50
packages/spring/src/server.ts
Normal file
@@ -0,0 +1,50 @@
|
|||||||
|
import { server } from '@ccms/api'
|
||||||
|
import { provideSingleton } from '@ccms/container';
|
||||||
|
import { NativePluginManager } from '@ccms/api/dist/interfaces/server/native_plugin';
|
||||||
|
|
||||||
|
@provideSingleton(server.Server)
|
||||||
|
export class SpringServer implements server.Server {
|
||||||
|
constructor() {
|
||||||
|
}
|
||||||
|
getVersion(): string {
|
||||||
|
return "SpringFramework"
|
||||||
|
}
|
||||||
|
getPlayer(name: string) {
|
||||||
|
throw new Error("Method not implemented.");
|
||||||
|
}
|
||||||
|
getOnlinePlayers(): any[] {
|
||||||
|
throw new Error("Method not implemented.");
|
||||||
|
}
|
||||||
|
getConsoleSender() {
|
||||||
|
return undefined;
|
||||||
|
}
|
||||||
|
getService(service: string) {
|
||||||
|
throw new Error("Method not implemented.");
|
||||||
|
}
|
||||||
|
dispatchCommand(sender: any, command: string): boolean {
|
||||||
|
console.console('§4Spring暂不支持dispatchCommand!')
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
dispatchConsoleCommand(command: string): boolean {
|
||||||
|
console.console('§4Spring暂不支持dispatchConsoleCommand!')
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
getPluginsFolder(): string {
|
||||||
|
throw new Error("Method not implemented.");
|
||||||
|
}
|
||||||
|
getNativePluginManager(): NativePluginManager {
|
||||||
|
throw new Error("Method not implemented.");
|
||||||
|
}
|
||||||
|
getNettyPipeline() {
|
||||||
|
return base.getInstance().getAutowireCapableBeanFactory()
|
||||||
|
}
|
||||||
|
getRootLogger() {
|
||||||
|
return global.logger
|
||||||
|
}
|
||||||
|
sendJson(sender: any, json: string | object): void {
|
||||||
|
throw new Error("Method not implemented.");
|
||||||
|
}
|
||||||
|
tabComplete(sender: any, input: string, index?: number) {
|
||||||
|
throw new Error("Method not implemented.");
|
||||||
|
}
|
||||||
|
}
|
||||||
88
packages/spring/src/task.ts
Normal file
88
packages/spring/src/task.ts
Normal file
@@ -0,0 +1,88 @@
|
|||||||
|
import { task, plugin } from '@ccms/api'
|
||||||
|
import { inject, provideSingleton } from '@ccms/container'
|
||||||
|
|
||||||
|
const AtomicBoolean = Java.type("java.util.concurrent.atomic.AtomicBoolean")
|
||||||
|
const Thread = Java.type('java.lang.Thread')
|
||||||
|
const ThreadPoolExecutor = Java.type('java.util.concurrent.ThreadPoolExecutor')
|
||||||
|
const ThreadPoolTaskExecutor = Java.type('org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor')
|
||||||
|
|
||||||
|
let executor: any
|
||||||
|
let tasks: { [key: number]: task.Cancelable } = {}
|
||||||
|
let taskId = 0
|
||||||
|
|
||||||
|
@provideSingleton(task.TaskManager)
|
||||||
|
export class SpringTaskManager implements task.TaskManager {
|
||||||
|
@inject(plugin.PluginInstance)
|
||||||
|
private pluginInstance: any
|
||||||
|
|
||||||
|
constructor() {
|
||||||
|
executor = new ThreadPoolTaskExecutor()
|
||||||
|
executor.setCorePoolSize(10)
|
||||||
|
executor.setMaxPoolSize(100)
|
||||||
|
executor.setQueueCapacity(500)
|
||||||
|
executor.setKeepAliveSeconds(60)
|
||||||
|
executor.setThreadNamePrefix("@ccms/spring-")
|
||||||
|
executor.setRejectedExecutionHandler(new ThreadPoolExecutor.CallerRunsPolicy())
|
||||||
|
executor.initialize()
|
||||||
|
}
|
||||||
|
|
||||||
|
create(func: Function): task.Task {
|
||||||
|
if (Object.prototype.toString.call(func) !== "[object Function]") { throw TypeError('第一个参数 Task 必须为 function !') }
|
||||||
|
return new SpringTask(this.pluginInstance, func)
|
||||||
|
}
|
||||||
|
callSyncMethod(func: Function): any {
|
||||||
|
return func()
|
||||||
|
}
|
||||||
|
disable() {
|
||||||
|
Object.values(tasks).forEach((task) => task.cancel())
|
||||||
|
executor.shutdown();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export class SpringTask extends task.Task {
|
||||||
|
public id = taskId++
|
||||||
|
private running = new AtomicBoolean(true)
|
||||||
|
|
||||||
|
run() {
|
||||||
|
if (this.laterTime > 0) {
|
||||||
|
try {
|
||||||
|
Thread.sleep(this.laterTime)
|
||||||
|
} catch (ex) {
|
||||||
|
Thread.currentThread().interrupt()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
while (this.running.get()) {
|
||||||
|
try {
|
||||||
|
this.func()
|
||||||
|
} catch (t) {
|
||||||
|
console.error("Task exec error:", t)
|
||||||
|
console.ex(t)
|
||||||
|
}
|
||||||
|
// If we have a interval of 0 or less, only run once
|
||||||
|
if (this.interval <= 0) { break }
|
||||||
|
try {
|
||||||
|
Thread.sleep(this.interval)
|
||||||
|
} catch (ex) {
|
||||||
|
Thread.currentThread().interrupt()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
this.cancel()
|
||||||
|
}
|
||||||
|
|
||||||
|
cancel(): any {
|
||||||
|
var wasRunning = this.running.getAndSet(false)
|
||||||
|
if (wasRunning) {
|
||||||
|
tasks[this.id] = undefined
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
submit(): task.Cancelable {
|
||||||
|
tasks[this.id] = this
|
||||||
|
executor.execute(this.run.bind(this))
|
||||||
|
return {
|
||||||
|
cancel: () => {
|
||||||
|
return this.cancel()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
7
packages/spring/tsconfig.json
Normal file
7
packages/spring/tsconfig.json
Normal file
@@ -0,0 +1,7 @@
|
|||||||
|
{
|
||||||
|
"extends": "../../tsconfig.json",
|
||||||
|
"compilerOptions": {
|
||||||
|
"baseUrl": "src",
|
||||||
|
"outDir": "dist"
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1 +0,0 @@
|
|||||||
../../.npmignore
|
|
||||||
22
packages/types/.npmignore
Normal file
22
packages/types/.npmignore
Normal file
@@ -0,0 +1,22 @@
|
|||||||
|
test
|
||||||
|
bundled
|
||||||
|
build
|
||||||
|
coverage
|
||||||
|
docs
|
||||||
|
wiki
|
||||||
|
gulpfile.js
|
||||||
|
bower.json
|
||||||
|
karma.conf.js
|
||||||
|
tsconfig.json
|
||||||
|
typings.json
|
||||||
|
CONTRIBUTING.md
|
||||||
|
ISSUE_TEMPLATE.md
|
||||||
|
PULL_REQUEST_TEMPLATE.md
|
||||||
|
tslint.json
|
||||||
|
wallaby.js
|
||||||
|
.travis.yml
|
||||||
|
.gitignore
|
||||||
|
.vscode
|
||||||
|
.theia
|
||||||
|
type_definitions
|
||||||
|
tsconfig.tsbuildinfo
|
||||||
@@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "@ccms/types",
|
"name": "@ccms/types",
|
||||||
"version": "0.6.7",
|
"version": "0.7.0",
|
||||||
"description": "MiaoScript types package",
|
"description": "MiaoScript types package",
|
||||||
"keywords": [
|
"keywords": [
|
||||||
"miaoscript",
|
"miaoscript",
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "@ccms/websocket",
|
"name": "@ccms/websocket",
|
||||||
"version": "0.6.7",
|
"version": "0.7.0",
|
||||||
"description": "MiaoScript websocket package",
|
"description": "MiaoScript websocket package",
|
||||||
"keywords": [
|
"keywords": [
|
||||||
"miaoscript",
|
"miaoscript",
|
||||||
@@ -24,6 +24,6 @@
|
|||||||
"typescript": "^3.9.2"
|
"typescript": "^3.9.2"
|
||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@ccms/nashorn": "^0.6.7"
|
"@ccms/nashorn": "^0.7.0"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
import { EventEmitter } from 'events'
|
import { EventEmitter } from 'events'
|
||||||
import { SocketIO } from 'socket-io/interfaces';
|
import { SocketIO } from '../socket-io/interfaces';
|
||||||
import { AttributeKeys } from './constants';
|
import { AttributeKeys } from './constants';
|
||||||
|
|
||||||
const TextWebSocketFrame = Java.type('io.netty.handler.codec.http.websocketx.TextWebSocketFrame')
|
const TextWebSocketFrame = Java.type('io.netty.handler.codec.http.websocketx.TextWebSocketFrame')
|
||||||
|
|||||||
@@ -1,12 +1,3 @@
|
|||||||
export enum ServerEvent {
|
|
||||||
detect = 'detect',
|
|
||||||
connect = 'connect',
|
|
||||||
connection = 'connection',
|
|
||||||
message = 'message',
|
|
||||||
error = 'error',
|
|
||||||
disconnect = 'disconnect'
|
|
||||||
}
|
|
||||||
|
|
||||||
const AttributeKey = Java.type('io.netty.util.AttributeKey');
|
const AttributeKey = Java.type('io.netty.util.AttributeKey');
|
||||||
|
|
||||||
export enum Keys {
|
export enum Keys {
|
||||||
|
|||||||
@@ -1,8 +1,10 @@
|
|||||||
import { EventEmitter } from 'events'
|
import { EventEmitter } from 'events'
|
||||||
|
|
||||||
import { NettyClient } from './client'
|
|
||||||
import { ServerOptions } from '../socket-io'
|
import { ServerOptions } from '../socket-io'
|
||||||
import { ServerEvent, Keys } from './constants'
|
import { ServerEvent } from '../socket-io/constants'
|
||||||
|
|
||||||
|
import { NettyClient } from './client'
|
||||||
|
import { Keys } from './constants'
|
||||||
import { WebSocketDetect } from './websocket_detect'
|
import { WebSocketDetect } from './websocket_detect'
|
||||||
import { WebSocketHandler } from './websocket_handler'
|
import { WebSocketHandler } from './websocket_handler'
|
||||||
|
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
import { EventEmitter } from 'events'
|
import { EventEmitter } from 'events'
|
||||||
import { ServerEvent } from './constants'
|
|
||||||
import { ServerOptions } from '../socket-io';
|
import { ServerOptions } from '../socket-io';
|
||||||
|
import { ServerEvent } from '../socket-io/constants'
|
||||||
import { TextWebSocketFrameHandlerAdapter } from '../netty'
|
import { TextWebSocketFrameHandlerAdapter } from '../netty'
|
||||||
|
|
||||||
export class TextWebSocketFrameHandler extends TextWebSocketFrameHandlerAdapter {
|
export class TextWebSocketFrameHandler extends TextWebSocketFrameHandlerAdapter {
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
import { EventEmitter } from 'events'
|
import { EventEmitter } from 'events'
|
||||||
import { WebSocketHandlerAdapter } from "../netty"
|
import { WebSocketHandlerAdapter } from "../netty"
|
||||||
import { ServerEvent } from './constants'
|
import { ServerEvent } from '../socket-io/constants'
|
||||||
|
|
||||||
export class WebSocketDetect extends WebSocketHandlerAdapter {
|
export class WebSocketDetect extends WebSocketHandlerAdapter {
|
||||||
private event: EventEmitter;
|
private event: EventEmitter;
|
||||||
|
|||||||
@@ -1,5 +1,7 @@
|
|||||||
import { ServerOptions } from '../socket-io'
|
import { ServerOptions } from '../socket-io'
|
||||||
import { Keys, ServerEvent } from './constants'
|
import { ServerEvent } from '../socket-io/constants'
|
||||||
|
|
||||||
|
import { Keys } from './constants'
|
||||||
import { HttpRequestHandler } from './httprequest'
|
import { HttpRequestHandler } from './httprequest'
|
||||||
import { WebSocketHandlerAdapter } from "../netty"
|
import { WebSocketHandlerAdapter } from "../netty"
|
||||||
import { TextWebSocketFrameHandler } from './text_websocket_frame'
|
import { TextWebSocketFrameHandler } from './text_websocket_frame'
|
||||||
|
|||||||
@@ -1,30 +1,34 @@
|
|||||||
import { EventEmitter } from 'events'
|
import { EventEmitter } from 'events'
|
||||||
import { Parser } from './parser'
|
import { Parser } from './parser'
|
||||||
import { Packet } from './packet';
|
import { Packet } from './packet';
|
||||||
import { NettyClient } from '../server';
|
|
||||||
import { SocketIO } from './interfaces'
|
import { SocketIO } from './interfaces'
|
||||||
import { Server, Socket } from './index';
|
import { Server, Socket } from './index';
|
||||||
import { PacketTypes, SubPacketTypes } from './types';
|
import { PacketTypes, SubPacketTypes } from './types';
|
||||||
|
import { ServerEvent } from './constants';
|
||||||
|
|
||||||
const parser = new Parser();
|
const parser = new Parser();
|
||||||
|
|
||||||
export class Client extends EventEmitter implements SocketIO.Client {
|
export class Client extends EventEmitter implements SocketIO.Client {
|
||||||
id: string;
|
id: string;
|
||||||
server: Server;
|
server: Server;
|
||||||
conn: NettyClient;
|
conn: SocketIO.EngineSocket;
|
||||||
request: any;
|
request: any;
|
||||||
sockets: { [id: string]: Socket; };
|
sockets: { [id: string]: Socket; };
|
||||||
nsps: { [nsp: string]: SocketIO.Socket; };
|
nsps: { [nsp: string]: SocketIO.Socket; };
|
||||||
connectBuffer: any;
|
connectBuffer: any;
|
||||||
|
|
||||||
constructor(server: Server, nettyClient: NettyClient) {
|
constructor(server: Server, engine: SocketIO.EngineSocket) {
|
||||||
super();
|
super();
|
||||||
this.server = server;
|
this.server = server;
|
||||||
this.conn = nettyClient;
|
this.conn = engine;
|
||||||
this.id = this.conn.id + '';
|
this.id = this.conn.id + '';
|
||||||
this.request = nettyClient.request;
|
this.request = engine.request;
|
||||||
this.sockets = {};
|
this.sockets = {};
|
||||||
this.nsps = {};
|
this.nsps = {};
|
||||||
|
|
||||||
|
this.conn.on(ServerEvent.disconnect, (reason) => {
|
||||||
|
this.onclose(reason)
|
||||||
|
})
|
||||||
}
|
}
|
||||||
connect(name, query) {
|
connect(name, query) {
|
||||||
if (this.server.nsps[name]) {
|
if (this.server.nsps[name]) {
|
||||||
@@ -79,11 +83,11 @@ export class Client extends EventEmitter implements SocketIO.Client {
|
|||||||
// this.decoder.destroy(); // clean up decoder
|
// this.decoder.destroy(); // clean up decoder
|
||||||
}
|
}
|
||||||
disconnect() {
|
disconnect() {
|
||||||
// if ('open' == this.conn.readyState) {
|
if ('open' == this.conn.readyState) {
|
||||||
// debug('forcing transport close');
|
// debug('forcing transport close');
|
||||||
this.conn.close();
|
this.conn.close();
|
||||||
this.onclose('forced server close');
|
this.onclose('forced server close');
|
||||||
// }
|
}
|
||||||
}
|
}
|
||||||
remove(socket: Socket) {
|
remove(socket: Socket) {
|
||||||
if (this.sockets.hasOwnProperty(socket.id)) {
|
if (this.sockets.hasOwnProperty(socket.id)) {
|
||||||
|
|||||||
8
packages/websocket/src/socket-io/constants.ts
Normal file
8
packages/websocket/src/socket-io/constants.ts
Normal file
@@ -0,0 +1,8 @@
|
|||||||
|
export enum ServerEvent {
|
||||||
|
detect = 'detect',
|
||||||
|
connect = 'connect',
|
||||||
|
connection = 'connection',
|
||||||
|
message = 'message',
|
||||||
|
error = 'error',
|
||||||
|
disconnect = 'disconnect'
|
||||||
|
}
|
||||||
@@ -1,8 +1,6 @@
|
|||||||
import { EventEmitter } from 'events'
|
import { EventEmitter } from 'events'
|
||||||
|
|
||||||
import { NettyWebSocketServer, NettyClient } from '../server'
|
import { ServerEvent } from './constants';
|
||||||
import { ServerEvent } from '../server/constants';
|
|
||||||
|
|
||||||
import { Namespace } from './namespace';
|
import { Namespace } from './namespace';
|
||||||
import { Client } from './client';
|
import { Client } from './client';
|
||||||
import { SocketIO } from './interfaces'
|
import { SocketIO } from './interfaces'
|
||||||
@@ -17,8 +15,12 @@ interface ServerOptions extends SocketIO.ServerOptions {
|
|||||||
root?: string;
|
root?: string;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
interface WebSocketServer extends EventEmitter {
|
||||||
|
close(): void
|
||||||
|
}
|
||||||
|
|
||||||
class Server implements SocketIO.Server {
|
class Server implements SocketIO.Server {
|
||||||
private nettyServer: NettyWebSocketServer;
|
private websocketServer: WebSocketServer;
|
||||||
private allClients: { [key: string]: Client };
|
private allClients: { [key: string]: Client };
|
||||||
|
|
||||||
engine: { ws: any; };
|
engine: { ws: any; };
|
||||||
@@ -31,17 +33,24 @@ class Server implements SocketIO.Server {
|
|||||||
_adapter: Adapter;
|
_adapter: Adapter;
|
||||||
options: ServerOptions;
|
options: ServerOptions;
|
||||||
|
|
||||||
constructor(pipeline: any, options: ServerOptions) {
|
constructor(instance: any, options: ServerOptions) {
|
||||||
if (!pipeline) { throw new Error('Netty Pipeline can\'t be undefiend!') }
|
if (!instance) { throw new Error('instance can\'t be undefiend!') }
|
||||||
this.allClients = {};
|
this.allClients = {};
|
||||||
this.nsps = {};
|
this.nsps = {};
|
||||||
this.sockets = new Namespace('/', this);
|
this.sockets = new Namespace('/', this);
|
||||||
this.nsps['/'] = this.sockets;
|
this.nsps['/'] = this.sockets;
|
||||||
this.initNettyServer(pipeline, Object.assign({
|
if (instance.class.name.startsWith('io.netty.channel')) {
|
||||||
event: new EventEmitter(),
|
let { NettyWebSocketServer } = require("../server")
|
||||||
path: '/socket.io',
|
this.websocketServer = new NettyWebSocketServer(instance, Object.assign({
|
||||||
root: root + '/wwwroot'
|
event: new EventEmitter(),
|
||||||
}, options));
|
path: '/socket.io',
|
||||||
|
root: root + '/wwwroot'
|
||||||
|
}, options));
|
||||||
|
} else {
|
||||||
|
let { TomcatWebSocketServer } = require("../tomcat/server")
|
||||||
|
this.websocketServer = new TomcatWebSocketServer(instance, options);
|
||||||
|
}
|
||||||
|
this.initServer()
|
||||||
}
|
}
|
||||||
|
|
||||||
checkRequest(req: any, fn: (err: any, success: boolean) => void): void {
|
checkRequest(req: any, fn: (err: any, success: boolean) => void): void {
|
||||||
@@ -114,7 +123,7 @@ class Server implements SocketIO.Server {
|
|||||||
for (let socket in this.sockets.sockets) {
|
for (let socket in this.sockets.sockets) {
|
||||||
this.sockets.sockets[socket].onclose()
|
this.sockets.sockets[socket].onclose()
|
||||||
}
|
}
|
||||||
this.nettyServer.close();
|
this.websocketServer.close();
|
||||||
}
|
}
|
||||||
on(event: "connection", listener: (socket: SocketIO.Socket) => void): SocketIO.Namespace;
|
on(event: "connection", listener: (socket: SocketIO.Socket) => void): SocketIO.Namespace;
|
||||||
on(event: "connect", listener: (socket: SocketIO.Socket) => void): SocketIO.Namespace;
|
on(event: "connect", listener: (socket: SocketIO.Socket) => void): SocketIO.Namespace;
|
||||||
@@ -152,17 +161,16 @@ class Server implements SocketIO.Server {
|
|||||||
fn(false);
|
fn(false);
|
||||||
};
|
};
|
||||||
|
|
||||||
private initNettyServer(pipeline, options) {
|
private initServer() {
|
||||||
this.nettyServer = new NettyWebSocketServer(pipeline, options);
|
this.websocketServer.on(ServerEvent.connect, (socket: SocketIO.EngineSocket) => {
|
||||||
this.nettyServer.on(ServerEvent.connect, (nettyClient: NettyClient) => {
|
let client = new Client(this, socket);
|
||||||
let client = new Client(this, nettyClient);
|
|
||||||
this.onconnection(client);
|
this.onconnection(client);
|
||||||
})
|
})
|
||||||
this.nettyServer.on(ServerEvent.message, (nettyClient: NettyClient, text) => {
|
this.websocketServer.on(ServerEvent.message, (socket: SocketIO.EngineSocket, text) => {
|
||||||
this.processPacket(this.parser.decode(text), this.allClients[nettyClient.id]);
|
this.processPacket(this.parser.decode(text), this.allClients[socket.id]);
|
||||||
})
|
})
|
||||||
this.nettyServer.on(ServerEvent.error, (nettyClient: NettyClient, cause) => {
|
this.websocketServer.on(ServerEvent.error, (socket: SocketIO.EngineSocket, cause) => {
|
||||||
console.error(`Client ${nettyClient.id} cause error: ` + cause)
|
console.error(`Client ${socket.id} cause error: ` + cause)
|
||||||
console.ex(cause)
|
console.ex(cause)
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -830,5 +830,15 @@ export declare namespace SocketIO {
|
|||||||
* (Transport): transport reference
|
* (Transport): transport reference
|
||||||
*/
|
*/
|
||||||
transport: any;
|
transport: any;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* send
|
||||||
|
*/
|
||||||
|
send(text: string);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* close
|
||||||
|
*/
|
||||||
|
close();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -2,7 +2,7 @@ import { EventEmitter } from 'events'
|
|||||||
|
|
||||||
import { Client } from './client'
|
import { Client } from './client'
|
||||||
import { SocketIO } from './interfaces';
|
import { SocketIO } from './interfaces';
|
||||||
import { ServerEvent } from '../server';
|
import { ServerEvent } from './constants';
|
||||||
import { Socket } from './socket';
|
import { Socket } from './socket';
|
||||||
import { Adapter } from './adapter';
|
import { Adapter } from './adapter';
|
||||||
import { Server } from './index'
|
import { Server } from './index'
|
||||||
|
|||||||
44
packages/websocket/src/tomcat/client.ts
Normal file
44
packages/websocket/src/tomcat/client.ts
Normal file
@@ -0,0 +1,44 @@
|
|||||||
|
import { EventEmitter } from 'events'
|
||||||
|
import { SocketIO } from '../socket-io/interfaces';
|
||||||
|
|
||||||
|
export class TomcatClient extends EventEmitter implements SocketIO.EngineSocket {
|
||||||
|
private _id: string;
|
||||||
|
private session: any
|
||||||
|
|
||||||
|
server: any;
|
||||||
|
readyState: string;
|
||||||
|
remoteAddress: string;
|
||||||
|
upgraded: boolean;
|
||||||
|
request: any;
|
||||||
|
transport: any;
|
||||||
|
|
||||||
|
constructor(server: any, session: any) {
|
||||||
|
super();
|
||||||
|
this.server = server;
|
||||||
|
this.readyState = 'open';
|
||||||
|
this.remoteAddress = session + ''
|
||||||
|
this.upgraded = true;
|
||||||
|
this.request = {
|
||||||
|
uri: () => {
|
||||||
|
return session.getRequestURI() + ''
|
||||||
|
},
|
||||||
|
headers: () => {
|
||||||
|
return []
|
||||||
|
}
|
||||||
|
};
|
||||||
|
this.transport = null;
|
||||||
|
|
||||||
|
this.session = session;
|
||||||
|
this._id = session.getId();
|
||||||
|
}
|
||||||
|
|
||||||
|
get id() {
|
||||||
|
return this._id;
|
||||||
|
}
|
||||||
|
send(text: string) {
|
||||||
|
this.session.getBasicRemote().sendText(text)
|
||||||
|
}
|
||||||
|
close() {
|
||||||
|
this.session.close();
|
||||||
|
}
|
||||||
|
}
|
||||||
1
packages/websocket/src/tomcat/constants.ts
Normal file
1
packages/websocket/src/tomcat/constants.ts
Normal file
@@ -0,0 +1 @@
|
|||||||
|
export const ProxyBeanName = "webSocketServerProxy"
|
||||||
69
packages/websocket/src/tomcat/server.ts
Normal file
69
packages/websocket/src/tomcat/server.ts
Normal file
@@ -0,0 +1,69 @@
|
|||||||
|
import { EventEmitter } from 'events'
|
||||||
|
|
||||||
|
import { ServerOptions } from '../socket-io'
|
||||||
|
import { ServerEvent } from '../socket-io/constants'
|
||||||
|
import { SocketIO } from '../socket-io/interfaces'
|
||||||
|
import { ProxyBeanName } from './constants'
|
||||||
|
import { TomcatClient } from './client'
|
||||||
|
|
||||||
|
const WebSocketServerProxy = Java.type("com.sixi.framework.scriptservice.websocket.WebSocketServerProxy")
|
||||||
|
const ThreadPoolExecutor = Java.type('java.util.concurrent.ThreadPoolExecutor')
|
||||||
|
const ThreadPoolTaskExecutor = Java.type('org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor')
|
||||||
|
|
||||||
|
interface TomcatWebSocketSession {
|
||||||
|
getId: () => number
|
||||||
|
}
|
||||||
|
|
||||||
|
class TomcatWebSocketServer extends EventEmitter {
|
||||||
|
private beanFactory: any
|
||||||
|
private executor: any
|
||||||
|
private allClients: { [key: string]: SocketIO.EngineSocket }
|
||||||
|
|
||||||
|
constructor(beanFactory: any, options: ServerOptions) {
|
||||||
|
super()
|
||||||
|
this.allClients = {}
|
||||||
|
this.beanFactory = beanFactory
|
||||||
|
this.initThreadPool()
|
||||||
|
try { this.beanFactory.destroySingleton(ProxyBeanName) } catch (error) { }
|
||||||
|
let NashornWebSocketServerProxy = Java.extend(WebSocketServerProxy, {
|
||||||
|
onOpen: (session: TomcatWebSocketSession) => {
|
||||||
|
let tomcatClient = new TomcatClient(this, session)
|
||||||
|
this.allClients[tomcatClient.id] = tomcatClient
|
||||||
|
this.emit(ServerEvent.connect, tomcatClient)
|
||||||
|
},
|
||||||
|
onMessage: (message: any, session: TomcatWebSocketSession) => {
|
||||||
|
this.executor.execute(() => {
|
||||||
|
this.emit(ServerEvent.message, this.allClients[session.getId()], message)
|
||||||
|
})
|
||||||
|
},
|
||||||
|
onClose: (session: TomcatWebSocketSession, reason: any) => {
|
||||||
|
this.emit(ServerEvent.disconnect, this.allClients[session.getId()], reason)
|
||||||
|
},
|
||||||
|
onError: (session: TomcatWebSocketSession, error: any) => {
|
||||||
|
this.emit(ServerEvent.error, this.allClients[session.getId()], error)
|
||||||
|
},
|
||||||
|
})
|
||||||
|
this.beanFactory.registerSingleton(ProxyBeanName, new NashornWebSocketServerProxy())
|
||||||
|
}
|
||||||
|
private initThreadPool() {
|
||||||
|
this.executor = new ThreadPoolTaskExecutor()
|
||||||
|
this.executor.setCorePoolSize(10)
|
||||||
|
this.executor.setMaxPoolSize(100)
|
||||||
|
this.executor.setQueueCapacity(500)
|
||||||
|
this.executor.setKeepAliveSeconds(60)
|
||||||
|
this.executor.setThreadNamePrefix("@ccms/websocket-")
|
||||||
|
this.executor.setRejectedExecutionHandler(new ThreadPoolExecutor.CallerRunsPolicy())
|
||||||
|
this.executor.initialize()
|
||||||
|
}
|
||||||
|
close() {
|
||||||
|
Object.values(this.allClients).forEach(client => client.close())
|
||||||
|
this.beanFactory.destroySingleton(ProxyBeanName)
|
||||||
|
this.executor.shutdown()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export {
|
||||||
|
TomcatWebSocketServer,
|
||||||
|
ServerEvent,
|
||||||
|
TomcatClient
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user