Some checks are pending
Build Windows Executable / Build BetterCurseForge.exe (push) Waiting to run
Deploy Documentation / build (push) Waiting to run
Deploy Documentation / deploy (push) Blocked by required conditions
261 lines
6.6 KiB
Markdown
261 lines
6.6 KiB
Markdown
# API Reference
|
|
|
|
BetterCurseForge adds a global object, `window.BetterCurseForge`, to CurseForge's Electron renderer process. Themes, plugins and your own scripts can use it to inject styles, patch methods, read and write settings, and listen for events.
|
|
|
|
---
|
|
|
|
## TypeScript definitions
|
|
|
|
If you're using TypeScript, this gives you types 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**: Version of the BetterCurseForge runtime that's currently running.
|
|
|
|
```javascript
|
|
console.log(BetterCurseForge.version); // "1.0.0"
|
|
```
|
|
|
|
---
|
|
|
|
### `BetterCurseForge.injectCSS(css)`
|
|
|
|
Adds CSS rules to the document `<head>`.
|
|
|
|
- **Parameters**:
|
|
- `css` *(string)*: The CSS to inject.
|
|
- **Returns**: `() => void`. Call it to remove the injected `<style>` tag.
|
|
|
|
```javascript
|
|
// Inject styles
|
|
const uninject = BetterCurseForge.injectCSS(`
|
|
.some-container {
|
|
background-color: #1a102f !important;
|
|
}
|
|
`);
|
|
|
|
// Later, remove the styles
|
|
uninject();
|
|
```
|
|
|
|
---
|
|
|
|
## Settings API (`BetterCurseForge.settings`)
|
|
|
|
Persistent configuration, stored in `%APPDATA%\CurseForge\BetterCurseForge\settings.json`.
|
|
|
|
### `settings.get(key?)`
|
|
|
|
Returns the setting for `key`, or the whole settings object if you don't pass a key.
|
|
|
|
- **Parameters**:
|
|
- `key` *(string, optional)*: Name of the setting.
|
|
- **Returns**: `Promise<any>`. The value, or `null` if it isn't set.
|
|
|
|
```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)`
|
|
|
|
Saves a value and writes it to disk asynchronously.
|
|
|
|
- **Parameters**:
|
|
- `key` *(string)*: Name of the setting.
|
|
- `value` *(any)*: Any JSON-serializable value.
|
|
- **Returns**: `Promise<boolean>`. `true` if the save worked.
|
|
|
|
```javascript
|
|
await BetterCurseForge.settings.set('myPlugin.fontSize', 14);
|
|
```
|
|
|
|
---
|
|
|
|
## Patcher API (`BetterCurseForge.patcher`)
|
|
|
|
Utilities for inspecting, modifying or replacing methods on JavaScript objects and modules. Every function returns an unpatch function.
|
|
|
|
### `patcher.before(obj, method, callback)`
|
|
|
|
Runs `callback(args)` **before** the target method is called.
|
|
|
|
- **Parameters**:
|
|
- `obj` *(object)*: Target object.
|
|
- `method` *(string)*: Method name on `obj`.
|
|
- `callback` *(Function)*: `(args) => void`.
|
|
- **Returns**: `() => void`. Call it to restore 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)`
|
|
|
|
Runs `callback(args, result)` **after** the target method. Return a 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)`
|
|
|
|
Replaces the target method. The callback gets the 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 has an event bus that plugins can use to talk to each other and to react to lifecycle events.
|
|
|
|
### `BetterCurseForge.on(event, callback)`
|
|
Adds a listener for an event.
|
|
|
|
```javascript
|
|
const onReady = () => console.log('BetterCurseForge is ready!');
|
|
BetterCurseForge.on('ready', onReady);
|
|
```
|
|
|
|
### `BetterCurseForge.off(event, callback)`
|
|
Removes a listener.
|
|
|
|
```javascript
|
|
BetterCurseForge.off('ready', onReady);
|
|
```
|
|
|
|
### `BetterCurseForge.emit(event, ...args)`
|
|
Calls every listener registered for the event.
|
|
|
|
```javascript
|
|
BetterCurseForge.emit('custom-event', { detail: 123 });
|
|
```
|
|
|
|
---
|
|
|
|
## Subsystem managers
|
|
|
|
### `BetterCurseForge.themes` (`ThemeManager`)
|
|
Control custom themes from code:
|
|
|
|
```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`)
|
|
Control plugins from code:
|
|
|
|
```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`)
|
|
The internal ad blocker runtime:
|
|
|
|
```javascript
|
|
// Contains zero-ad CSS rules and ad container cleanup handlers
|
|
console.log(BetterCurseForge.ads);
|
|
```
|