/// /// declare type KNumberType = | 's8' | 'u8' | 's16' | 'u16' | 's32' | 'u32' | 'time' | 'ip4' | 'float' | 'double' | 'bool'; declare type KBigIntType = 's64' | 'u64'; declare type KNumberGroupType = | '2s8' | '2u8' | '2s16' | '2u16' | '2s32' | '2u32' | '2f' | '2d' | '3s8' | '3u8' | '3s16' | '3u16' | '3s32' | '3u32' | '3f' | '3d' | '4s8' | '4u8' | '4s16' | '4u16' | '4s32' | '4u32' | '4f' | '4d' | '2b' | '3b' | '4b' | 'vb'; declare type KBigIntGroupType = | '2s64' | '2u64' | '3s64' | '3u64' | '4s64' | '4u64' | 'vs8' | 'vu8' | 'vs16' | 'vu16'; /** * Attribute object */ declare type KAttrMap = { [key: string]: string }; /** * Supported response encoding */ declare type KEncoding = | 'shift_jis' | 'utf8' | 'euc-jp' | 'ascii' | 'iso-8859-1'; /** * Information about requester */ declare interface EamuseInfo { module: string; method: string; model: string; } /** * Detail of a config */ declare interface ConfigOption { /** Provide a name to display in webui. If not provided, webui will use key as the name. */ name?: string; /** Provide a description for the option */ desc?: string; /** Type of the option */ type: 'string' | 'integer' | 'float' | 'boolean'; /** Only applies to 'integer' and 'float' */ range?: [number, number]; /** Validator for notify user about invalid values. return `true` to pass the validation. return a string to send a error message to WebUI. */ validator?: (data: string) => true | string; /** Only applies to 'string', provide options in a dropdown menu. */ options?: string[]; /** Indicate whether user need to restart CORE to see changes. */ needRestart?: boolean; /** Default value of the option */ default: any; } /** * Response options */ declare interface EamuseSendOption { status?: number; /** * Encode response with specified encoding * Default: 'SHIFT_JIS' */ encoding?: KEncoding; /** * Replace response root tag name. * Default to child tag name of request tag, * which is usually the case and don't need to be replaced. */ rootName?: string; compress?: boolean; kencode?: boolean; encrypt?: boolean; } declare interface EamuseSend { /** * Send empty response with status code 0 */ success: (options?: EamuseSendOption) => Promise; /** * Send empty response with status code 1 */ deny: (options?: EamuseSendOption) => Promise; /** * Send empty response with custom status code */ status: (code: number, options?: EamuseSendOption) => Promise; /** * Send plain javascript object. * When constructing objects, make sure to use helper [[K]]: * ``` * { * outter: K.ATTR({ status: "1" }, { * inner: K.ITEM("s32", 1) * }) * } * ``` * * Or follow xml-like format manually: * ``` * { * outter: { * "@attr": { status: "1" }, * inner: { * "@attr": { __type: "s32" }, * "@content": [1] * } * } * } * ``` * @param res xml-like formatted javascript object * @param options Response options. See: [[EamuseSendOption]] */ object: (res: any, options?: EamuseSendOption) => Promise; /** * Send xml data using ejs template system. * * @param res xml string as the template * @param data Render template with specified data, * pass null or undefined to render static xml * @param options Response options. See: [[EamuseSendOption]] */ xml: (res: string, data?: any, options?: EamuseSendOption) => Promise; /** * Send xml data using pug template system. * * @param res pug string as the template * @param data Render template with specified data, * pass null or undefined to render static xml * @param options Response options. See: [[EamuseSendOption]] */ pug: (res: string, data?: any, options?: EamuseSendOption) => Promise; /** * Render and send ejs template from a file * * @param file Filename of the template * @param data Render template with specified data, * pass null or undefined to render static xml * @param options Response options. See: [[EamuseSendOption]] */ xmlFile: ( file: string, data?: any, options?: EamuseSendOption ) => Promise; /** * Render and send pug template from a file * * @param file Filename of the template * @param data Render template with specified data, * pass null or undefined to render static xml * @param options Response options. See: [[EamuseSendOption]] */ pugFile: ( file: string, data?: any, options?: EamuseSendOption ) => Promise; } /** * Helper type for typing your custom route. */ declare type EamusePluginRoute = ( req: EamuseInfo, data: any, send: EamuseSend ) => Promise; /** * Helper type for typing your custom route. * * Alias for [[EamusePluginRoute]] */ declare type EPR = EamusePluginRoute; /** * R stands for `Register` * * These functions can only be called in plugins' `register()` function. */ declare namespace R { /** * Register your custom route. * * You should only call this from your plugin's `register()` function. * * @param method Method name of your target route, * usually looks like `"module.get"` * @param handler Your custom route function/method following the type [[EamusePluginRoute]]. * A boolean can be passed if you don't need any processing: * - `true`: Sending empty response with status code 0 * - `false`: Sending empty response with status code 1 */ function Route(method: string, handler: EamusePluginRoute | boolean): void; /** * Register all unhandled routes for a game. * * You should only call this from your plugin's `register()` function. * * @param handler Your custom route function/method following the type [[EamusePluginRoute]]. * If undefined, the router will apply a default handler that prints method names. */ function Unhandled(handler?: EamusePluginRoute): void; /** * Register a target game code to your plugin for checking savedata. * * You should only call this from your plugin's `register()` function. * * @param code Model code of your target machine, * usually __three capital letters__ * */ function GameCode(code: string): void; /** * Register a contributor. * * Contributors will show up in WebUI. * * @param name Contributor's name * @param link Contributor's homepage */ function Contributor(name: string, link?: string): void; /** * Register a configuration option. * * @param key config key * @param options See [[ConfigOption]] * * __NOTE__: `options.validator` will only notify user about invalid value. It wouldn't stop user from saving invalid value. */ function Config(key: string, options: ConfigOption): void; /** * Register a WebUI event callback * * Which can be called in WebUI using `emit(event)` function or a post message to `/emit/` * * Callback can be async function if you want to use await for your DB operations. */ function WebUIEvent( event: string, callback: (data: any) => void | Promise ): void; } /** * A warpper of javascript object for reading xml-like formatted data. */ declare class KDataReader { /** * Wrapped javascript object */ public obj: any; constructor(obj: any); /** * Get attrubutes for a tag * * Example: * ```xml * * * 1 * 2 * * * ``` * ```javascript * const data = { * tag: K.ATTR({ status: "1" }, { * inner: [ * K.ITEM("s32", 1), * K.ITEM("s32", 2) * ] * }) * } * ``` * * Evals: * ```javascript * $(data).attr("tag") // { status: "1" } * $(data).element("tag").attr().status // "1" * $(data).attr("tag.inner.0").__type // "s32" * ``` */ attr(path?: string): KAttrMap; /** * Get a bigint value from a tag, convert to bigint if applicable. * * Example: * ```xml * * 1 * 2 * abc * * ``` * ```javascript * const data = { * inner: [ * K.ITEM("s64", 1n), * K.ITEM("s32", 2) * ], * invalid: K.ITEM("str", "abc") * } * ``` * * Evals: * ```javascript * $(data).element("inner").bigint() // 1n * $(data).bigint("inner.1") // 2n * $(data).bigint("invalid", 3n) // 3n * ``` * * @param def Default return value when target path does * not exists or is not valid. */ bigint(path: string, def?: bigint): bigint; /** * Get a bigint array from a tag. Only returns valid arrays * when target tag has a type of [[KBigIntType]] or [[KBigIntGroupType]] * * Example: * ```xml * * 1 2 * 3 4 * * ``` * ```javascript * const data = { * inner: K.ARRAY("s64", [1n, 2n]), * invalid: K.ARRAY("s32", [3, 4]) * } * ``` * * Evals: * ```javascript * $(data).bigints("inner") // [1n, 2n] * $(data).bigints("invalid") // undefined * ``` */ bigints(path: string, def?: bigint[]): bigint[]; /** * Get a boolean value from a tag, return true only if value in the tag is number and **greater than zero** * * Example: * ```xml * * 0 * 2 * * ``` * ```javascript * const data = { * inner: [ * K.ITEM("bool", false), * K.ITEM("s32", 2) * ] * } * ``` * * Evals: * ```javascript * $(data).bool("inner.0") // false * $(data).bool("inner.1") // true * $(data).bool("invalid") // false * ``` */ bool(path: string): boolean; /** * Get a Buffer object from a tag, Only returns valid Buffer * when target tag has a type of "bin" * * Example: * ```xml * * 00ff * 1 2 3 * * ``` * ```javascript * const data = { * inner: K.ITEM("bin", Buffer.from([0x00, 0xff])), * invalid: K.ARRAY("u8", [1, 2, 3]) * } * ``` * * Evals: * ```javascript * $(data).buffer("inner") // * $(data).buffer("invalid") // undefined * ``` */ buffer(path: string, def?: Buffer): Buffer; /** * Get raw content representation regardless of tag type * * Example: * ```xml * * 1 * 1 2 3 * abc * * ``` * ```javascript * const data = { * number: K.ITEM("s32", 1), * array: K.ARRAY("u8", [1, 2, 3]), * string: K.ITEM("str", "abc") * } * ``` * * Evals: * ```javascript * $(data).content("number") // [1] * $(data).content("array") // [1, 2, 3] * $(data).content("string") // "abc" * ``` */ content(path: string, def?: any): any; /** * Get first element named **path** inside a tag * * Example: * ```xml * * * 1 * * * 1 * * * ``` * ```javascript * const data = { * inner: [ * { id: K.ITEM("s32", 1) }, * { id: K.ITEM("s32", 2) } * ] * } * ``` * * Evals: * ```javascript * $(data).element("inner") // * $(data).element("inner").obj // { id: [object] } * $(data).element("inner").number("id") // 1 * ``` */ element(path: string): KDataReader; /** * Get array of all elements named **path** inside a tag * * Example: * ```xml * * * 1 * * * 1 * * * ``` * ```javascript * const data = { * inner: [ * { id: K.ITEM("s32", 1) }, * { id: K.ITEM("s32", 2) } * ] * } * ``` * * Evals: * ```javascript * $(data).elements("inner") // [, ] * $(data).elements("inner")[1].number("id") // 2 * ``` */ elements(path: string): KDataReader[]; /** * Get a number value from a tag, convert to number if applicable. * * Example: * ```xml * * 1 * 2 * abc * * ``` * ```javascript * const data = { * inner: [ * K.ITEM("s64", 1n), * K.ITEM("s32", 2) * ], * invalid: K.ITEM("str", "abc") * } * ``` * * Evals: * ```javascript * $(data).element("inner").number() // 1 * $(data).number("inner.1") // 2 * $(data).number("invalid", 3) // 3 * ``` * * @param def Default return value when target path does * not exists or is not valid. */ number(path: string, def?: number): number; /** * Get a number array from a tag. Only returns valid arrays * when target tag has a type of [[KNumberType]] or [[KNumberGroupType]] * * Example: * ```xml * * 1 2 * 3 4 * * ``` * ```javascript * const data = { * invalid: K.ARRAY("s64", [1n, 2n]), * inner: K.ARRAY("s32", [3, 4]) * } * ``` * * Evals: * ```javascript * $(data).bigints("invalid") // undefined * $(data).bigints("inner") // [3, 4] * ``` */ numbers(path: string, def?: number[]): number[]; /** * Get a string from a tag, Only returns valid string * when target tag has a type of "str" * * Example: * ```xml * * abc * 1 * * ``` * ```javascript * const data = { * inner: K.ITEM("str", "abc"), * invalid: K.ITEM("s32", 1) * } * ``` * * Evals: * ```javascript * $(data).str("inner") // "abc" * $(data).str("invalid") // undefined * ``` */ str(path: string, def?: string): string; } /** * Helper for reading xml-like formatted data. */ declare function $(data: any): KDataReader; declare namespace $ { function ATTR(data: any, path?: string): KAttrMap; function BIGINT(data: any, path: string, def?: bigint): bigint; function BIGINTS(data: any, path: string, def?: bigint[]): bigint[]; function BOOL(data: any, path: string): boolean; function BUFFER(data: any, path: string, def?: Buffer): Buffer; function CONTENT(data: any, path: string, def?: any): any; function ELEMENT(data: any, path: string, def?: any): any; function ELEMENTS(data: any, path: string, def?: any): any; function NUMBER(data: any, path: string, def?: number): number; function NUMBERS(data: any, path: string, def?: number[]): number[]; function STR(data: any, path: string, def?: string): string; } /** @ignore */ declare interface KITEM< S extends | KNumberType | KBigIntType | KNumberGroupType | KBigIntGroupType | 'str' | 'bool' | 'bin' | 'ip4' > { '@attr': { __type: S; }; '@content': S extends 'str' ? string : S extends 'bin' ? Buffer : S extends KNumberType | 'ip4' | 'bool' ? [number] : S extends KBigIntType ? [bigint] : S extends KNumberGroupType ? number[] : S extends KBigIntGroupType ? bigint[] : unknown; } /** @ignore */ declare interface KARRAY { '@attr': { __count: number; __type: S; }; '@content': S extends KNumberType ? number[] : S extends KBigIntType ? bigint[] : unknown; } /** @ignore */ declare interface KATTR { '@attr': M; } /** * K stands for `Konstruct` * * Helper for constructing xml-like javascript object. */ declare namespace K { /** * Example: * ``` * { * tag: K.ATTR({attr: "1"}, { * inner: [{}, {}] * }) * } * ``` * Represents: * ``` * * * * * ``` * @param attr Attribute map * @param inner Inner tag/data */ function ATTR(attr: M, inner?: T): KATTR & T; /** * Example: * ``` * { * tag: K.ITEM('s32', 1, {attr: "2"}) * } * ``` * Represents: * ``` * 1 * ``` * @param type ____type__ attribute, which is used during encoding and compression * @param content data of specified type * @param attr attribute map in addition to **__type** */ function ITEM(type: 'str', content: string, attr?: KAttrMap): KITEM<'str'>; function ITEM(type: 'bin', content: Buffer, attr?: KAttrMap): KITEM<'bin'>; function ITEM(type: 'ip4', content: string, attr?: KAttrMap): KITEM<'ip4'>; function ITEM(type: 'bool', content: boolean, attr?: KAttrMap): KITEM<'bool'>; function ITEM( type: S, content: number, attr?: KAttrMap ): KITEM; function ITEM( type: S, content: bigint, attr?: KAttrMap ): KITEM; function ITEM( type: S, content: number[], attr?: KAttrMap ): KITEM; function ITEM( type: S, content: bigint[], attr?: KAttrMap ): KITEM; /** * Example: * ``` * { * tag: K.ARRAY('s32', [1, 2, 3], {attr: "4"}) * } * ``` * Represents: * ``` * 1 2 3 * ``` * @param type ____type__ attribute, which is used during encoding and compression * @param content array of data, ____count__ attribute will be automatically set to `content.length` * @param attr attribute map in addition to **__type** and **__count** */ function ARRAY( type: S, content: Buffer, attr?: KAttrMap ): KARRAY; function ARRAY( type: S, content: number[], attr?: KAttrMap ): KARRAY; function ARRAY( type: S, content: bigint[], attr?: KAttrMap ): KARRAY; } /** * Filesystem IO * * These are designed to match nodejs `fs` module. Along with custom filesystem implementation for reading compressed data. * * __DO NOT__ use IO for savedata. Please use [[DB]] namespace so your data can be managed by WebUI. * * Also, due to difference between operating systems, you should always prepare your files using ascii path. * Both UTF-8 and local encodings will have cross-platform compatibility issues. */ declare namespace IO { /** * Resolve a relative path starting from your plugin directory to an absolute path. */ function Resolve(path: string): string; /** * Asynchronously read a directory. * @param path A path to a directory. */ function ReadDir( path: string ): Promise<{ name: string; type: 'file' | 'dir' | 'unsupported' }[]>; /** * Asynchronously writes data to a file, replacing the file if it already exists. * @param path A path to a file. * If a file descriptor is provided, the underlying file will _not_ be closed automatically. * @param data The data to write. If something other than a Buffer or Uint8Array is provided, the value is coerced to a string. * @param options Either the encoding for the file, or an object optionally specifying the encoding, file mode, and flag. * If `encoding` is not supplied, the default of `'utf8'` is used. * If `mode` is not supplied, the default of `0o666` is used. * If `mode` is a string, it is parsed as an octal integer. * If `flag` is not supplied, the default of `'w'` is used. */ function WriteFile( path: string, data: any, options: | { encoding?: string | null; mode?: number | string; flag?: string } | string | null ): Promise; /** * Asynchronously writes data to a file, replacing the file if it already exists. * @param path A path to a file. * If a file descriptor is provided, the underlying file will _not_ be closed automatically. * @param data The data to write. If something other than a Buffer or Uint8Array is provided, the value is coerced to a string. */ function WriteFile(path: string, data: any): Promise; /** * Asynchronously reads the entire contents of a file. * @param path A path to a file. * If a file descriptor is provided, the underlying file will _not_ be closed automatically. * @param options An object that may contain an optional flag. * If a flag is not provided, it defaults to `'r'`. */ function ReadFile( path: string, options: { encoding?: null; flag?: string } | undefined | null ): Promise; /** * Asynchronously reads the entire contents of a file. * @param path A path to a file. * If a file descriptor is provided, the underlying file will _not_ be closed automatically. * @param options Either the encoding for the result, or an object that contains the encoding and an optional flag. * If a flag is not provided, it defaults to `'r'`. */ function ReadFile( path: string, options: { encoding: string; flag?: string } | string ): Promise; /** * Asynchronously reads the entire contents of a file. * @param path A path to a file. * If a file descriptor is provided, the underlying file will _not_ be closed automatically. * @param options Either the encoding for the result, or an object that contains the encoding and an optional flag. * If a flag is not provided, it defaults to `'r'`. */ function ReadFile( path: string, options: | { encoding?: string | null; flag?: string } | string | undefined | null ): Promise; /** * Asynchronously reads the entire contents of a file. * @param path A path to a file. * If a file descriptor is provided, the underlying file will _not_ be closed automatically. */ function ReadFile(path: string): Promise; } /** * U stands for `Utilities` * * You can find miscellaneous helpers here */ declare namespace U { /** * Convert json data to xml string. * * @param data xml-like javascript object */ function toXML(data: any): string; /** * Convert xml string to javascript object. Output will always be plain javascript string. * * @param xml xml string * @param simplify if true, the parser will ignore attributes and only generate string values. (default: true) */ function parseXML(xml: string, simplify?: boolean): any; /** * Get config from user configuration file. * @param key */ function GetConfig(key: string): any; } /** @ignore */ type Doc = { _id?: string } & T; /** @ignore */ type ProfileDoc = { _id?: string; __refid?: string } & T; /** @ignore */ type Query = { [P in keyof T]?: | T[P] | (T[P] extends Array ? { $elemMatch: Query } | { $size: number } : T[P] extends number | string ? | { $lt: T[P] } | { $lte: T[P] } | { $gt: T[P] } | { $gte: T[P] } | { $in: T[P][] } | { $ne: any } | { $nin: any[] } | { $exists: boolean } | { $regex: RegExp } : T[P] extends object ? Query : T[P]); } & { $or?: Query[]; $and?: Query[]; $not?: Query; $where?: (this: T) => boolean; _id?: string; [path: string]: any; }; /** @ignore */ type Operators = | '$exists' | '$lt' | '$lte' | '$gt' | '$gte' | '$in' | '$ne' | '$nin' | '$regex'; /** @ignore */ type PickyOperator = Pick< { [P in keyof T]?: T[P] extends C ? F : Omit; }, { [P in keyof T]: T[P] extends C ? P : never; }[keyof T] >; /** @ignore */ type ArrayPushOperator = Pick< { [P in keyof T]?: T[P] extends Array ? E | { $each?: E[]; $slice?: number } : never; }, { [P in keyof T]: T[P] extends Array ? P : never }[keyof T] > & { [path: string]: any | { $each?: any[]; $slice?: number } }; /** @ignore */ type ArraySetOperator = Pick< { [P in keyof T]?: T[P] extends Array ? E | { $each: E[] } : never; }, { [P in keyof T]: T[P] extends Array ? P : never }[keyof T] > & { [path: string]: any | { $each: any[] } }; /** @ignore */ type ArrayInOperator = Pick< { [P in keyof T]?: T[P] extends Array ? E | { $in: E[] } : never; }, { [P in keyof T]: T[P] extends Array ? P : never }[keyof T] > & { [path: string]: any | { $in: any[] } }; /** @ignore */ type ArrayPopOperator = Pick< { [P in keyof T]?: T[P] extends Array ? -1 | 1 : never; }, { [P in keyof T]: T[P] extends Array ? P : never }[keyof T] > & { [path: string]: -1 | 1 }; /** @ignore */ type Update = Partial & { $unset?: PickyOperator & { [path: string]: true }; $set?: { [P in keyof T]?: Omit } & { [path: string]: any }; $min?: PickyOperator & { [path: string]: number }; $max?: PickyOperator & { [path: string]: number }; $inc?: PickyOperator & { [path: string]: number }; $push?: ArrayPushOperator; $addToSet?: ArraySetOperator; $pop?: ArrayPopOperator; $pull?: ArrayInOperator; } & { [path: string]: any; }; /** * Database operation. * * There are two pools of data for each plugin: ___PluginSpace___ and __ProfileSpace__ * * If `refid` is a string, query will match a specific profile data in __ProfileSpace__. * * If `refid` is null, query will match all profile data in __ProfileSpace__. * (doesn't apply to [[DB.Insert]]) * * If `refid` is not provided, query will match data in ___PluginSpace___. * * --- * * **NOTE**: since WebUI can delete data in __ProfileSpace__, * you should refrain from referencing refid in your document to prevent getting unclearable garbage data. * * If you need to make rival/friend feature, we recommend you to get all profile data by passing null to `refid`. * There will be 16 profiles maximum which is small enough to manage. * * All query and doc should not have any fields start with "__" with "__refid" being the only exception. * However, "__refid" field will still be ignored while other "__" starting fields will cause an error to be thrown. */ declare namespace DB { function FindOne( refid: string | null, query: Query ): Promise>; function FindOne(query: Query): Promise>; function Find( refid: string | null, query: Query ): Promise[]>; function Find(query: Query): Promise[]>; function Insert(refid: string, doc: T): Promise>; function Insert(doc: T): Promise>; function Remove(refid: string | null, query: Query): Promise; function Remove(query: Query): Promise; function Update( refid: string | null, query: Query, update: Update ): Promise<{ updated: number; docs: ProfileDoc[]; }>; function Update( query: Query, update: Update ): Promise<{ updated: number; docs: Doc[]; }>; function Upsert( refid: string | null, query: Query, update: Update ): Promise<{ updated: number; docs: ProfileDoc[]; upsert: boolean; }>; function Upsert( query: Query, update: Update ): Promise<{ updated: number; docs: Doc[]; upsert: boolean; }>; function Count(refid: string | null, query: Query): Promise; function Count(query: Query): Promise; } /** @ignore */ // @ts-ignore declare const _: any;