mirror of
https://github.com/unanmed/HumanBreak.git
synced 2025-01-19 12:49:25 +08:00
feat: 复写api
This commit is contained in:
parent
5119227a41
commit
483df57fdf
@ -95,7 +95,14 @@ interface SystemInterfaceMap {
|
|||||||
|
|
||||||
type InterfaceType = keyof SystemInterfaceMap;
|
type InterfaceType = keyof SystemInterfaceMap;
|
||||||
|
|
||||||
|
interface PluginInterface {}
|
||||||
|
|
||||||
export interface IMota {
|
export interface IMota {
|
||||||
|
rewrite: typeof rewrite;
|
||||||
|
rewriteSys: typeof rewriteSys;
|
||||||
|
|
||||||
|
Plugin: IPlugin;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 获取一个样板接口
|
* 获取一个样板接口
|
||||||
* @param type 要获取的接口类型
|
* @param type 要获取的接口类型
|
||||||
@ -138,6 +145,131 @@ export interface IMota {
|
|||||||
register(type: InterfaceType, key: string, data: any): void;
|
register(type: InterfaceType, key: string, data: any): void;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export interface IPlugin {
|
||||||
|
/**
|
||||||
|
* 初始化所有插件
|
||||||
|
*/
|
||||||
|
init(): void;
|
||||||
|
/**
|
||||||
|
* 初始化指定插件
|
||||||
|
* @param plugin 要初始化的插件
|
||||||
|
*/
|
||||||
|
init(plugin: string): void;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取到一个插件的内容
|
||||||
|
* @param plugin 要获取的插件
|
||||||
|
*/
|
||||||
|
require<K extends keyof PluginInterface>(plugin: K): PluginInterface[K];
|
||||||
|
/**
|
||||||
|
* 获取到一个插件的内容
|
||||||
|
* @param plugin 要获取的插件
|
||||||
|
*/
|
||||||
|
require(plugin: string): any;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取所有插件
|
||||||
|
*/
|
||||||
|
requireAll(): PluginInterface;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 注册一个插件
|
||||||
|
* @param plugin 要注册的插件名
|
||||||
|
* @param data 插件内容
|
||||||
|
* @param init 插件的初始化函数,可选,初始化函数接受两个参数,分别是plugin和data,表示插件名称和内容
|
||||||
|
*/
|
||||||
|
register<K extends keyof PluginInterface>(
|
||||||
|
plugin: K,
|
||||||
|
data: PluginInterface[K],
|
||||||
|
init?: (plugin: K, data: PluginInterface[K]) => void
|
||||||
|
): void;
|
||||||
|
/**
|
||||||
|
* 注册一个插件
|
||||||
|
* @param plugin 要注册的插件名
|
||||||
|
* @param init 插件的初始化函数,初始化函数接受一个参数,表示插件名称,要求返回插件内容
|
||||||
|
*/
|
||||||
|
register<K extends keyof PluginInterface>(
|
||||||
|
plugin: K,
|
||||||
|
init: (plugin: K) => PluginInterface[K]
|
||||||
|
): void;
|
||||||
|
/**
|
||||||
|
* 注册一个插件
|
||||||
|
* @param plugin 要注册的插件名
|
||||||
|
* @param data 插件内容
|
||||||
|
* @param init 插件的初始化函数,可选,初始化函数接受两个参数,分别是plugin和data,表示插件名称和内容
|
||||||
|
*/
|
||||||
|
register<K extends string, D>(
|
||||||
|
plugin: K,
|
||||||
|
data: D,
|
||||||
|
init?: (plugin: K, data: D) => void
|
||||||
|
): void;
|
||||||
|
/**
|
||||||
|
* 注册一个插件
|
||||||
|
* @param plugin 要注册的插件名
|
||||||
|
* @param init 插件的初始化函数,初始化函数接受一个参数,表示插件名称,要求返回插件内容
|
||||||
|
*/
|
||||||
|
register<K extends string>(plugin: K, init: (plugin: K) => any): void;
|
||||||
|
}
|
||||||
|
|
||||||
|
interface IPluginData {
|
||||||
|
/** 插件类型,content表示直接注册了内容,function表示注册了初始化函数,内容从其返回值获取 */
|
||||||
|
type: 'content' | 'function';
|
||||||
|
data: any;
|
||||||
|
init?: (plugin: string, data?: any) => any;
|
||||||
|
}
|
||||||
|
|
||||||
|
class MPlugin {
|
||||||
|
private static plugins: Record<string, IPluginData> = {};
|
||||||
|
private static inited = false;
|
||||||
|
private static pluginData: Record<string, any> = {};
|
||||||
|
|
||||||
|
constructor() {
|
||||||
|
throw new Error(`System plugin class cannot be constructed.`);
|
||||||
|
}
|
||||||
|
|
||||||
|
static init() {
|
||||||
|
for (const [key, data] of Object.entries(this.plugins)) {
|
||||||
|
if (data.type === 'content') {
|
||||||
|
data.init?.(key, data.data);
|
||||||
|
} else {
|
||||||
|
data.data = data.init!(key);
|
||||||
|
}
|
||||||
|
this.pluginData[key] = data.data;
|
||||||
|
}
|
||||||
|
this.inited = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
static require(key: string) {
|
||||||
|
if (!this.inited) {
|
||||||
|
throw new Error(`Cannot access plugin '${key}' before initialize.`);
|
||||||
|
}
|
||||||
|
if (!(key in this.plugins)) {
|
||||||
|
throw new Error(`Cannot resolve plugin require: key='${key}'`);
|
||||||
|
}
|
||||||
|
return this.plugins[key].data;
|
||||||
|
}
|
||||||
|
|
||||||
|
static requireAll() {
|
||||||
|
return this.pluginData;
|
||||||
|
}
|
||||||
|
|
||||||
|
static register(key: string, data: any, init?: any) {
|
||||||
|
if (typeof data === 'function') {
|
||||||
|
this.plugins[key] = {
|
||||||
|
type: 'function',
|
||||||
|
init: data,
|
||||||
|
data: void 0
|
||||||
|
};
|
||||||
|
} else {
|
||||||
|
this.plugins[key] = {
|
||||||
|
type: 'content',
|
||||||
|
data,
|
||||||
|
init
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 样板接口系统,通过 Mota 获取到样板的核心功能,不可实例化
|
* 样板接口系统,通过 Mota 获取到样板的核心功能,不可实例化
|
||||||
*/
|
*/
|
||||||
@ -146,25 +278,14 @@ class Mota {
|
|||||||
private static functions: Record<string, any> = {};
|
private static functions: Record<string, any> = {};
|
||||||
private static variables: Record<string, any> = {};
|
private static variables: Record<string, any> = {};
|
||||||
|
|
||||||
|
static rewrite = rewrite;
|
||||||
|
static rewriteSys = rewriteSys;
|
||||||
|
static Plugin = MPlugin;
|
||||||
|
|
||||||
constructor() {
|
constructor() {
|
||||||
throw new Error(`System interface class cannot be constructed.`);
|
throw new Error(`System interface class cannot be constructed.`);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* 获取一个样板接口
|
|
||||||
* @param type 要获取的接口类型
|
|
||||||
* @param key 接口名称
|
|
||||||
*/
|
|
||||||
static require<
|
|
||||||
T extends InterfaceType,
|
|
||||||
K extends keyof SystemInterfaceMap[T]
|
|
||||||
>(type: T, key: K): SystemInterfaceMap[T][K];
|
|
||||||
/**
|
|
||||||
* 获取一个样板接口
|
|
||||||
* @param type 要获取的接口类型
|
|
||||||
* @param key 接口名称
|
|
||||||
*/
|
|
||||||
static require(type: InterfaceType, key: string): any;
|
|
||||||
static require(type: InterfaceType, key: string): any {
|
static require(type: InterfaceType, key: string): any {
|
||||||
const data = this.getByType(type)[key];
|
const data = this.getByType(type)[key];
|
||||||
if (!!data) return data;
|
if (!!data) return data;
|
||||||
@ -175,31 +296,10 @@ class Mota {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* 获取一种接口的所有内容
|
|
||||||
* @param type 要获取的接口类型
|
|
||||||
*/
|
|
||||||
static requireAll<T extends InterfaceType>(type: T): SystemInterfaceMap[T] {
|
static requireAll<T extends InterfaceType>(type: T): SystemInterfaceMap[T] {
|
||||||
return this.getByType(type) as SystemInterfaceMap[T];
|
return this.getByType(type) as SystemInterfaceMap[T];
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* 注册一个样板接口
|
|
||||||
* @param type 要注册的接口类型
|
|
||||||
* @param key 接口名称
|
|
||||||
* @param data 接口内容
|
|
||||||
*/
|
|
||||||
static register<
|
|
||||||
T extends InterfaceType,
|
|
||||||
K extends keyof SystemInterfaceMap[T]
|
|
||||||
>(type: T, key: K, data: SystemInterfaceMap[T][K]): void;
|
|
||||||
/**
|
|
||||||
* 注册一个样板接口
|
|
||||||
* @param type 要注册的接口类型
|
|
||||||
* @param key 接口名称
|
|
||||||
* @param data 接口内容
|
|
||||||
*/
|
|
||||||
static register(type: InterfaceType, key: string, data: any): void;
|
|
||||||
static register(type: InterfaceType, key: string, data: any) {
|
static register(type: InterfaceType, key: string, data: any) {
|
||||||
const obj = this.getByType(type);
|
const obj = this.getByType(type);
|
||||||
if (key in obj) {
|
if (key in obj) {
|
||||||
@ -219,6 +319,135 @@ class Mota {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type RewriteType = 'full' | 'front' | 'add';
|
||||||
|
type _F<F> = F extends (...params: infer P) => infer R ? [P, R] : never;
|
||||||
|
type _Func = (...params: any) => any;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 全量复写或在函数前添加内容
|
||||||
|
* @param base 函数所在对象
|
||||||
|
* @param key 函数名称,即函数在base中叫什么
|
||||||
|
* @param type 复写类型,full表示全量复写,front表示在原函数之前添加内容
|
||||||
|
* @param re 复写函数,类型为full时表示将原函数完全覆盖,为front时表示将该函数添加到原函数之前
|
||||||
|
* @param bind 原函数的调用对象,默认为base
|
||||||
|
* @param rebind 复写函数的调用对象,默认为base
|
||||||
|
*/
|
||||||
|
function rewrite<O, K extends SelectKey<O, _Func>, T = O>(
|
||||||
|
base: O,
|
||||||
|
key: K,
|
||||||
|
type: 'full' | 'front',
|
||||||
|
re: (this: T, ...params: [..._F<O[K]>[0], ...any[]]) => _F<O[K]>[1],
|
||||||
|
bind?: any,
|
||||||
|
rebind?: T
|
||||||
|
): (this: T, ...params: [..._F<O[K]>[0], ...any[]]) => _F<O[K]>[1];
|
||||||
|
/**
|
||||||
|
* 在函数后追加内容
|
||||||
|
* @param base 函数所在对象
|
||||||
|
* @param key 函数名称,即函数在base中叫什么
|
||||||
|
* @param type 复写类型,add表示在函数后追加
|
||||||
|
* @param re 复写函数,类型为add时表示在原函数后面追加复写函数,会在第一个参数中传入原函数的返回值,
|
||||||
|
* 并要求复写函数必须有返回值,作为复写的最终返回值。
|
||||||
|
* @param bind 原函数的调用对象,默认为base
|
||||||
|
* @param rebind 复写函数的调用对象,默认为base
|
||||||
|
*/
|
||||||
|
function rewrite<O, K extends SelectKey<O, _Func>, T = O>(
|
||||||
|
base: O,
|
||||||
|
key: K,
|
||||||
|
type: 'add',
|
||||||
|
re: (
|
||||||
|
this: T,
|
||||||
|
...params: [_F<O[K]>[1], ..._F<O[K]>[0], ...any[]]
|
||||||
|
) => _F<O[K]>[1],
|
||||||
|
bind?: any,
|
||||||
|
rebind?: T
|
||||||
|
): (this: T, ...params: [..._F<O[K]>[0], ...any[]]) => _F<O[K]>[1];
|
||||||
|
function rewrite<O, K extends SelectKey<O, _Func>, T = O>(
|
||||||
|
base: O,
|
||||||
|
key: K,
|
||||||
|
type: RewriteType,
|
||||||
|
re: (this: T, ...params: [..._F<O[K]>[0], ...any[]]) => _F<O[K]>[1],
|
||||||
|
bind?: any,
|
||||||
|
rebind?: T
|
||||||
|
): (this: T, ...params: [..._F<O[K]>[0], ...any[]]) => _F<O[K]>[1] {
|
||||||
|
const func = base[key];
|
||||||
|
if (typeof func !== 'function') {
|
||||||
|
throw new Error(
|
||||||
|
`Cannot rewrite variable with type of '${typeof func}'.`
|
||||||
|
);
|
||||||
|
}
|
||||||
|
if (type === 'full') {
|
||||||
|
// @ts-ignore
|
||||||
|
return (base[key] = re.bind(rebind ?? base));
|
||||||
|
} else if (type === 'add') {
|
||||||
|
const origin = base[key];
|
||||||
|
function res(this: T, ...params: [..._F<O[K]>[0], ...any[]]) {
|
||||||
|
const v = (origin as _Func).call(bind ?? base, ...params);
|
||||||
|
// @ts-ignore
|
||||||
|
const ret = re.call(rebind ?? base, v, ...params);
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
// @ts-ignore
|
||||||
|
return (base[key] = res);
|
||||||
|
} else {
|
||||||
|
const origin = base[key];
|
||||||
|
function res(this: T, ...params: [..._F<O[K]>[0], ...any[]]) {
|
||||||
|
// @ts-ignore
|
||||||
|
re.call(rebind ?? base, v, ...params);
|
||||||
|
const ret = (origin as _Func).call(bind ?? base, ...params);
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
// @ts-ignore
|
||||||
|
return (base[key] = res);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
type _FI<K extends keyof FunctionInterface> = FunctionInterface[K];
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 全量复写系统函数或在系统函数函数前添加内容
|
||||||
|
* @param key 系统函数名称
|
||||||
|
* @param type 复写类型,full表示全量复写,front表示在原函数之前添加内容
|
||||||
|
* @param re 复写函数,类型为full时表示将原函数完全覆盖,为front时表示将该函数添加到原函数之前
|
||||||
|
* @param bind 原函数的调用对象,默认为base
|
||||||
|
* @param rebind 复写函数的调用对象,默认为base
|
||||||
|
*/
|
||||||
|
function rewriteSys<K extends keyof FunctionInterface, T>(
|
||||||
|
key: K,
|
||||||
|
type: 'full' | 'front',
|
||||||
|
re: (this: T, ...params: [..._F<_FI<K>>[0], ...any[]]) => _F<_FI<K>>[1],
|
||||||
|
bind?: any,
|
||||||
|
rebind?: T
|
||||||
|
): (this: T, ...params: [..._F<_FI<K>>[0], ...any[]]) => _F<_FI<K>>[1];
|
||||||
|
/**
|
||||||
|
* 在系统函数后追加内容
|
||||||
|
* @param key 系统函数名称
|
||||||
|
* @param type 复写类型,add表示在函数后追加
|
||||||
|
* @param re 复写函数,类型为add时表示在原函数后面追加复写函数,会在第一个参数中传入原函数的返回值,
|
||||||
|
* 并要求复写函数必须有返回值,作为复写的最终返回值。
|
||||||
|
* @param bind 原函数的调用对象,默认为base
|
||||||
|
* @param rebind 复写函数的调用对象,默认为base
|
||||||
|
*/
|
||||||
|
function rewriteSys<K extends keyof FunctionInterface, T>(
|
||||||
|
key: K,
|
||||||
|
type: 'add',
|
||||||
|
re: (
|
||||||
|
this: T,
|
||||||
|
...params: [_F<_FI<K>>[1], ..._F<_FI<K>>[0], ...any[]]
|
||||||
|
) => _F<_FI<K>>[1],
|
||||||
|
bind?: any,
|
||||||
|
rebind?: T
|
||||||
|
): (this: T, ...params: [..._F<_FI<K>>[0], ...any[]]) => _F<_FI<K>>[1];
|
||||||
|
function rewriteSys<K extends keyof FunctionInterface, T>(
|
||||||
|
key: K,
|
||||||
|
type: RewriteType,
|
||||||
|
re: (this: T, ...params: [..._F<_FI<K>>[0], ...any[]]) => _F<_FI<K>>[1],
|
||||||
|
bind?: any,
|
||||||
|
rebind?: T
|
||||||
|
): (this: T, ...params: [..._F<_FI<K>>[0], ...any[]]) => _F<_FI<K>>[1] {
|
||||||
|
// @ts-ignore
|
||||||
|
return rewrite(Mota.requireAll('fn'), key, type, re, bind, rebind);
|
||||||
|
}
|
||||||
|
|
||||||
declare global {
|
declare global {
|
||||||
interface Window {
|
interface Window {
|
||||||
Mota: IMota;
|
Mota: IMota;
|
||||||
|
Loading…
Reference in New Issue
Block a user