mudlet-map-binary-reader
Version:
Reads and writes Mudlet's map binary file (v20), with read-only support for older formats (v16-v19). Can output .js files needed for Mudlet Map Reader.
301 lines • 11 kB
TypeScript
//#region src/types.d.ts
/** Top-level Mudlet map model as stored in the binary map file. */
interface MudletMap {
version: number;
envColors: Record<number, number>;
areaNames: Record<number, string>;
mCustomEnvColors: Record<number, MudletColor>;
mpRoomDbHashToRoomId: Record<string, number>;
mUserData: Record<string, string>;
mapSymbolFont: MudletFont;
mapFontFudgeFactor: number;
useOnlyMapFont: boolean;
areas: Record<number, MudletArea>;
mRoomIdHash: Record<string, number>;
labels: Record<number, MudletLabel[]>;
rooms: Record<number, MudletRoom>;
}
/**
* Every top-level {@link MudletMap} field except `rooms`. Produced by
* streaming reads (see `streamRooms`) so callers get area/label/colour
* metadata without the rooms ever being collected into memory at once.
*/
type MudletMapHeader = Omit<MudletMap, 'rooms'>;
/** A single area containing rooms, spatial bounds, and per-Z-level extents. */
interface MudletArea {
rooms: number[];
zLevels: number[];
mAreaExits: Record<number, [number, number][]>;
gridMode: boolean;
max_x: number;
max_y: number;
max_z: number;
min_x: number;
min_y: number;
min_z: number;
span: [number, number, number];
xmaxForZ: Record<number, number>;
ymaxForZ: Record<number, number>;
xminForZ: Record<number, number>;
yminForZ: Record<number, number>;
pos: [number, number, number];
isZone: boolean;
zoneAreaRef: number;
userData: Record<string, string>;
}
/** A single room with coordinates, exits, custom lines, and user data. */
interface MudletRoom {
area: number;
x: number;
y: number;
z: number;
north: number;
northeast: number;
east: number;
southeast: number;
south: number;
southwest: number;
west: number;
northwest: number;
up: number;
down: number;
in: number;
out: number;
environment: number;
weight: number;
name: string;
isLocked: boolean;
rawSpecialExits?: Record<number, string[]>;
mSpecialExits: Record<string, number>;
mSpecialExitLocks: number[];
symbol: string;
userData: Record<string, string>;
customLines: Record<string, [number, number][]>;
customLinesArrow: Record<string, boolean>;
customLinesColor: Record<string, MudletColor>;
customLinesStyle: Record<string, number>;
exitLocks: number[];
stubs: number[];
exitWeights: Record<string, number>;
doors: Record<string, number>;
hash?: string;
}
/** A text/image label placed on the map at a specific position and size. */
interface MudletLabel {
id: number;
labelId?: number;
areaId?: number;
pos: [number, number, number];
dummy1?: number;
dummy2?: number;
size: [number, number];
text: string;
fgColor: MudletColor;
bgColor: MudletColor;
pixMap: Uint8Array | string;
noScaling: boolean;
showOnTop: boolean;
}
/** An RGBA color as stored by Qt's QColor (spec-qualified). */
interface MudletColor {
spec: number;
alpha: number;
r: number;
g: number;
b: number;
pad?: number;
}
/** A font descriptor as stored by Qt's QFont (QDataStream v5.12 layout). */
interface MudletFont {
family: string;
style: string;
pointSize: number;
pixelSize: number;
styleHint: number;
styleStrategy: number;
weight: number;
fontBits: number;
stretch: number;
extendedFontBits: number;
letterSpacing: number;
wordSpacing: number;
hintingPreference: number;
capital: number;
styleSetting: boolean;
underline: boolean;
overline: boolean;
strikeOut: boolean;
fixedPitch: boolean;
kerning: boolean;
styleOblique: boolean;
ignorePitch: boolean;
letterSpacingIsAbsolute: boolean;
}
//#endregion
//#region src/map-operations.d.ts
/**
* Parse a Mudlet binary map from an in-memory buffer. Environment-
* independent: no `fs`, no file path. Callers in Node can pass
* `fs.readFileSync(path)`; callers in the browser can pass a `Buffer`
* constructed from a `File` / `ArrayBuffer`.
*
* The format version (the first int in the stream) selects the model. An
* unsupported version fails fast with a clear error rather than silently
* mis-parsing a layout it doesn't match (reading a v16 map as v20 desyncs the
* stream and dies with an opaque "Invalid array length").
*/
declare function readMapFromBuffer$1(buf: Uint8Array): MudletMap;
/**
* Stream a Mudlet binary map room-by-room without ever holding the whole
* room graph in memory. Decodes the (small) header sections eagerly — areas,
* labels, colours, names — then walks the trailing rooms blob, invoking
* `onRoom(id, room)` for each room and discarding it as soon as the callback
* returns. Peak memory is therefore `buffer + one room`, not the multi-GB
* fully-materialised object graph that {@link readMapFromBuffer} builds.
*
* This is the building block for chunking/packing very large maps (260 MB+)
* that cannot be loaded whole. The format is strictly sequential with no
* index, so this still reads every byte once — but it does not accumulate.
* Supported for every version {@link readMapFromBuffer} supports (v16-v20);
* an unsupported version throws the same error `readMapFromBuffer` would.
*
* Each emitted room has its `mSpecialExits` / `mSpecialExitLocks` hydrated,
* matching {@link readMapFromBuffer}. The per-room content `hash` is NOT set
* (it lives in the header's `mpRoomDbHashToRoomId` index, returned here so a
* caller can resolve hashes itself if needed).
*
* `onHeader`, if given, is invoked with the decoded header *before* the room
* loop begins. The rooms section itself is unframed (no count), but every
* area's `rooms` id-list is in the header, so a caller can sum them there to
* learn the total room count up front (e.g. for a progress bar / preallocation).
*
* @returns the map header (everything except `rooms`).
*/
declare function streamRooms$1(buf: Uint8Array, onRoom: (id: number, room: MudletRoom) => void, onHeader?: (header: MudletMapHeader) => void): MudletMapHeader;
/**
* Serialise a map model to a Mudlet binary buffer. Environment-
* independent: no `fs`. Node callers persist with
* `fs.writeFileSync(path, writeMapToBuffer(map))`; browser callers can
* hand it to a `Blob` or HTTP response.
*/
declare function writeMapToBuffer$1(map: MudletMap): Uint8Array;
//#endregion
//#region src/reader-export.d.ts
/** RGB color for the JS Mudlet Map Renderer. */
interface RendererColor {
r: number;
g: number;
b: number;
}
/** A custom line between rooms, with waypoints and visual attributes. */
interface RendererCustomLine {
points: {
x: number;
y: number;
}[];
attributes: {
color: RendererColor;
style: string;
arrow: boolean;
};
}
/**
* A room as consumed by the JS Mudlet Map Renderer.
*
* Preserves every field from {@link MudletRoom} (`x`, `y`, `z`, `weight`, `name`,
* `userData`, `doors`, `exitLocks`, `stubs`, `exitWeights`, `mSpecialExitLocks`,
* `isLocked`, …) and only remaps the per-direction exits, special exits, custom lines,
* environment, and symbol fields.
*/
type RendererRoom = Omit<MudletRoom, 'north' | 'northeast' | 'east' | 'southeast' | 'south' | 'southwest' | 'west' | 'northwest' | 'up' | 'down' | 'in' | 'out' | 'environment' | 'symbol' | 'mSpecialExits' | 'customLines' | 'customLinesArrow' | 'customLinesColor' | 'customLinesStyle' | 'hash'> & {
id: number;
env?: number;
roomChar?: string;
exits: Record<string, number>;
specialExits: Record<string, number>;
customLines: Record<string, RendererCustomLine>;
hash?: string;
};
/**
* A map label as consumed by the JS Mudlet Map Renderer.
*
* Preserves every field from {@link MudletLabel} (`id`, `areaId`, `labelId`, …) other than
* the ones that are renamed (`pos` → X/Y/Z, `size` → Width/Height, `text` → Text,
* `fgColor`/`bgColor` → FgColor/BgColor) or dropped (`dummy1`, `dummy2`).
* `pixMap` is always base64-encoded inline.
*/
type RendererLabel = Omit<MudletLabel, 'pos' | 'size' | 'text' | 'fgColor' | 'bgColor' | 'dummy1' | 'dummy2' | 'pixMap'> & {
X: number;
Y: number;
Z: number;
Width: number;
Height: number;
Text: string;
FgColor: Omit<MudletColor, 'spec' | 'pad'>;
BgColor: Omit<MudletColor, 'spec' | 'pad'>;
pixMap: string;
};
/** An area with its rooms and labels, formatted for the JS Mudlet Map Renderer. */
interface RendererArea {
areaName: string;
areaId: string;
rooms: RendererRoom[];
labels: RendererLabel[];
}
/** Complete renderer export: map data (areas/rooms/labels) and environment color palette. */
interface RendererExport {
mapData: RendererArea[];
colors: {
envId: number;
colors: number[];
}[];
}
/** Convert a single room to the renderer shape (also used by streaming consumers). */
declare function convertRoom$1(roomId: number, room: MudletRoom, hash?: string): RendererRoom;
/** Convert a single label to the renderer shape (also used by streaming consumers). */
declare function convertLabel$1(label: MudletLabel): RendererLabel;
/**
* Exports model into format understandable by JS Mudlet Map Renderer - https://github.com/Delwing/js-mudlet-map-renderer
*
* @param mapModel - the Mudlet map model
* @param directory - directory path; if provided, writes export as .js and .json files
* @returns exported map data and colors
*/
/**
* Build the renderer-ready export (`{ mapData, colors }`) from a Mudlet map
* model. Pure: returns the data, never touches disk. Persist with your
* tool of choice (`fs.writeFileSync`, a `Blob`, an HTTP response, …).
*/
declare function readerExport$1(mapModel: MudletMap): RendererExport;
//#endregion
//#region src/json-export.d.ts
/**
* Convert a map model to the Mudlet JSON export format.
*
* Pure: returns the JSON string. Persist it with your tool of choice.
*
* @param map - the Mudlet map model
* @param minified - if true, JSON is emitted without indentation
*/
declare function exportMap$1(map: MudletMap, minified?: boolean): string;
//#endregion
//#region src/index.d.ts
declare const readMapFromBuffer: typeof readMapFromBuffer$1;
declare const writeMapToBuffer: typeof writeMapToBuffer$1;
declare const streamRooms: typeof streamRooms$1;
declare const readerExport: typeof readerExport$1;
/** Per-room / per-label converters to the renderer shape (for streaming consumers). */
declare const convertRoom: typeof convertRoom$1;
declare const convertLabel: typeof convertLabel$1;
declare const exportMap: typeof exportMap$1;
/** Convenience namespace for reading, writing, and exporting Mudlet map files. */
declare const MudletMapReader: {
readBuffer: typeof readMapFromBuffer$1;
writeBuffer: typeof writeMapToBuffer$1;
streamRooms: typeof streamRooms$1;
export: typeof readerExport$1;
exportJson: typeof exportMap$1;
};
//#endregion
export { MudletArea, MudletColor, MudletFont, MudletLabel, MudletMap, MudletMapHeader, MudletMapReader, MudletRoom, type RendererLabel, type RendererRoom, convertLabel, convertRoom, exportMap, readMapFromBuffer, readerExport, streamRooms, writeMapToBuffer };
//# sourceMappingURL=index.d.ts.map