Compare commits
No commits in common. "c3d47fec771179085814de6897f0a28acd083b4e" and "fe4248eb8be37568244588468c27cf09e33ba352" have entirely different histories.
c3d47fec77
...
fe4248eb8b
459
ambient.d.ts
vendored
459
ambient.d.ts
vendored
|
@ -1,459 +0,0 @@
|
||||||
interface ServerChatRoomMessage {
|
|
||||||
MBCHC_ID?: number
|
|
||||||
}
|
|
||||||
|
|
||||||
namespace BCE {
|
|
||||||
interface Matcher {
|
|
||||||
Tester: RegExp
|
|
||||||
Criteria?: {
|
|
||||||
TargetIsPlayer?: boolean
|
|
||||||
SenderIsPlayer?: boolean
|
|
||||||
DictionaryMatchers?: Array<OBJ<string>>
|
|
||||||
}
|
|
||||||
}
|
|
||||||
interface Trigger {
|
|
||||||
Event: string
|
|
||||||
Type: 'Emote' | 'Activity' | 'Action'
|
|
||||||
Matchers: Matcher[]
|
|
||||||
}
|
|
||||||
interface Patcher {
|
|
||||||
timer: number | undefined
|
|
||||||
patches: Array<[RegExp, string]>
|
|
||||||
cfs: {[k in 'anim' | 'pose']: () => Iterable<string>}
|
|
||||||
gen: (comp_func: () => Iterable<string>) => (this: Optional<ICommand, 'Tag'>) => undefined
|
|
||||||
copy(t: Trigger): Trigger
|
|
||||||
patch(): true | undefined
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
type SUBCOMMANDS = {
|
|
||||||
[k: string]: {
|
|
||||||
desc: string
|
|
||||||
args?: {[n: string]: OBJ}
|
|
||||||
cb: (mbchc: Window['MBCHC'], args: string[], __: unknown, ___?: unknown) => void
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
interface Window {
|
|
||||||
MBCHC: {
|
|
||||||
loader: () => void
|
|
||||||
DO_DATA: {
|
|
||||||
zones: OBJ<string>
|
|
||||||
verbs: {
|
|
||||||
[verb: string]: {
|
|
||||||
[zone: string]: {
|
|
||||||
self: string[]
|
|
||||||
others: string[]
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
MAP_ACTIONS: {
|
|
||||||
[verb: string]: {
|
|
||||||
[zones: string]: {
|
|
||||||
all?: string
|
|
||||||
self?: string
|
|
||||||
others?: string
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
MAP_ZONES: {[zone: string]: string[]}
|
|
||||||
LOADED: boolean
|
|
||||||
NEXT_MESSAGE: number
|
|
||||||
LOG_MESSAGES: boolean
|
|
||||||
LAST_HACKED: number | undefined
|
|
||||||
version: string
|
|
||||||
VERSION: string
|
|
||||||
Settings: Settings.Methods
|
|
||||||
TZ: TZ_Cache
|
|
||||||
SUBCOMMANDS_MBCHC: SUBCOMMANDS
|
|
||||||
H: InputHistory
|
|
||||||
U: Utils
|
|
||||||
AUTOHACK_ENABLED: boolean
|
|
||||||
RE_PREF_ACTIVITY_ME: RegExp
|
|
||||||
RE_PREF_ACTIVITY: RegExp
|
|
||||||
RE_ACT_CIDS: RegExp
|
|
||||||
RE_LAST_WORD: RegExp
|
|
||||||
RE_LAST_LETTER: RegExp
|
|
||||||
RE_ACTIVITY: RegExp
|
|
||||||
UTC_OFFSET: number
|
|
||||||
calculate_maps(): void
|
|
||||||
normalise_message(text: string, options?: OBJ<boolean>): string
|
|
||||||
donate_data(target: string): void
|
|
||||||
run_activity(char: Character, ag: AssetGroupItemName, action: ActivityName): void
|
|
||||||
send_activity(message: string): void
|
|
||||||
set_timezone(args: string[]): number | undefined
|
|
||||||
command_mbchc(this: Optional<ICommand, 'Tag'>, args: string, msg: string, parsed: string[]): undefined
|
|
||||||
command_activity(this: Optional<ICommand, 'Tag'>, args: string, msg: string, parsed: string[]): undefined
|
|
||||||
command_do(this: Optional<ICommand, 'Tag'>, args: string, msg: string, parsed: string[]): undefined
|
|
||||||
}
|
|
||||||
bcModSdk?: import('./node_modules/bondage-club-mod-sdk/dist/bcmodsdk.d.ts').ModSDKGlobalAPI;
|
|
||||||
FBC_VERSION?: string
|
|
||||||
bce_ActivityTriggers?: BCE.Trigger[]
|
|
||||||
bce_EventExpressions?: OBJ
|
|
||||||
}
|
|
||||||
|
|
||||||
type OBJ<T = unknown> = Record<string, T>;
|
|
||||||
type FUN = (...args: never[]) => unknown;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Stands for "Value or Function". Not remotely ideal, but the best I can come up with.
|
|
||||||
*/
|
|
||||||
type VOF<F extends FUN> = undefined | boolean | number | bigint | string | symbol | OBJ | Set<unknown> | Map<unknown, unknown> | FP.Interval | F;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* I can write Haskell in every language.
|
|
||||||
* I was unbelievably tempted to go with emojis here, but I'm not a monster of this caliber.
|
|
||||||
* @see https://8fw.me/hell/a8aaaefcb6e30ec4b2e398c70d49b72a6b53232f.png
|
|
||||||
*/
|
|
||||||
namespace FP {
|
|
||||||
interface Interval {
|
|
||||||
proxy: object // eslint-disable-line @typescript-eslint/ban-types
|
|
||||||
min: number
|
|
||||||
max: number
|
|
||||||
mini: boolean
|
|
||||||
maxi: boolean
|
|
||||||
has(_: unknown, x: string): boolean
|
|
||||||
}
|
|
||||||
|
|
||||||
interface Pipeline<T> {
|
|
||||||
proxy: PipelineProxy<T>
|
|
||||||
me<N>(iterable: Iterable<N>): PipelineProxy<N>
|
|
||||||
[Symbol.iterator](): Iterator<T>
|
|
||||||
rdc<R>(initial: R, func: (accumulator: R, value: T) => R): R
|
|
||||||
any(func: (v: T) => boolean): boolean
|
|
||||||
all(func: (v: T) => boolean): boolean
|
|
||||||
map<R>(func: (value: T) => R): PipelineProxy<R>
|
|
||||||
sel(func: (value: T) => boolean): PipelineProxy<T>
|
|
||||||
}
|
|
||||||
interface PipelineProxy<T> extends Pipeline<T> {
|
|
||||||
[i: number]: T | undefined
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Creates an iteration pipeline.
|
|
||||||
*/
|
|
||||||
type P = <T>(iterable: Iterable<T>) => PipelineProxy<T>;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* A silly helper to kinda c[au]rry values. Basically equivalent to:
|
|
||||||
* `const a = value; return func(a)`
|
|
||||||
* Stands for "Carry, Use, Return".
|
|
||||||
*/
|
|
||||||
type cur = <T, R>(value: T, func: (value: T) => R) => R;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Convert `null` to `undefined`.
|
|
||||||
*/ // eslint-disable-next-line @typescript-eslint/ban-types
|
|
||||||
type n2u = <T>(value: T | undefined | null) => T | undefined;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Enumerate keys of an object. Type-safe, also shorter.
|
|
||||||
*/
|
|
||||||
type enu = <O extends OBJ>(object: O) => Array<keyof O>;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Like `carry()` but does nothing if `value` is `null` or `undefined`.
|
|
||||||
* Something like an `Option<>` when you want to just pass `undefined` along, but
|
|
||||||
* run a function on actual values. Also coverts `null` to `undefined`.
|
|
||||||
*/ // eslint-disable-next-line @typescript-eslint/ban-types
|
|
||||||
type val = <T, R>(value: T | null | undefined, func: (value: T) => R) => R | undefined;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* `+` as a function
|
|
||||||
*/
|
|
||||||
type add = (x: number, y: number) => number;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* `-` as a function
|
|
||||||
*/
|
|
||||||
type sub = (x: number, y: number) => number;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* `>` as a function
|
|
||||||
*/
|
|
||||||
type cgt = (x: number, y: number) => boolean;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* `>=` as a function
|
|
||||||
*/
|
|
||||||
type cge = (x: number, y: number) => boolean;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* `<` as a function
|
|
||||||
*/
|
|
||||||
type clt = (x: number, y: number) => boolean;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* `<=` as a function
|
|
||||||
*/
|
|
||||||
type cle = (x: number, y: number) => boolean;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Converts a string into a base 10 integer. Not only is it shorter than `Number.parseInt`,
|
|
||||||
* it also converts `NaN` to `undefined`, because I find it much easier to only have
|
|
||||||
* one nil value for everything.
|
|
||||||
*/
|
|
||||||
type int = (text: string) => number | undefined;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* This is a type assertion helper for Typescript. Probably not very useful in general.
|
|
||||||
*/
|
|
||||||
type fun = <F extends FUN>(func: unknown) => func is F;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Takes anything, ignores non-functions, calls functions with supplied parameters.
|
|
||||||
*/
|
|
||||||
type run = <F extends FUN>(functions_or_values: Array<VOF<F>>, ...args: Parameters<F>) => true;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Takes anything, ignores non-functions, calls functions with `undefined` as a single parameter.
|
|
||||||
*/
|
|
||||||
type yes = (...args: Array<VOF<(_: undefined) => unknown>>) => true;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Takes anything, ignores non-functions, calls functions with a single provided parameter.
|
|
||||||
* Always returns the parameter itself.
|
|
||||||
*/
|
|
||||||
type mut = <T>(value: T, ...args: Array<VOF<(value: T) => unknown>>) => T;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* `delete` as a function
|
|
||||||
*/ // eslint-disable-next-line @typescript-eslint/ban-types
|
|
||||||
type del = <T extends object>(object: T, property: keyof T) => T;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Short for `assert`. Throws, if value is `undefined`, or if `condition(value)` is false.
|
|
||||||
*/
|
|
||||||
type ass = <T>(error: string, value: T | undefined, condition?: (value: T) => boolean) => T | never;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Casts value as a given prototype or returns undefined.
|
|
||||||
*/
|
|
||||||
type asa = <T>(prototype: new () => T, value: unknown) => T | undefined;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* `catch` as a function. Short for `rescue`.
|
|
||||||
*/
|
|
||||||
type rsc = (operation: (_: undefined) => unknown, exception_handler: (error: unknown) => unknown) => true;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Returns a proxy for `in` operator.
|
|
||||||
* Use it like `2 in rng(0, 4)`.
|
|
||||||
*/ // eslint-disable-next-line @typescript-eslint/ban-types
|
|
||||||
type rng = (min: number, max: number, min_inclusive?: boolean, max_inclusive?: boolean) => object;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Something slightly better than `Boolean()`.
|
|
||||||
* True is `null`, `undefined`, `false`, empty strings, sets, maps, arrays and objects.
|
|
||||||
* Short for "empty".
|
|
||||||
*/
|
|
||||||
type m_t = (value: unknown) => boolean;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* `while()` as a function. Executes the second callback while the first one is true.
|
|
||||||
* Always bound by max number of iterations.
|
|
||||||
* Returns the last value from the action or undefined if the action never ran.
|
|
||||||
*/
|
|
||||||
type loo = <T>(max: number, condition: (_: undefined) => boolean, action: (_: undefined) => T) => T | undefined;
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
namespace SDK {
|
|
||||||
type GDPT<F> = import('./node_modules/bondage-club-mod-sdk/dist/bcmodsdk.d.ts').GetDotedPathType<typeof globalThis, F>;
|
|
||||||
type Void<F extends FUN> = (...args: Parameters<F>) => unknown;
|
|
||||||
type Hook = <F extends string>(name: F, hook: Void<GDPT<F>>) => () => unknown;
|
|
||||||
}
|
|
||||||
|
|
||||||
namespace Cons {
|
|
||||||
type MS = {w: 'warn', i: 'info', d: 'debug', l: 'log'};
|
|
||||||
type E = (error: unknown) => true;
|
|
||||||
type F = (message: string) => true;
|
|
||||||
interface Wrap {
|
|
||||||
readonly ms: MS
|
|
||||||
e: E
|
|
||||||
w: F
|
|
||||||
i: F
|
|
||||||
d: F
|
|
||||||
l: F
|
|
||||||
gen: (m: keyof MS) => F
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
namespace Settings {
|
|
||||||
/**
|
|
||||||
* The whole `Player.OnlineSettings`.
|
|
||||||
*/
|
|
||||||
type V0 = PlayerOnlineSettings & {MBCHC?: {timezones?: Record<number, number>}};
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Specifically `MBCHC` inside `Player.ExtensionSettings`.
|
|
||||||
*/
|
|
||||||
interface V1 {
|
|
||||||
TZ: Record<number, number>
|
|
||||||
}
|
|
||||||
|
|
||||||
interface Methods {
|
|
||||||
migrate_0_1(v0: V0): true
|
|
||||||
save(func?: (v1: V1) => unknown): true
|
|
||||||
replace(new_v1: V1): true
|
|
||||||
'purge!'(): true
|
|
||||||
get v0(): V0 | undefined
|
|
||||||
get v1(): V1
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* We need a place to cache the timezones instead of the `Character` object itself.
|
|
||||||
*/
|
|
||||||
interface TZ_Cache {
|
|
||||||
map: Map<number, number>
|
|
||||||
RE: RegExp
|
|
||||||
parse(description: string | undefined): number | undefined
|
|
||||||
memo(member_number: number, description?: string | undefined): number | undefined
|
|
||||||
lookup(character: Character): number | undefined
|
|
||||||
}
|
|
||||||
|
|
||||||
interface Utils {
|
|
||||||
remove_loader_hook: (() => unknown) | undefined
|
|
||||||
RE: {SPACES: RegExp, REL: {L: RegExp, R: RegExp}, '@': [RegExp, RegExp]}
|
|
||||||
RGB: {Polly: string, Mute: string}
|
|
||||||
ACT: string,
|
|
||||||
get crc(): Character[]
|
|
||||||
get ic(): HTMLTextAreaElement | undefined
|
|
||||||
cid(character: Character): number | undefined
|
|
||||||
dn(character: Character): string
|
|
||||||
current(): string
|
|
||||||
style<T>(query: string, func: (s: CSSStyleDeclaration) => T): T | undefined
|
|
||||||
inform(html: string): true
|
|
||||||
report(error: unknown): true
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Splits a string into words by continuous whitespace sequences. Some examples:
|
|
||||||
* ```
|
|
||||||
* "" => [""]
|
|
||||||
* " " => ["", ""]
|
|
||||||
* "f g" => ["f", "g"]
|
|
||||||
* " f g " => ["", "f", "g", ""]
|
|
||||||
* ```
|
|
||||||
*/
|
|
||||||
split(text: string): string[]
|
|
||||||
abs2char(index: number): Character
|
|
||||||
rel2char(target: string): Character
|
|
||||||
cid2char(cid: number): Character
|
|
||||||
target2char(target: string): Character
|
|
||||||
mkdiv(html?: string): HTMLDivElement
|
|
||||||
bell(): true
|
|
||||||
targets(me2?: boolean, check_perms?: boolean): Set<string>
|
|
||||||
complete_mbchc(this: Optional<ICommand, 'Tag'>): undefined
|
|
||||||
complete_do_target(actions: {self: unknown, others: unknown}): Set<string>
|
|
||||||
complete_do(this: Optional<ICommand, 'Tag'>): undefined
|
|
||||||
replace_me(_match: string, _offset: number, whole: string): string
|
|
||||||
//pad_chat(chat: HTMLDivElement): undefined
|
|
||||||
}
|
|
||||||
|
|
||||||
interface Complete {
|
|
||||||
S_OPTS: {behavior: 'instant'}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* The suggestions panel.
|
|
||||||
* Its structure is (outer div) -> (container div) -> (multiple suggestion div elements)
|
|
||||||
*/
|
|
||||||
e: HTMLDivElement
|
|
||||||
|
|
||||||
/**
|
|
||||||
* The container div.
|
|
||||||
*/
|
|
||||||
get div(): Element | undefined
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Longest common prefix, or an empty string for an empty set.
|
|
||||||
*/
|
|
||||||
lcp(candidates: Set<string>): string
|
|
||||||
|
|
||||||
/**
|
|
||||||
* !WARNING! Mutate the given set in accordance with the input.
|
|
||||||
* Returns the input with completion done and removes all failed candidates.
|
|
||||||
* If the set is empty, the completion failed and the result is the unmodified input.
|
|
||||||
* If the set has more than one value, these are all new candidates, and the input was completed with the lcp.
|
|
||||||
* Otherwise, the only successful candidate will remain in the set and the input was completed to it.
|
|
||||||
*/
|
|
||||||
complete_word(input: string, candidates: Set<string>, ignore_case?: boolean | undefined): string
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Show the suggestions to the user.
|
|
||||||
*/
|
|
||||||
hint(candidates: Set<string>): true
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Returns false if the suggestion panel is visible.
|
|
||||||
*/
|
|
||||||
get hidden(): boolean
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Makes the suggestions panel disappear.
|
|
||||||
*/
|
|
||||||
hide(): true
|
|
||||||
|
|
||||||
/**
|
|
||||||
* The whole deal. Will read and modify the chat input window.
|
|
||||||
* Takes a callback that will receive current input split into words
|
|
||||||
* and should return all possible candidates for the word being completed.
|
|
||||||
* Note: if the input ends with whitespace, the last word will be empty.
|
|
||||||
*/
|
|
||||||
complete(func: (words: string[]) => Set<string>, ignore_case?: boolean | undefined): true
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Case-insensitive complete.
|
|
||||||
*/
|
|
||||||
icomplete(func: (words: string[]) => Set<string>): true
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* So, this is what happens. We have two modes: input mode and history mode. In the history mode the element is read-only.
|
|
||||||
* In the input mode:
|
|
||||||
* If the input is empty, we just scroll the history as usual
|
|
||||||
* Otherwise, we build a history set using the input as prefix
|
|
||||||
* The history set filters through the history, keeping only unique lines that start with the prefix along with indices
|
|
||||||
* But we exclude lines that match the input exactly
|
|
||||||
* It keeps the original input in a separate place too
|
|
||||||
* If the set is empty, we bell out
|
|
||||||
* Otherwise, we enter the history mode and invoke the first search
|
|
||||||
* In the history mode:
|
|
||||||
* We search up or down, using the index as a starting point for the next match, treating the set as a ring
|
|
||||||
* If the found line is the same as the current line, we bell out
|
|
||||||
* Upon finding a next match, we replace the input with its text and set the index appropriately
|
|
||||||
* We exit the history mode using the InputChat keydown handler, on Tab, Escape or Enter
|
|
||||||
* Escape restores the saved input, discarding the history line
|
|
||||||
* Tab keeps the current text and unlocks the element, allowing it to be edited
|
|
||||||
* Enter keeps the current text and sends it as the message as usual
|
|
||||||
*/
|
|
||||||
interface InputHistory {
|
|
||||||
/**
|
|
||||||
* Whether the chat log is scrolled to the end when we enter history mode.
|
|
||||||
*/
|
|
||||||
bottom: boolean | undefined
|
|
||||||
|
|
||||||
/**
|
|
||||||
* The initial user input when we enter the history mode.
|
|
||||||
*/
|
|
||||||
input: string | undefined
|
|
||||||
|
|
||||||
/**
|
|
||||||
* The indices of the lines that match the prefix.
|
|
||||||
*/
|
|
||||||
ids: Set<number> | undefined
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Enter the history mode.
|
|
||||||
*/
|
|
||||||
enter(textarea: HTMLTextAreaElement, input: string, bottom: boolean, ids: Set<number>): true
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Exit the history mode and optionally restore original input.
|
|
||||||
*/
|
|
||||||
exit(textarea: HTMLTextAreaElement, restore_input: boolean): true
|
|
||||||
}
|
|
||||||
|
|
||||||
// FIXME spread around readonly where appropriate
|
|
|
@ -2,24 +2,17 @@
|
||||||
"include": [
|
"include": [
|
||||||
"node_modules/bc-stubs/bc/**/*.d.ts",
|
"node_modules/bc-stubs/bc/**/*.d.ts",
|
||||||
"node_modules/bondage-club-mod-sdk/dist/**/*.d.ts",
|
"node_modules/bondage-club-mod-sdk/dist/**/*.d.ts",
|
||||||
"ambient.d.ts",
|
"typedef.d.ts",
|
||||||
"mbchc.mjs",
|
"mbchc.mjs",
|
||||||
"server.js"
|
"server.js"
|
||||||
],
|
],
|
||||||
"compilerOptions": {
|
"compilerOptions": {
|
||||||
"target": "es2023",
|
"lib": [
|
||||||
"allowJs": true,
|
"es2022",
|
||||||
|
"DOM"
|
||||||
|
],
|
||||||
"checkJs": true,
|
"checkJs": true,
|
||||||
"allowUnreachableCode": false,
|
"strict": false,
|
||||||
"allowUnusedLabels": false,
|
"noImplicitOverride": true
|
||||||
"exactOptionalPropertyTypes": true,
|
|
||||||
"noImplicitOverride": true,
|
|
||||||
"noImplicitReturns": true,
|
|
||||||
"noPropertyAccessFromIndexSignature": true,
|
|
||||||
"noUncheckedIndexedAccess": true,
|
|
||||||
"noUnusedLocals": true,
|
|
||||||
"noUnusedParameters": true,
|
|
||||||
"strict": true,
|
|
||||||
"noEmit": true
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
15
package-lock.json
generated
15
package-lock.json
generated
|
@ -1,17 +1,16 @@
|
||||||
{
|
{
|
||||||
"name": "mbchc",
|
"name": "mbchc",
|
||||||
"version": "107.13.0",
|
"version": "0.0.12",
|
||||||
"lockfileVersion": 3,
|
"lockfileVersion": 3,
|
||||||
"requires": true,
|
"requires": true,
|
||||||
"packages": {
|
"packages": {
|
||||||
"": {
|
"": {
|
||||||
"name": "mbchc",
|
"name": "mbchc",
|
||||||
"version": "107.13.0",
|
"version": "0.0.12",
|
||||||
"license": "SEE LICENSE IN LICENSE",
|
"license": "SEE LICENSE IN LICENSE.",
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"bc-stubs": "^107.0.0",
|
"bc-stubs": "^105.0.0",
|
||||||
"bondage-club-mod-sdk": "^1.2.0",
|
"bondage-club-mod-sdk": "^1.2.0",
|
||||||
"typescript": "^5.5.2",
|
|
||||||
"xo": "^0.56.0"
|
"xo": "^0.56.0"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
@ -1074,9 +1073,9 @@
|
||||||
"dev": true
|
"dev": true
|
||||||
},
|
},
|
||||||
"node_modules/bc-stubs": {
|
"node_modules/bc-stubs": {
|
||||||
"version": "107.0.0",
|
"version": "105.0.3",
|
||||||
"resolved": "https://registry.npmjs.org/bc-stubs/-/bc-stubs-107.0.0.tgz",
|
"resolved": "https://registry.npmjs.org/bc-stubs/-/bc-stubs-105.0.3.tgz",
|
||||||
"integrity": "sha512-PUEvMGe7dDm+lKy6YJIWv1xWCOBVt/WAn4xrG8mBUoGobZVBqOrg+x5lOV0HvG9fcBB8K5NEaXMciE5TOTWkBA==",
|
"integrity": "sha512-haKRphxOdPQT/9W6s5L0x5DFDttOrk0xBddFfoLnMQlz7AiXnU3TGdlJ+biWpmQtyHc7WrJARbYd4Wf7+a4j8g==",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"socket.io-client": "4.6.1"
|
"socket.io-client": "4.6.1"
|
||||||
|
|
74
package.json
74
package.json
|
@ -1,92 +1,38 @@
|
||||||
{
|
{
|
||||||
"name": "mbchc",
|
"name": "mbchc",
|
||||||
"version": "107.13.0",
|
"version": "0.0.12",
|
||||||
"description": "Mute's Bondage Club Hacks Collection",
|
"description": "Mute's Bondage Club Hacks Collection",
|
||||||
"author": "Mute",
|
|
||||||
"type": "module",
|
"type": "module",
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"bc-stubs": "^107.0.0",
|
"xo": "^0.56.0",
|
||||||
"bondage-club-mod-sdk": "^1.2.0",
|
"bc-stubs": "^105.0.0",
|
||||||
"typescript": "^5.5.2",
|
"bondage-club-mod-sdk": "^1.2.0"
|
||||||
"xo": "^0.56.0"
|
|
||||||
},
|
},
|
||||||
"license": "SEE LICENSE IN LICENSE",
|
"license": "SEE LICENSE IN LICENSE.",
|
||||||
"eslintConfig": {
|
"xo": {
|
||||||
"root": true,
|
"env": [
|
||||||
"extends": ["xo", "xo-typescript", "plugin:unicorn/recommended"],
|
"browser",
|
||||||
"parser": "@typescript-eslint/parser",
|
"node"
|
||||||
"parserOptions": { "project": ["./jsconfig.json"] },
|
],
|
||||||
"plugins": ["@typescript-eslint", "unicorn"],
|
|
||||||
"rules": {
|
"rules": {
|
||||||
"@typescript-eslint/brace-style": "off",
|
|
||||||
"@typescript-eslint/comma-dangle": ["error", "only-multiline"],
|
|
||||||
"@typescript-eslint/consistent-indexed-object-style": "off",
|
|
||||||
"@typescript-eslint/consistent-type-definitions": "off",
|
|
||||||
"@typescript-eslint/consistent-type-imports": "off",
|
|
||||||
"@typescript-eslint/dot-notation": "off",
|
|
||||||
"@typescript-eslint/lines-between-class-members": "off",
|
|
||||||
"@typescript-eslint/member-delimiter-style": "off",
|
|
||||||
"@typescript-eslint/naming-convention": "off",
|
|
||||||
"@typescript-eslint/no-confusing-void-expression": ["error", {
|
|
||||||
"ignoreVoidOperator": true
|
|
||||||
}],
|
|
||||||
"@typescript-eslint/no-explicit-any": "error",
|
|
||||||
"@typescript-eslint/no-meaningless-void-operator": "off",
|
|
||||||
"@typescript-eslint/no-unused-expressions": "off",
|
|
||||||
"@typescript-eslint/object-curly-spacing": "off",
|
|
||||||
"@typescript-eslint/padding-line-between-statements": "off",
|
|
||||||
"@typescript-eslint/semi": "off",
|
|
||||||
"@typescript-eslint/space-before-function-paren": "off",
|
|
||||||
"@typescript-eslint/strict-boolean-expressions": ["error", {
|
|
||||||
"allowString": false,
|
|
||||||
"allowNumber": false,
|
|
||||||
"allowNullableObject": false
|
|
||||||
}],
|
|
||||||
"array-element-newline": "off",
|
|
||||||
"brace-style": "off",
|
"brace-style": "off",
|
||||||
"camelcase": "off",
|
"camelcase": "off",
|
||||||
"capitalized-comments": "off",
|
"capitalized-comments": "off",
|
||||||
"curly": "off",
|
"curly": "off",
|
||||||
"generator-star-spacing": "off",
|
|
||||||
"max-nested-callbacks": "off",
|
|
||||||
"max-params": "off",
|
"max-params": "off",
|
||||||
"max-statements-per-line": "off",
|
"max-statements-per-line": "off",
|
||||||
"new-cap": "off",
|
"new-cap": "off",
|
||||||
"no-mixed-spaces-and-tabs": ["error", "smart-tabs"],
|
|
||||||
"no-return-assign": "off",
|
"no-return-assign": "off",
|
||||||
"no-unused-expressions": "off",
|
"no-unused-expressions": "off",
|
||||||
"no-unused-vars": ["error", {
|
"no-unused-vars": ["error", {
|
||||||
"argsIgnorePattern": "^_",
|
"argsIgnorePattern": "^_",
|
||||||
"destructuredArrayIgnorePattern": "^_"
|
"destructuredArrayIgnorePattern": "^_"
|
||||||
}],
|
}],
|
||||||
"no-void": "off",
|
|
||||||
"padding-line-between-statements": "off",
|
"padding-line-between-statements": "off",
|
||||||
"object-curly-newline": "off",
|
|
||||||
"one-var": "off",
|
|
||||||
"one-var-declaration-per-line": "off",
|
|
||||||
"semi": "off",
|
"semi": "off",
|
||||||
"space-before-function-paren": "off",
|
|
||||||
"spaced-comment": "off",
|
"spaced-comment": "off",
|
||||||
"unicorn/catch-error-name": ["error", {"name": "x"}],
|
|
||||||
"unicorn/consistent-function-scoping": "off",
|
|
||||||
"unicorn/no-array-callback-reference": "off",
|
|
||||||
"unicorn/no-array-for-each": "off",
|
|
||||||
"unicorn/no-array-reduce": "off",
|
"unicorn/no-array-reduce": "off",
|
||||||
"unicorn/no-nested-ternary": "off",
|
|
||||||
"unicorn/prevent-abbreviations": ["error", {
|
|
||||||
"allowList": {"cur": true, "args": true, "func": true, "val": true, "mod": true, "msg": true, "i": true, "e": true}
|
|
||||||
}],
|
|
||||||
"unicorn/switch-case-braces": ["error", "avoid"],
|
|
||||||
"fake/fuck-commas": "off"
|
"fake/fuck-commas": "off"
|
||||||
},
|
|
||||||
"overrides": [
|
|
||||||
{
|
|
||||||
"files": ["*.d.ts"],
|
|
||||||
"rules": {
|
|
||||||
"@typescript-eslint/semi": "error",
|
|
||||||
"no-unused-vars": "off"
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
]
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
23
server.js
23
server.js
|
@ -1,8 +1,7 @@
|
||||||
import {readFileSync} from 'node:fs'
|
import {readFileSync} from 'node:fs'
|
||||||
import {createServer} from 'node:http'
|
import {createServer} from 'node:http'
|
||||||
import {argv} from 'node:process'
|
|
||||||
|
|
||||||
const config = {host: '127.0.0.1', port: 9696, filename: argv[2] ?? 'mbchc.mjs'}
|
const config = {host: '127.0.0.1', port: 9696}
|
||||||
|
|
||||||
const h_cors = {
|
const h_cors = {
|
||||||
'Access-Control-Max-Age': '86400',
|
'Access-Control-Max-Age': '86400',
|
||||||
|
@ -12,19 +11,23 @@ const h_cors = {
|
||||||
'Access-Control-Allow-Headers': '*',
|
'Access-Control-Allow-Headers': '*',
|
||||||
// 'Access-Control-Allow-Credentials': 'false', // omit this header to disallow
|
// 'Access-Control-Allow-Credentials': 'false', // omit this header to disallow
|
||||||
}
|
}
|
||||||
const h_all = {
|
const h_all = Object.assign({
|
||||||
'Content-Type': 'text/javascript',
|
'Content-Type': 'text/javascript',
|
||||||
'Cache-Control': 'no-cache',
|
'Cache-Control': 'no-cache',
|
||||||
...h_cors
|
}, h_cors)
|
||||||
}
|
|
||||||
|
|
||||||
/** @type {Record<string,((request: import('node:http').ServerResponse) => void)>} */ const resp = {
|
/**
|
||||||
GET(rx) { rx.writeHead(200, h_all); rx.write(readFileSync(config.filename)) },
|
* @typedef {import('node:http').ServerResponse} ServerResponse
|
||||||
|
* @type {Record<string,function(ServerResponse):void>}
|
||||||
|
*/
|
||||||
|
const resp = {
|
||||||
|
GET(rx) { rx.writeHead(200, h_all); rx.write(readFileSync('./mbchc.mjs')) },
|
||||||
OPTIONS(rx) { rx.writeHead(204, h_cors) },
|
OPTIONS(rx) { rx.writeHead(204, h_cors) },
|
||||||
}
|
}
|
||||||
|
|
||||||
const server = createServer((rq, rx) => {
|
const server = createServer((rq, rx) => {
|
||||||
rq.method !== undefined && resp[rq.method] !== undefined && (new URL(`http://${config.host}:${config.port}${rq.url}`)).pathname === '/' ? resp[rq.method](rx) : rx.writeHead(400)
|
resp[rq.method] && (new URL(`http://${config.host}:${config.port}${rq.url}`)).pathname === '/' ? resp[rq.method](rx) : rx.writeHead(400)
|
||||||
rx.end(() => void console.log('%s %d %s %s', (new Date()).toISOString(), rx.statusCode, rq.method, rq.url))
|
rx.end()
|
||||||
|
console.log('%s %d %s %s', (new Date()).toISOString(), rx.statusCode, rq.method, rq.url)
|
||||||
})
|
})
|
||||||
server.listen(config.port, config.host, () => void console.log(`Server started at http://${config.host}:${config.port} for ${config.filename}`))
|
server.listen(config.port, config.host, () => console.log(`Server started at http://${config.host}:${config.port}`))
|
||||||
|
|
10
typedef.d.ts
vendored
Normal file
10
typedef.d.ts
vendored
Normal file
|
@ -0,0 +1,10 @@
|
||||||
|
/* eslint-disable no-unused-vars */
|
||||||
|
/* eslint-disable @typescript-eslint/consistent-type-definitions */
|
||||||
|
|
||||||
|
interface PlayerOnlineSettings {
|
||||||
|
MBCHC?: any;
|
||||||
|
}
|
||||||
|
|
||||||
|
interface ServerChatRoomMessage {
|
||||||
|
MBCHC_ID?: number;
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user