@mudlet/mudlet-web 0.3.0 → 0.4.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +338 -338
- package/README.md +158 -150
- package/dist-lib/assets/qt-resources/index.d.ts +16 -0
- package/dist-lib/branding.d.ts +1 -1
- package/dist-lib/hooks/useMudSession.d.ts +1 -1
- package/dist-lib/hooks/useOutput.d.ts +3 -1
- package/dist-lib/import/defaultPackages.d.ts +35 -2
- package/dist-lib/import/defaults/generic_mapper/generic_mapper.mpackage +0 -0
- package/dist-lib/import/defaults/gui-drop/gui-drop.mpackage +0 -0
- package/dist-lib/import/defaults/{run-lua-code.mpackage → mudlet-base-ui/mudlet-base-ui.mpackage} +0 -0
- package/dist-lib/import/defaults/mudlet-mapper.xml +13023 -13023
- package/dist-lib/import/defaults/run-lua-code/run-lua-code.mpackage +0 -0
- package/dist-lib/import/packageExport.d.ts +71 -0
- package/dist-lib/import/packageInstaller.d.ts +4 -1
- package/dist-lib/index.js +45910 -39931
- package/dist-lib/logging/SessionLogger.d.ts +66 -1
- package/dist-lib/map/MapStore.d.ts +32 -4
- package/dist-lib/map/mapImageExport.d.ts +1 -1
- package/dist-lib/map/mapZoom.d.ts +71 -0
- package/dist-lib/mud/ItemIdSequence.d.ts +23 -0
- package/dist-lib/mud/MudSession.d.ts +113 -11
- package/dist-lib/mud/PatternEngine.d.ts +6 -1
- package/dist-lib/mud/commandSplit.d.ts +16 -0
- package/dist-lib/mud/connection/LineAssembler.d.ts +56 -0
- package/dist-lib/mud/connection/MudClient.d.ts +136 -19
- package/dist-lib/mud/connection/TelnetNegotiator.d.ts +39 -0
- package/dist-lib/mud/connection/telnetByteTags.d.ts +35 -0
- package/dist-lib/mud/events.d.ts +86 -4
- package/dist-lib/mud/games/bundledGames.d.ts +29 -0
- package/dist-lib/mud/games/gameIcons.d.ts +5 -0
- package/dist-lib/mud/keybindings/KeyEngine.d.ts +9 -2
- package/dist-lib/mud/keybindings/browserReservedKeys.d.ts +5 -1
- package/dist-lib/mud/keybindings/keyEventTarget.d.ts +17 -0
- package/dist-lib/mud/keybindings/qtKeys.d.ts +2 -0
- package/dist-lib/mud/protocol/charLoginFlow.d.ts +68 -0
- package/dist-lib/mud/protocol/charset.d.ts +27 -5
- package/dist-lib/mud/protocol/constants.d.ts +1 -0
- package/dist-lib/mud/protocol/gmcp.d.ts +19 -3
- package/dist-lib/mud/protocol/index.d.ts +1 -1
- package/dist-lib/mud/protocol/msspTls.d.ts +54 -0
- package/dist-lib/mud/protocol/mxp.d.ts +28 -5
- package/dist-lib/mud/protocol/tlsCodes.d.ts +4 -0
- package/dist-lib/mud/replay/ReplayPlayer.d.ts +17 -0
- package/dist-lib/mud/text/Console.d.ts +64 -0
- package/dist-lib/mud/text/FormatState.d.ts +66 -3
- package/dist-lib/mud/text/hyperlinkVisibility.d.ts +35 -0
- package/dist-lib/mud/text/osc8Docs.d.ts +23 -0
- package/dist-lib/mud/text/serverWrap.d.ts +191 -0
- package/dist-lib/mud/timers/TimerEngine.d.ts +43 -12
- package/dist-lib/mud/triggers/TriggerEngine.d.ts +112 -3
- package/dist-lib/scripting/EngineHost.d.ts +56 -3
- package/dist-lib/scripting/IScriptingRuntime.d.ts +22 -0
- package/dist-lib/scripting/MxpFrameManager.d.ts +118 -0
- package/dist-lib/scripting/ScriptingAPI.d.ts +331 -54
- package/dist-lib/scripting/ScriptingEngine.d.ts +181 -24
- package/dist-lib/scripting/http/HttpService.d.ts +51 -1
- package/dist-lib/scripting/lua/LuaRuntime.d.ts +159 -2
- package/dist-lib/scripting/lua/bindings/map.d.ts +0 -12
- package/dist-lib/scripting/lua/utf8Patterns.d.ts +59 -0
- package/dist-lib/storage/index.d.ts +1 -1
- package/dist-lib/storage/persistentStorage.d.ts +10 -0
- package/dist-lib/storage/schema.d.ts +166 -4
- package/dist-lib/styles.css +1 -1
- package/dist-lib/ui/BundledGameGrid.d.ts +21 -0
- package/dist-lib/ui/CharLoginModal.d.ts +5 -1
- package/dist-lib/ui/CommandBar.d.ts +7 -1
- package/dist-lib/ui/ConnectionGrid.d.ts +4 -1
- package/dist-lib/ui/FileBrowserModal.d.ts +1 -0
- package/dist-lib/ui/FilePickerModal.d.ts +3 -3
- package/dist-lib/ui/HelpModal.d.ts +11 -0
- package/dist-lib/ui/LogBrowserModal.d.ts +4 -1
- package/dist-lib/ui/PlayerMarkerPreview.d.ts +20 -0
- package/dist-lib/ui/SettingsModal.d.ts +5 -1
- package/dist-lib/ui/TlsAlertBanner.d.ts +18 -0
- package/dist-lib/ui/TlsCertificateBox.d.ts +20 -0
- package/dist-lib/ui/TlsUpgradeModal.d.ts +16 -0
- package/dist-lib/ui/Toolbar.d.ts +2 -1
- package/dist-lib/ui/VfsPickerModal.d.ts +26 -0
- package/dist-lib/ui/components/FileSourceButton.d.ts +47 -0
- package/dist-lib/ui/components/index.d.ts +1 -0
- package/dist-lib/ui/components/useModalFocus.d.ts +6 -0
- package/dist-lib/ui/helpTopics.d.ts +19 -0
- package/dist-lib/ui/labels/LabelManager.d.ts +32 -0
- package/dist-lib/ui/labels/labelLinks.d.ts +52 -0
- package/dist-lib/ui/layout/ScriptWindow.d.ts +11 -2
- package/dist-lib/ui/markdown.d.ts +10 -1
- package/dist-lib/ui/output/OutputArea.d.ts +11 -1
- package/dist-lib/ui/output/OutputContextMenu.d.ts +3 -1
- package/dist-lib/ui/output/OutputRenderer.d.ts +7 -1
- package/dist-lib/ui/output/OutputSearchBar.d.ts +25 -0
- package/dist-lib/ui/output/StickyOutputPanel.d.ts +5 -1
- package/dist-lib/ui/output/linkNavigation.d.ts +22 -0
- package/dist-lib/ui/output/outputSearch.d.ts +130 -0
- package/dist-lib/ui/search/matcher.d.ts +15 -0
- package/dist-lib/ui/search/useDebounced.d.ts +3 -0
- package/dist-lib/ui/tts/TtsManager.d.ts +3 -0
- package/dist-lib/ui/useCommandHistory.d.ts +4 -2
- package/dist-lib/ui/useOpenProfiles.d.ts +26 -0
- package/dist-lib/ui/video/VideoManager.d.ts +17 -0
- package/dist-lib/ui/windows/WindowManager.d.ts +149 -2
- package/dist-lib/ui/windows/panels/MapPanel.d.ts +4 -1
- package/dist-lib/ui/windows/panels/PackageExportModal.d.ts +18 -0
- package/dist-lib/ui/windows/panels/TextPanel.d.ts +3 -1
- package/dist-lib/ui/windows/types.d.ts +35 -0
- package/dist-lib/utils/describeThrown.d.ts +22 -0
- package/dist-lib/utils/fontLoader.d.ts +5 -0
- package/dist-lib/vfs-sw.js +131 -131
- package/dist-lib/vite.js +22 -0
- package/package.json +97 -93
- package/dist-lib/scripting/lua/mudlet-lua/generic-mapper/generic_mapper.mpackage +0 -0
- package/dist-lib/ui/windows/panels/VfsModulePickerModal.d.ts +0 -8
|
@@ -1,4 +1,20 @@
|
|
|
1
1
|
import type { MudSession } from '../mud/MudSession';
|
|
2
|
+
/**
|
|
3
|
+
* How the file log is written. Mudlet's `logInHTML` picks between two genuinely
|
|
4
|
+
* different documents, and the HTML one has to name the console's own font and
|
|
5
|
+
* background — neither of which the logger can see for itself.
|
|
6
|
+
*/
|
|
7
|
+
export interface LogFormat {
|
|
8
|
+
html: boolean;
|
|
9
|
+
/** Resolved console font family, the one `getFont()` reports. */
|
|
10
|
+
font?: string;
|
|
11
|
+
/** Console background, painted behind the whole document as Mudlet does. */
|
|
12
|
+
background?: {
|
|
13
|
+
r: number;
|
|
14
|
+
g: number;
|
|
15
|
+
b: number;
|
|
16
|
+
};
|
|
17
|
+
}
|
|
2
18
|
/**
|
|
3
19
|
* Records one gameplay session to IndexedDB. Subscribes to the session's
|
|
4
20
|
* `message` event — the single choke point every line of output passes
|
|
@@ -14,9 +30,19 @@ export declare class SessionLogger {
|
|
|
14
30
|
private readonly session;
|
|
15
31
|
private readonly connectionId;
|
|
16
32
|
private readonly connectionName;
|
|
33
|
+
/** Profile filesystem the plain-text log is written into. Optional: the
|
|
34
|
+
* IndexedDB record is the primary log and works without one. */
|
|
35
|
+
private readonly vfs?;
|
|
17
36
|
private readonly sessionId;
|
|
18
37
|
private readonly startedAt;
|
|
19
38
|
private buffer;
|
|
39
|
+
/** Absolute VFS path of the plain-text log, or null when there is no VFS to
|
|
40
|
+
* write one into. See {@link openLogFile}. */
|
|
41
|
+
private logFilePath;
|
|
42
|
+
/** Lines written to the text log but not yet flushed to the VFS. Kept
|
|
43
|
+
* separate from `buffer` (the IndexedDB batch) because the two flush on
|
|
44
|
+
* different triggers and the text log has to survive an IDB failure. */
|
|
45
|
+
private fileBuffer;
|
|
20
46
|
private seq;
|
|
21
47
|
private totalCount;
|
|
22
48
|
private flushTimer;
|
|
@@ -24,8 +50,47 @@ export declare class SessionLogger {
|
|
|
24
50
|
private sessionCreated;
|
|
25
51
|
/** Serializes flushes so a size-triggered flush can't race the timer. */
|
|
26
52
|
private flushing;
|
|
27
|
-
constructor(session: MudSession, connectionId: string, connectionName: string
|
|
53
|
+
constructor(session: MudSession, connectionId: string, connectionName: string,
|
|
54
|
+
/** Profile filesystem the plain-text log is written into. Optional: the
|
|
55
|
+
* IndexedDB record is the primary log and works without one. */
|
|
56
|
+
vfs?: {
|
|
57
|
+
profilePath: string;
|
|
58
|
+
mkdir(p: string): void;
|
|
59
|
+
writeFile(p: string, c: string): void;
|
|
60
|
+
exists(p: string): boolean;
|
|
61
|
+
readFile(p: string): string;
|
|
62
|
+
} | null | undefined);
|
|
28
63
|
start(): void;
|
|
64
|
+
/** Where this session's plain-text log is being written, or null when the
|
|
65
|
+
* file log is off. Backs Mudlet's `startLogging` path return. */
|
|
66
|
+
get filePath(): string | null;
|
|
67
|
+
/**
|
|
68
|
+
* Mudlet's `startLogging(true)` — begin mirroring output to a file as well.
|
|
69
|
+
* Deliberately separate from {@link start}: recording to the log browser is
|
|
70
|
+
* a mudix profile setting that is on by default, whereas Mudlet's file log
|
|
71
|
+
* is something a player or script asks for. Sharing one switch would have
|
|
72
|
+
* every profile quietly writing a file nobody asked for, and would make
|
|
73
|
+
* `startLogging(true)` report "already on" for ever.
|
|
74
|
+
*
|
|
75
|
+
* The file is created up front, before any line has arrived, so a script can
|
|
76
|
+
* hand its path straight to something else. Named as Mudlet names its own:
|
|
77
|
+
* `<profile>/log/<yyyy-MM-dd#hh-mm-ss>.txt` — or `.html` when `format.html`
|
|
78
|
+
* is set (Mudlet's `logInHTML`), which is a whole second document format
|
|
79
|
+
* rather than the same lines with markup: a `<html>` wrapper, a stylesheet
|
|
80
|
+
* naming the console's own font and background, and a closing tag pair only
|
|
81
|
+
* {@link stopFileLog} writes.
|
|
82
|
+
*/
|
|
83
|
+
startFileLog(format?: LogFormat): string | null;
|
|
84
|
+
/** Stop mirroring to the file, writing out whatever is buffered — and, for
|
|
85
|
+
* an HTML log, the closing tags that make it a document. */
|
|
86
|
+
stopFileLog(): void;
|
|
87
|
+
/** Whether the open file log is HTML rather than plain text. */
|
|
88
|
+
private logHtml;
|
|
89
|
+
private openLogFile;
|
|
90
|
+
/** Append the buffered lines to the log file. ZenFS has no
|
|
91
|
+
* append mode we can rely on across both backends, so this re-writes the
|
|
92
|
+
* file with the new tail — hence the buffering. */
|
|
93
|
+
private flushLogFile;
|
|
29
94
|
private capture;
|
|
30
95
|
/**
|
|
31
96
|
* Mudlet `appendLog(text)` — append an arbitrary line to the current log,
|
|
@@ -168,6 +168,7 @@ export declare class MapStore {
|
|
|
168
168
|
profileName: string;
|
|
169
169
|
private mapEventDispatcher;
|
|
170
170
|
private mapInfoContributors;
|
|
171
|
+
private pendingMapInfoEnabled;
|
|
171
172
|
private builtinMapInfo;
|
|
172
173
|
private mapInfoEvaluator;
|
|
173
174
|
constructor();
|
|
@@ -232,6 +233,14 @@ export declare class MapStore {
|
|
|
232
233
|
* adding rooms). Returns true.
|
|
233
234
|
*/
|
|
234
235
|
deleteMap(): boolean;
|
|
236
|
+
/**
|
|
237
|
+
* Mudlet `T2DMap::slot_newMap` — the mapper's "Create new map" action,
|
|
238
|
+
* offered when the profile has no map at all. Wipes to a fresh empty map
|
|
239
|
+
* and seeds it with a single room at the origin of the default area (-1),
|
|
240
|
+
* marked as the player's position so the marker and the opening view both
|
|
241
|
+
* land on it. Returns the new room's id.
|
|
242
|
+
*/
|
|
243
|
+
createNewMap(): number;
|
|
235
244
|
toRendererData(): MapRendererData | null;
|
|
236
245
|
/**
|
|
237
246
|
* Mudlet `saveJsonMap(path)` backbone — serialise the entire MapStore as a
|
|
@@ -707,9 +716,15 @@ export declare class MapStore {
|
|
|
707
716
|
searchAreaUserData(key?: string, value?: string): string[] | number[];
|
|
708
717
|
/**
|
|
709
718
|
* Per-area 2D-map zoom stored in the map file (area userData under
|
|
710
|
-
* {@link AREA_ZOOM_KEY}). Returns `undefined` when the area
|
|
711
|
-
* no saved zoom
|
|
712
|
-
* zoom as map data
|
|
719
|
+
* {@link AREA_ZOOM_KEY}), in Mudlet units. Returns `undefined` when the area
|
|
720
|
+
* is missing or has no usable saved zoom, in which case the caller opens at
|
|
721
|
+
* {@link DEFAULT_MAP_ZOOM}. Mirrors Mudlet's treatment of zoom as map data
|
|
722
|
+
* rather than client config.
|
|
723
|
+
*
|
|
724
|
+
* A value below {@link MIN_MAP_ZOOM} is treated as absent, exactly as
|
|
725
|
+
* TMap::restore does with the same key — it can only come from a corrupt or
|
|
726
|
+
* foreign write, and honouring it would open the area zoomed in past the
|
|
727
|
+
* limit the wheel itself enforces.
|
|
713
728
|
*/
|
|
714
729
|
getAreaZoom(id: number): number | undefined;
|
|
715
730
|
/**
|
|
@@ -719,7 +734,10 @@ export declare class MapStore {
|
|
|
719
734
|
* handler calls this on every wheel tick; notifying would rebuild the whole
|
|
720
735
|
* scene on each one. The value persists to IndexedDB the next time the map is
|
|
721
736
|
* serialised (saveMap → toMudletMapForSave). Returns false when the area is
|
|
722
|
-
* missing or the zoom
|
|
737
|
+
* missing or the zoom is below {@link MIN_MAP_ZOOM} — TArea::set2DMapZoom
|
|
738
|
+
* silently ignores those too, and the floor is what stops a bad reading (a
|
|
739
|
+
* fit computed against a not-yet-laid-out 0×0 panel, say) from being written
|
|
740
|
+
* out and then restored on every subsequent open.
|
|
723
741
|
*/
|
|
724
742
|
setAreaZoom(id: number, zoom: number): boolean;
|
|
725
743
|
/**
|
|
@@ -892,6 +910,16 @@ export declare class MapStore {
|
|
|
892
910
|
};
|
|
893
911
|
enableMapInfo(label: string): boolean;
|
|
894
912
|
disableMapInfo(label: string): boolean;
|
|
913
|
+
/** Mudlet `setConfig("showMapInfo", label)` — switch a map-info overlay on.
|
|
914
|
+
* Unlike `enableMapInfo`, an unknown label is *not* an error: Mudlet inserts
|
|
915
|
+
* the name straight into `mMapInfoContributors` without consulting the
|
|
916
|
+
* registry, so the overlay lights up if and when something registers under
|
|
917
|
+
* that label. Always succeeds, matching setConfig's unconditional success. */
|
|
918
|
+
showMapInfo(label: string): void;
|
|
919
|
+
/** Mudlet `setConfig("hideMapInfo", label)` — switch a map-info overlay off.
|
|
920
|
+
* Clears a pending enable as well, so hiding a label that was turned on
|
|
921
|
+
* before its contributor existed actually cancels it. */
|
|
922
|
+
hideMapInfo(label: string): void;
|
|
895
923
|
/** Snapshot for tests / debug. The panel goes through evaluateMapInfos. */
|
|
896
924
|
getMapInfoContributors(): MapInfoContributor[];
|
|
897
925
|
/** Run every enabled contributor and collect their (text, style, color)
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import type { Settings as MapRendererSettings } from 'mudlet-map-renderer';
|
|
2
2
|
import type { MapStore } from './MapStore';
|
|
3
|
-
import type
|
|
3
|
+
import { type MapperSettings } from '../storage/schema';
|
|
4
4
|
/**
|
|
5
5
|
* Copy user-set fields from MapperSettings onto a live renderer settings
|
|
6
6
|
* object. Anything left undefined in `mapper` is intentionally not touched
|
|
@@ -0,0 +1,71 @@
|
|
|
1
|
+
import type { MapRenderer } from 'mudlet-map-renderer';
|
|
2
|
+
/**
|
|
3
|
+
* Map-view zoom: the two units it comes in, and the policy for opening an area.
|
|
4
|
+
*
|
|
5
|
+
* Two different numbers are both called "zoom", and mixing them is what made
|
|
6
|
+
* maps open absurdly far in or out:
|
|
7
|
+
*
|
|
8
|
+
* - **renderer zoom** — a scale multiplier; `camera.getScale() === BASE_SCALE *
|
|
9
|
+
* zoom` is the pixels drawn per map unit. Bigger = zoomed in. A pure renderer
|
|
10
|
+
* concept that only means anything paired with the current viewport size.
|
|
11
|
+
* - **Mudlet zoom** — how many map units the *shorter* viewport edge spans
|
|
12
|
+
* (T2DMap's `xyzoom`: 3 → 3 rooms across, 100 → ~100). Bigger = zoomed *out*.
|
|
13
|
+
* This is what `getMapZoom`/`setMapZoom` speak and what gets persisted into
|
|
14
|
+
* the map file, because it survives the panel being a different size in a
|
|
15
|
+
* later session.
|
|
16
|
+
*
|
|
17
|
+
* Everything outside the renderer is in Mudlet units; {@link toMudletZoom} and
|
|
18
|
+
* {@link toRendererZoom} convert at that boundary.
|
|
19
|
+
*/
|
|
20
|
+
/** Mudlet's hard floor for the 2D map zoom (T2DMap `csmMinXYZoom`): the shorter
|
|
21
|
+
* viewport edge may never span fewer than this many map units, i.e. you can't
|
|
22
|
+
* zoom in any closer. Mirrored so wheel/pinch zoom obeys the same limit. */
|
|
23
|
+
export declare const MUDLET_MIN_MAP_ZOOM = 3;
|
|
24
|
+
/** Mudlet's `T2DMap::csmDefaultXYZoom` — what an area opens at when it has no
|
|
25
|
+
* remembered zoom of its own. */
|
|
26
|
+
export declare const MUDLET_DEFAULT_MAP_ZOOM = 20;
|
|
27
|
+
/** How far past "the whole area exactly fills the panel" the user may keep
|
|
28
|
+
* zooming out. The renderer's `fitToMapBounds` ends with `minZoom = zoom`, so
|
|
29
|
+
* every `fitArea()` pins the zoom-out floor to that exact fit — the wheel then
|
|
30
|
+
* stops dead with the area flush against the panel edges, and there's no way
|
|
31
|
+
* to pull back for context or to see where an area sits relative to its
|
|
32
|
+
* surroundings. Relaxing the floor afterwards restores that headroom. */
|
|
33
|
+
export declare const ZOOM_OUT_HEADROOM = 4;
|
|
34
|
+
/**
|
|
35
|
+
* The renderer's current view expressed in Mudlet units, or null when the camera
|
|
36
|
+
* has no usable size yet.
|
|
37
|
+
*
|
|
38
|
+
* A panel that hasn't been laid out reports 0×0, and a "zoom" derived from that
|
|
39
|
+
* is meaningless — persisting one is exactly how an area got stuck at a few
|
|
40
|
+
* pixels per room on every subsequent open.
|
|
41
|
+
*/
|
|
42
|
+
export declare function toMudletZoom(renderer: MapRenderer): number | null;
|
|
43
|
+
/**
|
|
44
|
+
* The renderer zoom that makes `mudletZoom` map units span the shorter viewport
|
|
45
|
+
* edge, or null when the camera isn't sized (see {@link toMudletZoom}) or the
|
|
46
|
+
* request isn't a positive number.
|
|
47
|
+
*/
|
|
48
|
+
export declare function toRendererZoom(renderer: MapRenderer, mudletZoom: number): number | null;
|
|
49
|
+
/** Fit the area, then relax the floor the fit just pinned (see
|
|
50
|
+
* {@link ZOOM_OUT_HEADROOM}). Use everywhere instead of `renderer.fitArea()`. */
|
|
51
|
+
export declare function fitAreaWithHeadroom(renderer: MapRenderer): void;
|
|
52
|
+
/**
|
|
53
|
+
* Open an area at its remembered zoom, or at Mudlet's default when it has none,
|
|
54
|
+
* with a zoom-out floor derived from the area's actual extent.
|
|
55
|
+
*
|
|
56
|
+
* The fit runs first, but only for the floor it leaves behind — it is the only
|
|
57
|
+
* thing that derives one from how big the area actually is. The camera's own
|
|
58
|
+
* default floor is a fixed 0.05 with no relation to map size: on any map larger
|
|
59
|
+
* than the viewport that sits far *above* the zoom needed to see the whole thing,
|
|
60
|
+
* so opening without fitting first leaves the wheel pinned at a floor from which
|
|
61
|
+
* the map can never be framed.
|
|
62
|
+
*
|
|
63
|
+
* The fit deliberately does NOT survive as the opening view. Mudlet never fits an
|
|
64
|
+
* area to the widget — T2DMap opens at `TArea::mLast2DMapZoom`, defaulting to
|
|
65
|
+
* `csmDefaultXYZoom`. Fitting produced both halves of a reported bug: a four-room
|
|
66
|
+
* area fitted to roughly one room per screen (the fit of a 1×1-unit extent is
|
|
67
|
+
* already past Mudlet's zoom-in limit), while a city-sized area fitted to rooms a
|
|
68
|
+
* few pixels wide. A fixed unit count is scale-free and gives both the same
|
|
69
|
+
* legible room size.
|
|
70
|
+
*/
|
|
71
|
+
export declare function applyAreaZoom(renderer: MapRenderer, savedZoom: number | null | undefined): void;
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The one source of item ids in a profile.
|
|
3
|
+
*
|
|
4
|
+
* Mudlet hands every trigger, alias, timer, key, button and script its id from
|
|
5
|
+
* a single running number — temporary and permanent alike — so `tempAlias()`
|
|
6
|
+
* followed by `permAlias()` followed by `tempAlias()` yields n, n+1, n+2. mudix
|
|
7
|
+
* grew a counter per engine plus one for the permanent tree, which meant a
|
|
8
|
+
* temporary item and a permanent one could be handed the *same* id: two
|
|
9
|
+
* different things answering to one number, which `killAlias(id)` and
|
|
10
|
+
* `exists(name)` then could not tell apart.
|
|
11
|
+
*
|
|
12
|
+
* Injected rather than constructed in place (see {@link ScriptingEngine}, which
|
|
13
|
+
* hands its own sequence to each engine) so every engine in a profile draws
|
|
14
|
+
* from the same one, while a bare engine built for a unit test still works with
|
|
15
|
+
* a private sequence of its own.
|
|
16
|
+
*/
|
|
17
|
+
export declare class ItemIdSequence {
|
|
18
|
+
private n;
|
|
19
|
+
next(): number;
|
|
20
|
+
/** Ensure future ids exceed `id` — used when an id arrives from outside the
|
|
21
|
+
* sequence (a restored profile, say) so it can never be handed out twice. */
|
|
22
|
+
reserve(id: number): void;
|
|
23
|
+
}
|
|
@@ -54,6 +54,10 @@ export declare class MudSession {
|
|
|
54
54
|
private lastUrl;
|
|
55
55
|
private pingTracker;
|
|
56
56
|
private stateUnsubs;
|
|
57
|
+
/** The profile's server encoding, as `getServerEncodingsList()` spells it.
|
|
58
|
+
* Lives here rather than on the client so it survives having none — see
|
|
59
|
+
* {@link getServerEncoding}. */
|
|
60
|
+
private serverEncoding;
|
|
57
61
|
private _status;
|
|
58
62
|
private _ping;
|
|
59
63
|
private _outputReady;
|
|
@@ -114,11 +118,53 @@ export declare class MudSession {
|
|
|
114
118
|
* local echo, under the current showSentText mode. `script` defers to the
|
|
115
119
|
* flag; `always`/`never` ignore it. */
|
|
116
120
|
private shouldEchoSentText;
|
|
121
|
+
/** Set by ScriptingAPI while trigger-mode echo deferral owns the main
|
|
122
|
+
* console's in-flight partial line (beginLine → flushDeferredEcho). Read
|
|
123
|
+
* by {@link echoCommand}, which must not close a partial the deferral is
|
|
124
|
+
* about to emit itself. */
|
|
125
|
+
scriptEchoDeferred: boolean;
|
|
126
|
+
/** Host::send's echo stage: print a command the player (or an item acting
|
|
127
|
+
* for them) sent, under the showSentText mode. `wantPrint` is the per-call
|
|
128
|
+
* flag `script` mode defers to — `always` and `never` overrule it. */
|
|
129
|
+
echoSentCommand(text: string, wantPrint: boolean): void;
|
|
117
130
|
echoCommand(text: string): void;
|
|
118
131
|
/** Wrap the echoed command in ANSI truecolor escapes from commandEchoColor
|
|
119
132
|
* so it renders in the configured foreground (and optional background). */
|
|
120
133
|
private styleEchoCommand;
|
|
121
|
-
|
|
134
|
+
/** `isGameCommand` mirrors `cTelnet::sendData`'s flag — see
|
|
135
|
+
* {@link MudClient.send}. Everything the player or a script submits is one;
|
|
136
|
+
* auto-login credentials are not, so they can't arm character-at-a-time
|
|
137
|
+
* detection. */
|
|
138
|
+
send(text: string, echo?: boolean, isGameCommand?: boolean): void;
|
|
139
|
+
/**
|
|
140
|
+
* `cTelnet::sendData` — put one command on the wire with **no** local echo
|
|
141
|
+
* under any showSentText mode.
|
|
142
|
+
*
|
|
143
|
+
* Mudlet echoes player input exactly once, at the top of `Host::send`,
|
|
144
|
+
* before the command separator split and before aliases see it (see
|
|
145
|
+
* {@link ScriptingEngine.hostSend}); the parts that come out the far side
|
|
146
|
+
* must not echo again. `send(text, false)` cannot express that — `always`
|
|
147
|
+
* overrides the per-call flag — which is the same reason
|
|
148
|
+
* {@link sendSecret} exists. Unlike sendSecret this is an ordinary command:
|
|
149
|
+
* it still warns about text the server encoding can't carry.
|
|
150
|
+
*/
|
|
151
|
+
sendData(text: string, isGameCommand?: boolean): void;
|
|
152
|
+
/** Mudlet's `mEncodingWarningIssued`: once per encoding, not once per
|
|
153
|
+
* command, so a script sending in a loop doesn't paper the screen. Reset by
|
|
154
|
+
* {@link setServerEncoding} / {@link noteNegotiatedEncoding}, because the
|
|
155
|
+
* new encoding may have no trouble with what the old one couldn't say. */
|
|
156
|
+
private encodingWarningIssued;
|
|
157
|
+
/**
|
|
158
|
+
* Warn when a command cannot survive the trip to the game — cTelnet::sendData
|
|
159
|
+
* posts this before sending anyway, and so do we: the server may still make
|
|
160
|
+
* something of what arrives, and silently dropping the command would be
|
|
161
|
+
* worse than sending it mangled.
|
|
162
|
+
*
|
|
163
|
+
* Warning here rather than in MudClient is deliberate: the encoding belongs
|
|
164
|
+
* to the profile, not the socket, and a player typing at a client that isn't
|
|
165
|
+
* connected yet has just as much use for the notice.
|
|
166
|
+
*/
|
|
167
|
+
private warnIfUnencodable;
|
|
122
168
|
/** Send credentials/secrets that must NEVER be echoed locally — regardless of
|
|
123
169
|
* the showSentText mode (including `always`) or the server-echo state. Used
|
|
124
170
|
* for auto-login passwords. The normal `send(text, false)` only suppresses
|
|
@@ -135,6 +181,15 @@ export declare class MudSession {
|
|
|
135
181
|
sendSocket(data: string): boolean;
|
|
136
182
|
/** True when there is no live socket — see MudClient.isSocketUnconnected. */
|
|
137
183
|
isSocketUnconnected(): boolean;
|
|
184
|
+
/** Mudlet `feedTelnet(data)`. Injects raw bytes into the inbound pipeline as
|
|
185
|
+
* if the server had sent them.
|
|
186
|
+
*
|
|
187
|
+
* Works with no connection, which is the state the API is *for*: Mudlet
|
|
188
|
+
* refuses to inject into a live socket (it would interleave with the real
|
|
189
|
+
* stream), so every caller — its own test suite included — is offline by
|
|
190
|
+
* definition. With no client there is no pipeline to inject into, so this
|
|
191
|
+
* borrows the detached one replay playback already builds for the same
|
|
192
|
+
* reason: the telnet/ANSI/trigger path needs no socket to run. */
|
|
138
193
|
feedTelnet(data: string): void;
|
|
139
194
|
sendATCP(message: string): boolean;
|
|
140
195
|
sendTelnetChannel102(msg: string): boolean;
|
|
@@ -144,6 +199,10 @@ export declare class MudSession {
|
|
|
144
199
|
get replaySpeed(): number;
|
|
145
200
|
get isReplayRecording(): boolean;
|
|
146
201
|
get isReplaying(): boolean;
|
|
202
|
+
/** Deliver any replay chunk that has come due. See ReplayPlayer.pumpDue —
|
|
203
|
+
* a script standing in for the event loop has to drive this queue too, or a
|
|
204
|
+
* replay it started never advances past its first chunk. */
|
|
205
|
+
pumpReplay(): number;
|
|
147
206
|
/** Set the playback speed divisor, clamped to Mudlet's 1..1024 range.
|
|
148
207
|
* Takes effect from the next chunk of an active replay. */
|
|
149
208
|
setReplaySpeed(speed: number): void;
|
|
@@ -162,23 +221,35 @@ export declare class MudSession {
|
|
|
162
221
|
/** Stop the active replay without delivering its remaining chunks.
|
|
163
222
|
* Returns false when no replay is running. */
|
|
164
223
|
abortReplay(): boolean;
|
|
165
|
-
/** The client whose parsing pipeline
|
|
166
|
-
* live client when one exists;
|
|
167
|
-
* that is never connect()ed — the
|
|
168
|
-
* socket, and any replies the
|
|
169
|
-
* by the readyState guards, which is exactly
|
|
170
|
-
|
|
224
|
+
/** The client whose parsing pipeline injected bytes feed into — replay
|
|
225
|
+
* chunks and feedTelnet alike. Reuses the live client when one exists;
|
|
226
|
+
* otherwise creates a detached MudClient that is never connect()ed — the
|
|
227
|
+
* inbound pipeline works without a socket, and any replies the injected IAC
|
|
228
|
+
* traffic provokes are dropped by the readyState guards, which is exactly
|
|
229
|
+
* right when nothing is listening for them. */
|
|
230
|
+
private ensureParsingClient;
|
|
171
231
|
private postReplayInfo;
|
|
172
232
|
/** Mudlet `reconnect()`. Disconnect and redial the most recently connected
|
|
173
233
|
* URL (set by connect(), so it covers both the app and Lua connect paths).
|
|
174
234
|
* Returns false when nothing has been dialed yet. */
|
|
175
235
|
reconnect(): boolean;
|
|
176
|
-
/**
|
|
177
|
-
*
|
|
236
|
+
/**
|
|
237
|
+
* Mudlet `getServerEncoding()` / `setServerEncoding(name)`.
|
|
238
|
+
*
|
|
239
|
+
* The encoding is the profile's, not the socket's: it can be read and
|
|
240
|
+
* changed with nothing dialed, and the setting carries across a connect.
|
|
241
|
+
* A live client is told about the change so its decoder follows, and a
|
|
242
|
+
* CHARSET negotiation writes the agreed name back here — but the client is
|
|
243
|
+
* not where the answer comes from. It used to be, which made both functions
|
|
244
|
+
* inert until a connection existed, and the name they reported was the
|
|
245
|
+
* decoder's IANA spelling ("utf-8") rather than the one the caller chose
|
|
246
|
+
* ("UTF-8" as `getServerEncodingsList()` spells it).
|
|
247
|
+
*/
|
|
178
248
|
getServerEncoding(): string;
|
|
179
|
-
/** Mudlet `setServerEncoding(name)`. Returns false when no client is
|
|
180
|
-
* attached or the name isn't supported. */
|
|
181
249
|
setServerEncoding(name: string): boolean;
|
|
250
|
+
/** Called when CHARSET negotiation settles on a name, so the profile-level
|
|
251
|
+
* setting reflects what the connection actually agreed. */
|
|
252
|
+
noteNegotiatedEncoding(name: string): void;
|
|
182
253
|
/** Mudlet `getServerEncodingsList()`. The fixed set of encodings mudix can
|
|
183
254
|
* decode — available even before a connection is dialed. */
|
|
184
255
|
getServerEncodingsList(): string[];
|
|
@@ -194,6 +265,37 @@ export declare class MudSession {
|
|
|
194
265
|
/** Mudlet `setConfig("fixUnnecessaryLinebreaks", …)`. Updates the live client
|
|
195
266
|
* and the stored options so the setting survives a reconnect. */
|
|
196
267
|
setFixUnnecessaryLinebreaks(enabled: boolean): void;
|
|
268
|
+
/** Mudlet `Host::mUndoServerWrap` / `mUndoServerWrapWidth`, as getConfig
|
|
269
|
+
* reads them back. */
|
|
270
|
+
get undoServerWrap(): boolean;
|
|
271
|
+
get undoServerWrapWidth(): number;
|
|
272
|
+
/** Mudlet `setConfig("undoServerWrap", …)`. Updates the live client and the
|
|
273
|
+
* stored options so the setting survives a reconnect. */
|
|
274
|
+
setUndoServerWrap(enabled: boolean): void;
|
|
275
|
+
/** Mudlet `setConfig("undoServerWrapWidth", …)`. */
|
|
276
|
+
setUndoServerWrapWidth(width: number): void;
|
|
277
|
+
/** Commit a line held for a wrap continuation whose flush delay has passed —
|
|
278
|
+
* the busted `pumpEvents` path, which cannot wait for a real timer. */
|
|
279
|
+
pumpServerWrap(): boolean;
|
|
280
|
+
/** Mudlet `setConfig("inputLineStrictUnixEndings", …)`. Live — the next
|
|
281
|
+
* command submitted uses the new line terminator. */
|
|
282
|
+
setInputLineStrictUnixEndings(enabled: boolean): void;
|
|
283
|
+
/** Mudlet `setConfig("specialForceGAOff", …)`. Stored for the next dial, and
|
|
284
|
+
* applied at once to a client that is not connected — which is the state a
|
|
285
|
+
* profile driving `feedTelnet` is in, and the only one where Mudlet lets
|
|
286
|
+
* the change land early. See MudClient.setForceGaOff. */
|
|
287
|
+
setSpecialForceGAOff(enabled: boolean): void;
|
|
288
|
+
/** Mudlet `setConfig("versionInTTYPE", …)` / `("promptForVersionInTTYPE", …)`.
|
|
289
|
+
* Stored only: TTYPE is negotiated at connect, so both take effect on the
|
|
290
|
+
* next dial — the same reconnect requirement Mudlet's own auto-detect works
|
|
291
|
+
* around by redialing for you. */
|
|
292
|
+
setVersionInTTYPE(enabled: boolean, prompted?: boolean): void;
|
|
293
|
+
/** Mudlet `setConfig("promptForMXPProcessorOn", …)` / `("specialForceMXPProcessorOn", …)`.
|
|
294
|
+
* Stored only — together they gate whether an in-band `ESC[<n>z` may still
|
|
295
|
+
* auto-start MXP, which the negotiator decides at connect. The *parser*
|
|
296
|
+
* side of `specialForceMXPProcessorOn` is applied live by ScriptingEngine;
|
|
297
|
+
* this is just the detection gate. */
|
|
298
|
+
setMxpProcessorFlags(prompted: boolean, forced: boolean): void;
|
|
197
299
|
/** Mudlet `setConfig("controlCharacterHandling", …)`. Applies immediately —
|
|
198
300
|
* every console/text window re-renders control characters (and tab-stops)
|
|
199
301
|
* under the new mode on their next paint. */
|
|
@@ -14,7 +14,12 @@ export declare class PatternEngine<T extends PatternItem> {
|
|
|
14
14
|
pattern: RegExp;
|
|
15
15
|
fn: TempFn;
|
|
16
16
|
}>;
|
|
17
|
-
|
|
17
|
+
/** Key for this engine's own temp map. NOT an item id: addTemp hands the
|
|
18
|
+
* caller an unsubscribe function, and the id Lua sees is allocated by the
|
|
19
|
+
* runtime from the profile's shared sequence. Drawing from that sequence
|
|
20
|
+
* here would burn a number per temp item and put permAlias/tempAlias out
|
|
21
|
+
* of step (Alias_spec pins the run of ids). */
|
|
22
|
+
protected nextInternalId: number;
|
|
18
23
|
protected permCompiled: Array<{
|
|
19
24
|
item: T;
|
|
20
25
|
re: RegExp;
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The command-separator split from Mudlet's `Host::send`.
|
|
3
|
+
*
|
|
4
|
+
* One line typed (or one `command` field on an alias/key/trigger/timer/button)
|
|
5
|
+
* can carry several commands, joined by the profile's separator — `;;` by
|
|
6
|
+
* default. Mudlet splits with `Qt::SkipEmptyParts`, so `n;;;;s` is two commands
|
|
7
|
+
* rather than three, and a line that is nothing but separators collapses to
|
|
8
|
+
* nothing at all.
|
|
9
|
+
*
|
|
10
|
+
* An empty result is meaningful: Mudlet answers it by putting a bare line feed
|
|
11
|
+
* on the wire, so pressing Enter on an empty command line still reaches the
|
|
12
|
+
* game (menus, "more" prompts). Callers handle that case themselves — see
|
|
13
|
+
* {@link ScriptingEngine.hostSend} — which is why this returns `[]` rather than
|
|
14
|
+
* quietly inventing an empty command.
|
|
15
|
+
*/
|
|
16
|
+
export declare function splitCommands(text: string, separator: string): string[];
|
|
@@ -19,6 +19,11 @@ export interface LineAssemblerCallbacks {
|
|
|
19
19
|
}
|
|
20
20
|
export interface LineAssemblerOptions {
|
|
21
21
|
promptTimeoutMs?: number;
|
|
22
|
+
/** Mudlet `Host::mUndoServerWrap` — rejoin lines the game hard-wrapped
|
|
23
|
+
* itself. Off by default; toggled live via setConfig. */
|
|
24
|
+
undoServerWrap?: boolean;
|
|
25
|
+
/** Mudlet `Host::mUndoServerWrapWidth` — the column the game wraps at. */
|
|
26
|
+
undoServerWrapWidth?: number;
|
|
22
27
|
/** Mudlet `mUSE_IRE_DRIVER_BUGFIX` — strip a spurious leading newline from
|
|
23
28
|
* GA-driven prompt blocks. Off by default; toggled live via
|
|
24
29
|
* setFixUnnecessaryLinebreaks (setConfig). */
|
|
@@ -58,6 +63,19 @@ export declare class LineAssembler {
|
|
|
58
63
|
* the block's leading-newline question has been settled. */
|
|
59
64
|
private atPromptBlockStart;
|
|
60
65
|
private fixUnnecessaryLinebreaks;
|
|
66
|
+
private undoServerWrap;
|
|
67
|
+
private undoServerWrapWidth;
|
|
68
|
+
private serverWrapPending;
|
|
69
|
+
/** Visible length of the last *game line* joined into the held text — what
|
|
70
|
+
* the next word is measured against, not the whole joined paragraph. */
|
|
71
|
+
private serverWrapPendingSegmentLength;
|
|
72
|
+
/** Opening of that same game line, kept so a continuation repeating it can
|
|
73
|
+
* be told from one that carries on where it left off. */
|
|
74
|
+
private serverWrapPendingSegmentStart;
|
|
75
|
+
private serverWrapTimer;
|
|
76
|
+
/** When the held line falls due, so a blocked event loop can still commit it
|
|
77
|
+
* on demand — see {@link pumpServerWrapDue}. */
|
|
78
|
+
private serverWrapDeadline;
|
|
61
79
|
constructor(callbacks: LineAssemblerCallbacks, options?: LineAssemblerOptions);
|
|
62
80
|
/** True once the session has latched into GA-driven prompt mode. */
|
|
63
81
|
get gaDriver(): boolean;
|
|
@@ -66,6 +84,12 @@ export declare class LineAssembler {
|
|
|
66
84
|
/** Mudlet `setConfig("fixUnnecessaryLinebreaks", …)`. Takes effect on the
|
|
67
85
|
* next GA-driven block; never retroactive. */
|
|
68
86
|
setFixUnnecessaryLinebreaks(enabled: boolean): void;
|
|
87
|
+
/** Mudlet `setConfig("undoServerWrap", …)`. Turning it off commits anything
|
|
88
|
+
* held on the spot rather than stranding it until the next line. */
|
|
89
|
+
setUndoServerWrap(enabled: boolean): void;
|
|
90
|
+
/** Mudlet `setConfig("undoServerWrapWidth", …)`. Applies from the next line;
|
|
91
|
+
* the held one was already judged against the previous column. */
|
|
92
|
+
setUndoServerWrapWidth(width: number): void;
|
|
69
93
|
/** Drop all held state (call on connect and after close). */
|
|
70
94
|
reset(): void;
|
|
71
95
|
/** Feed one frame's decoded text plus whether the frame carried a prompt
|
|
@@ -79,6 +103,38 @@ export declare class LineAssembler {
|
|
|
79
103
|
* socket close. Pushes the tail through the normal chunk path so triggers
|
|
80
104
|
* and rendering treat it as a complete line. */
|
|
81
105
|
flush(ts: number, final?: boolean): void;
|
|
106
|
+
/**
|
|
107
|
+
* Run the whole lines of one ready chunk through the server-wrap join and
|
|
108
|
+
* emit what comes out. With the option off this is `onChunk(ready)` and
|
|
109
|
+
* nothing else.
|
|
110
|
+
*
|
|
111
|
+
* Mudlet decides this per '\n' inside `TBuffer::append`, gated on the line
|
|
112
|
+
* having come from the server: everything else (prompts, timer-flushed
|
|
113
|
+
* fragments, MXP `<br>`, blank lines) is a real boundary. Here the gate is
|
|
114
|
+
* structural — this is the only path whole server lines take, and
|
|
115
|
+
* feedTriggers/echoes never reach it.
|
|
116
|
+
*/
|
|
117
|
+
private emitServerLines;
|
|
118
|
+
/**
|
|
119
|
+
* Offer one whole server line to the join. Returns the text to commit —
|
|
120
|
+
* newline-terminated lines, or the empty string when the line was held back
|
|
121
|
+
* for a continuation.
|
|
122
|
+
*/
|
|
123
|
+
private consumeServerLine;
|
|
124
|
+
/** Take the held line, if any, and stop its timer. */
|
|
125
|
+
private takeServerWrapPending;
|
|
126
|
+
/** Commit the held line on its own, as its own chunk. */
|
|
127
|
+
private commitServerWrapPending;
|
|
128
|
+
/**
|
|
129
|
+
* Commit a held line whose flush delay has elapsed. The timer below cannot
|
|
130
|
+
* be relied on alone: a busted run is one synchronous call sitting on top of
|
|
131
|
+
* the event loop, so no `setTimeout` of ours can fire until it returns. The
|
|
132
|
+
* spec's `pumpEvents` reaches this instead, exactly as it reaches the Lua
|
|
133
|
+
* timer queue and the replay player. Returns true when a line was committed.
|
|
134
|
+
*/
|
|
135
|
+
pumpServerWrapDue(now?: number): boolean;
|
|
136
|
+
private startServerWrapTimer;
|
|
137
|
+
private clearServerWrapTimer;
|
|
82
138
|
private scheduleTailFlush;
|
|
83
139
|
private clearTailTimer;
|
|
84
140
|
}
|