262 lines
6.7 KiB
Markdown
262 lines
6.7 KiB
Markdown
|
|
# API Reference
|
||
|
|
|
||
|
|
BetterCurseForge exposes a global runtime object on `window.BetterCurseForge` within the CurseForge Electron renderer process. This API allows themes, plugins, and developer scripts to inject styles, monkey-patch methods, manage settings, and listen to application events.
|
||
|
|
|
||
|
|
---
|
||
|
|
|
||
|
|
## TypeScript Definition
|
||
|
|
|
||
|
|
For TypeScript development and autocompletion:
|
||
|
|
|
||
|
|
```typescript
|
||
|
|
declare global {
|
||
|
|
interface Window {
|
||
|
|
BetterCurseForge: BetterCurseForgeAPI;
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
export interface BetterCurseForgeAPI {
|
||
|
|
/** Active BetterCurseForge runtime version */
|
||
|
|
readonly version: string;
|
||
|
|
|
||
|
|
/** Injects CSS dynamically into <head>. Returns an unmount callback. */
|
||
|
|
injectCSS(css: string): () => void;
|
||
|
|
|
||
|
|
/** Persistent settings storage */
|
||
|
|
settings: {
|
||
|
|
get(key?: string): Promise<any>;
|
||
|
|
set(key: string, value: any): Promise<boolean>;
|
||
|
|
};
|
||
|
|
|
||
|
|
/** Runtime method interception and monkey-patching */
|
||
|
|
patcher: {
|
||
|
|
before(obj: any, method: string, callback: (args: any[]) => void): () => void;
|
||
|
|
after(obj: any, method: string, callback: (args: any[], result: any) => any): () => void;
|
||
|
|
instead(obj: any, method: string, callback: (args: any[], original: Function) => any): () => void;
|
||
|
|
};
|
||
|
|
|
||
|
|
/** Event bus */
|
||
|
|
on(event: string, callback: (...args: any[]) => void): void;
|
||
|
|
off(event: string, callback: (...args: any[]) => void): void;
|
||
|
|
emit(event: string, ...args: any[]): void;
|
||
|
|
|
||
|
|
/** Internal subsystem managers */
|
||
|
|
themes: ThemeManager;
|
||
|
|
plugins: PluginManager;
|
||
|
|
ads: AdBlocker;
|
||
|
|
}
|
||
|
|
```
|
||
|
|
|
||
|
|
---
|
||
|
|
|
||
|
|
## Core API
|
||
|
|
|
||
|
|
### `BetterCurseForge.version`
|
||
|
|
|
||
|
|
- **Type**: `string`
|
||
|
|
- **Description**: The currently running BetterCurseForge runtime version.
|
||
|
|
|
||
|
|
```javascript
|
||
|
|
console.log(BetterCurseForge.version); // "1.0.0"
|
||
|
|
```
|
||
|
|
|
||
|
|
---
|
||
|
|
|
||
|
|
### `BetterCurseForge.injectCSS(css)`
|
||
|
|
|
||
|
|
Dynamically injects CSS rules into the document `<head>`.
|
||
|
|
|
||
|
|
- **Parameters**:
|
||
|
|
- `css` *(string)*: Raw CSS string to inject.
|
||
|
|
- **Returns**: `() => void` — Function that removes the injected `<style>` tag when called.
|
||
|
|
|
||
|
|
```javascript
|
||
|
|
// Inject styles
|
||
|
|
const uninject = BetterCurseForge.injectCSS(`
|
||
|
|
.some-container {
|
||
|
|
background-color: #1a102f !important;
|
||
|
|
}
|
||
|
|
`);
|
||
|
|
|
||
|
|
// Later, remove the styles
|
||
|
|
uninject();
|
||
|
|
```
|
||
|
|
|
||
|
|
---
|
||
|
|
|
||
|
|
## Settings API (`BetterCurseForge.settings`)
|
||
|
|
|
||
|
|
Manages persistent configuration stored in `%APPDATA%\CurseForge\BetterCurseForge\settings.json`.
|
||
|
|
|
||
|
|
### `settings.get(key?)`
|
||
|
|
|
||
|
|
Retrieves a setting by key, or returns the entire settings object if no key is specified.
|
||
|
|
|
||
|
|
- **Parameters**:
|
||
|
|
- `key` *(string, optional)*: Setting key name.
|
||
|
|
- **Returns**: `Promise<any>` — Value of the setting, or `null`.
|
||
|
|
|
||
|
|
```javascript
|
||
|
|
// Retrieve a specific value
|
||
|
|
const activeTheme = await BetterCurseForge.settings.get('activeCustomTheme');
|
||
|
|
|
||
|
|
// Retrieve all settings
|
||
|
|
const allSettings = await BetterCurseForge.settings.get();
|
||
|
|
```
|
||
|
|
|
||
|
|
### `settings.set(key, value)`
|
||
|
|
|
||
|
|
Stores a setting value and writes it asynchronously to disk.
|
||
|
|
|
||
|
|
- **Parameters**:
|
||
|
|
- `key` *(string)*: Setting key name.
|
||
|
|
- `value` *(any)*: JSON-serializable value.
|
||
|
|
- **Returns**: `Promise<boolean>` — `true` if saved successfully.
|
||
|
|
|
||
|
|
```javascript
|
||
|
|
await BetterCurseForge.settings.set('myPlugin.fontSize', 14);
|
||
|
|
```
|
||
|
|
|
||
|
|
---
|
||
|
|
|
||
|
|
## Patcher API (`BetterCurseForge.patcher`)
|
||
|
|
|
||
|
|
Provides monkey-patching utilities to inspect, modify, or replace methods on JavaScript objects and modules safely.
|
||
|
|
|
||
|
|
### `patcher.before(obj, method, callback)`
|
||
|
|
|
||
|
|
Executes `callback(args)` **before** the target method is invoked.
|
||
|
|
|
||
|
|
- **Parameters**:
|
||
|
|
- `obj` *(object)*: Target object.
|
||
|
|
- `method` *(string)*: Method name on `obj`.
|
||
|
|
- `callback` *(Function)*: Function receiving arguments: `(args) => void`.
|
||
|
|
- **Returns**: `() => void` — Unpatch function that restores the original method.
|
||
|
|
|
||
|
|
```javascript
|
||
|
|
const unpatch = BetterCurseForge.patcher.before(console, 'warn', (args) => {
|
||
|
|
console.log('[Warn Interceptor]', ...args);
|
||
|
|
});
|
||
|
|
|
||
|
|
// Revert patch:
|
||
|
|
unpatch();
|
||
|
|
```
|
||
|
|
|
||
|
|
---
|
||
|
|
|
||
|
|
### `patcher.after(obj, method, callback)`
|
||
|
|
|
||
|
|
Executes `callback(args, result)` **after** the target method runs. You can return a new value to replace the method's return value.
|
||
|
|
|
||
|
|
- **Parameters**:
|
||
|
|
- `obj` *(object)*: Target object.
|
||
|
|
- `method` *(string)*: Method name on `obj`.
|
||
|
|
- `callback` *(Function)*: `(args, result) => any`.
|
||
|
|
- **Returns**: `() => void` — Unpatch function.
|
||
|
|
|
||
|
|
```javascript
|
||
|
|
const unpatch = BetterCurseForge.patcher.after(service, 'getTitle', (args, result) => {
|
||
|
|
return `Prefix: ${result}`;
|
||
|
|
});
|
||
|
|
|
||
|
|
unpatch();
|
||
|
|
```
|
||
|
|
|
||
|
|
---
|
||
|
|
|
||
|
|
### `patcher.instead(obj, method, callback)`
|
||
|
|
|
||
|
|
Completely overrides the target method. Receives both the incoming arguments and a reference to the original method.
|
||
|
|
|
||
|
|
- **Parameters**:
|
||
|
|
- `obj` *(object)*: Target object.
|
||
|
|
- `method` *(string)*: Method name on `obj`.
|
||
|
|
- `callback` *(Function)*: `(args, originalFn) => any`.
|
||
|
|
- **Returns**: `() => void` — Unpatch function.
|
||
|
|
|
||
|
|
```javascript
|
||
|
|
const unpatch = BetterCurseForge.patcher.instead(target, 'openExternalUrl', (args, originalFn) => {
|
||
|
|
const url = args[0];
|
||
|
|
if (url.startsWith('https://safe-domain.com')) {
|
||
|
|
return originalFn(...args);
|
||
|
|
}
|
||
|
|
console.warn('Blocked external URL navigation:', url);
|
||
|
|
});
|
||
|
|
|
||
|
|
unpatch();
|
||
|
|
```
|
||
|
|
|
||
|
|
---
|
||
|
|
|
||
|
|
## Event System (`BetterCurseForge.on / off / emit`)
|
||
|
|
|
||
|
|
BetterCurseForge includes an event bus for inter-plugin and lifecycle communication.
|
||
|
|
|
||
|
|
### `BetterCurseForge.on(event, callback)`
|
||
|
|
Subscribes a listener to an event.
|
||
|
|
|
||
|
|
```javascript
|
||
|
|
const onReady = () => console.log('BetterCurseForge is ready!');
|
||
|
|
BetterCurseForge.on('ready', onReady);
|
||
|
|
```
|
||
|
|
|
||
|
|
### `BetterCurseForge.off(event, callback)`
|
||
|
|
Unsubscribes a listener.
|
||
|
|
|
||
|
|
```javascript
|
||
|
|
BetterCurseForge.off('ready', onReady);
|
||
|
|
```
|
||
|
|
|
||
|
|
### `BetterCurseForge.emit(event, ...args)`
|
||
|
|
Emits an event to all registered listeners.
|
||
|
|
|
||
|
|
```javascript
|
||
|
|
BetterCurseForge.emit('custom-event', { detail: 123 });
|
||
|
|
```
|
||
|
|
|
||
|
|
---
|
||
|
|
|
||
|
|
## Subsystem Managers
|
||
|
|
|
||
|
|
### `BetterCurseForge.themes` (`ThemeManager`)
|
||
|
|
Provides programmatic control over custom themes:
|
||
|
|
|
||
|
|
```javascript
|
||
|
|
// Get all discovered themes
|
||
|
|
const themes = BetterCurseForge.themes.getThemes();
|
||
|
|
|
||
|
|
// Get active theme filename (or null)
|
||
|
|
const currentTheme = BetterCurseForge.themes.getActiveThemeName();
|
||
|
|
|
||
|
|
// Preview a theme temporarily on screen
|
||
|
|
BetterCurseForge.themes.previewTheme(themes[0]);
|
||
|
|
|
||
|
|
// Revert preview back to active theme
|
||
|
|
BetterCurseForge.themes.cancelPreview();
|
||
|
|
|
||
|
|
// Apply and save a theme permanently
|
||
|
|
BetterCurseForge.themes.applyTheme(themes[0], true);
|
||
|
|
|
||
|
|
// Remove custom theme and revert to native CurseForge skin
|
||
|
|
BetterCurseForge.themes.removeTheme(true);
|
||
|
|
```
|
||
|
|
|
||
|
|
### `BetterCurseForge.plugins` (`PluginManager`)
|
||
|
|
Provides programmatic control over plugins:
|
||
|
|
|
||
|
|
```javascript
|
||
|
|
// Get all installed plugins
|
||
|
|
const plugins = BetterCurseForge.plugins.getPlugins();
|
||
|
|
|
||
|
|
// Toggle a plugin by folder name
|
||
|
|
await BetterCurseForge.plugins.togglePlugin('compact-mode');
|
||
|
|
```
|
||
|
|
|
||
|
|
### `BetterCurseForge.ads` (`AdBlocker`)
|
||
|
|
Internal ad blocker runtime:
|
||
|
|
|
||
|
|
```javascript
|
||
|
|
// Contains zero-ad CSS rules and ad container cleanup handlers
|
||
|
|
console.log(BetterCurseForge.ads);
|
||
|
|
```
|