@mudlet/mudlet-web 0.5.0 → 1.0.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.
Files changed (301) hide show
  1. package/README.md +1 -1
  2. package/dist-lib/analytics.d.ts +27 -0
  3. package/dist-lib/assets/fonts/Vera.woff2 +0 -0
  4. package/dist-lib/assets/fonts/VeraBI.woff2 +0 -0
  5. package/dist-lib/assets/fonts/VeraBd.woff2 +0 -0
  6. package/dist-lib/assets/fonts/VeraIt.woff2 +0 -0
  7. package/dist-lib/assets/mapParser.worker-DrVZ3wg_.js +9 -0
  8. package/dist-lib/backupImport-wt8r7JXI.js +233 -0
  9. package/dist-lib/branding.d.ts +111 -13
  10. package/dist-lib/db/sqliteClient.d.ts +195 -7
  11. package/dist-lib/hooks/useAutoReconnect.d.ts +61 -0
  12. package/dist-lib/hooks/useDocumentFullscreen.d.ts +23 -0
  13. package/dist-lib/hooks/useKeyboardShortcuts.d.ts +37 -0
  14. package/dist-lib/hooks/useRecordLastPlayed.d.ts +10 -0
  15. package/dist-lib/import/applyMudletProfile.d.ts +35 -9
  16. package/dist-lib/import/backupImport.d.ts +118 -0
  17. package/dist-lib/import/collectProfileExport.d.ts +33 -2
  18. package/dist-lib/import/defaultPackages.d.ts +57 -14
  19. package/dist-lib/import/defaults/CF-loader/CF-loader.mpackage +0 -0
  20. package/dist-lib/import/defaults/MedBootstrap/MedBootstrap.mpackage +0 -0
  21. package/dist-lib/import/defaults/deleteOldProfiles/deleteOldProfiles.mpackage +0 -0
  22. package/dist-lib/import/defaults/echo/echo.mpackage +0 -0
  23. package/dist-lib/import/defaults/enable-accessibility/enable-accessibility.mpackage +0 -0
  24. package/dist-lib/import/defaults/generic_mapper/generic_mapper.mpackage +0 -0
  25. package/dist-lib/import/defaults/gui-drop/gui-drop.mpackage +0 -0
  26. package/dist-lib/import/defaults/icesus-loader/icesus-loader.mpackage +0 -0
  27. package/dist-lib/import/defaults/mg-loader/mg-loader.mpackage +0 -0
  28. package/dist-lib/import/defaults/mudlet-base-ui/mudlet-base-ui.mpackage +0 -0
  29. package/dist-lib/import/defaults/mudlet-mapper.xml +1215 -389
  30. package/dist-lib/import/mudletControlChars.d.ts +14 -0
  31. package/dist-lib/import/mudletHost.d.ts +73 -10
  32. package/dist-lib/import/mudletLink.d.ts +53 -2
  33. package/dist-lib/import/mudletProfileExport.d.ts +38 -5
  34. package/dist-lib/import/mudletProfileImport.d.ts +110 -12
  35. package/dist-lib/import/mudletVariables.d.ts +4 -3
  36. package/dist-lib/import/mudletWriteback.d.ts +15 -1
  37. package/dist-lib/import/mudletXmlImport.d.ts +46 -0
  38. package/dist-lib/import/packageFonts.d.ts +33 -0
  39. package/dist-lib/import/packageInstaller.d.ts +111 -7
  40. package/dist-lib/import/qtProfileData.d.ts +10 -0
  41. package/dist-lib/import/remotePackageInstall.d.ts +23 -7
  42. package/dist-lib/import/zipEntries.d.ts +45 -0
  43. package/dist-lib/index.d.ts +7 -3
  44. package/dist-lib/index.js +50508 -29836
  45. package/dist-lib/logging/SessionLogger.d.ts +75 -15
  46. package/dist-lib/map/MapSelectionOverlay.d.ts +2 -2
  47. package/dist-lib/map/MapStore.d.ts +387 -60
  48. package/dist-lib/map/MudletHighlightOverlay.d.ts +2 -2
  49. package/dist-lib/map/{MudixMapReader.d.ts → MudletMapReader.d.ts} +2 -2
  50. package/dist-lib/map/areaGraph.d.ts +120 -0
  51. package/dist-lib/map/environmentKit.d.ts +36 -0
  52. package/dist-lib/map/labelPixmap.d.ts +90 -0
  53. package/dist-lib/map/mapImageExport.d.ts +36 -2
  54. package/dist-lib/map/mapStyle.d.ts +11 -0
  55. package/dist-lib/map/mapVersion.d.ts +66 -0
  56. package/dist-lib/map/pathfinding.d.ts +2 -2
  57. package/dist-lib/mud/CharLoginController.d.ts +230 -0
  58. package/dist-lib/mud/ItemIdSequence.d.ts +1 -1
  59. package/dist-lib/mud/MudSession.d.ts +279 -22
  60. package/dist-lib/mud/PatternEngine.d.ts +153 -14
  61. package/dist-lib/mud/aliases/AliasEngine.d.ts +55 -9
  62. package/dist-lib/mud/autoLogin.d.ts +59 -0
  63. package/dist-lib/mud/commandSplit.d.ts +9 -0
  64. package/dist-lib/mud/connection/LineAssembler.d.ts +38 -11
  65. package/dist-lib/mud/connection/MudClient.d.ts +291 -53
  66. package/dist-lib/mud/connection/SubnegotiationRepair.d.ts +24 -0
  67. package/dist-lib/mud/connection/TelnetNegotiator.d.ts +208 -68
  68. package/dist-lib/mud/connection/telnetDebug.d.ts +8 -8
  69. package/dist-lib/mud/events.d.ts +102 -23
  70. package/dist-lib/mud/games/bundledGames.d.ts +12 -7
  71. package/dist-lib/mud/games/gameLinks.d.ts +40 -0
  72. package/dist-lib/mud/games/icons/3Kingdoms.png +0 -0
  73. package/dist-lib/mud/games/icons/3Scapes.png +0 -0
  74. package/dist-lib/mud/games/icons/achaea.png +0 -0
  75. package/dist-lib/mud/games/icons/aetolia.png +0 -0
  76. package/dist-lib/mud/games/icons/banner_astaria.png +0 -0
  77. package/dist-lib/mud/games/icons/banner_darkmists.png +0 -0
  78. package/dist-lib/mud/games/icons/banner_dreamland.png +0 -0
  79. package/dist-lib/mud/games/icons/banner_petria.jpg +0 -0
  80. package/dist-lib/mud/games/icons/banner_ropmud.png +0 -0
  81. package/dist-lib/mud/games/icons/blackmud.png +0 -0
  82. package/dist-lib/mud/games/icons/carrionfields.png +0 -0
  83. package/dist-lib/mud/games/icons/dragonfire_icon.png +0 -0
  84. package/dist-lib/mud/games/icons/fed2-logo.png +0 -0
  85. package/dist-lib/mud/games/icons/icesus_480x120.png +0 -0
  86. package/dist-lib/mud/games/icons/imperian.png +0 -0
  87. package/dist-lib/mud/games/icons/infinity_480x120.png +0 -0
  88. package/dist-lib/mud/games/icons/lusternia.png +0 -0
  89. package/dist-lib/mud/games/icons/morgengrauen_480x120.png +0 -0
  90. package/dist-lib/mud/games/icons/mudlet-tutorial.png +0 -0
  91. package/dist-lib/mud/games/icons/phoenixmud_480x120.png +0 -0
  92. package/dist-lib/mud/games/icons/starmourn.png +0 -0
  93. package/dist-lib/mud/games/icons/voidmud_icon.png +0 -0
  94. package/dist-lib/mud/games/icons/wotmudicon.png +0 -0
  95. package/dist-lib/mud/games/websiteLinks.d.ts +21 -0
  96. package/dist-lib/mud/keybindings/KeyEngine.d.ts +110 -4
  97. package/dist-lib/mud/keybindings/browserReservedKeys.d.ts +2 -2
  98. package/dist-lib/mud/keybindings/keyEventTarget.d.ts +61 -0
  99. package/dist-lib/mud/keybindings/qtKeys.d.ts +91 -12
  100. package/dist-lib/mud/protocol/atcp.d.ts +19 -0
  101. package/dist-lib/mud/protocol/byteString.d.ts +24 -0
  102. package/dist-lib/mud/protocol/charLoginFlow.d.ts +243 -16
  103. package/dist-lib/mud/protocol/charset.d.ts +111 -46
  104. package/dist-lib/mud/protocol/codePages.d.ts +10 -0
  105. package/dist-lib/mud/protocol/constants.d.ts +17 -10
  106. package/dist-lib/mud/protocol/echo.d.ts +23 -27
  107. package/dist-lib/mud/protocol/gmcp.d.ts +36 -6
  108. package/dist-lib/mud/protocol/index.d.ts +3 -2
  109. package/dist-lib/mud/protocol/luaLiteral.d.ts +12 -0
  110. package/dist-lib/mud/protocol/mccp.d.ts +83 -1
  111. package/dist-lib/mud/protocol/mnes.d.ts +41 -58
  112. package/dist-lib/mud/protocol/msdp.d.ts +11 -4
  113. package/dist-lib/mud/protocol/msp.d.ts +3 -2
  114. package/dist-lib/mud/protocol/mssp.d.ts +9 -4
  115. package/dist-lib/mud/protocol/multiByte.d.ts +51 -0
  116. package/dist-lib/mud/protocol/multiByteEncode.d.ts +42 -0
  117. package/dist-lib/mud/protocol/mxp.d.ts +193 -14
  118. package/dist-lib/mud/protocol/oauthClientFlow.d.ts +128 -0
  119. package/dist-lib/mud/protocol/qtCodePages.generated.d.ts +1 -0
  120. package/dist-lib/mud/protocol/tlsCodes.d.ts +40 -3
  121. package/dist-lib/mud/replay/ReplayPlayer.d.ts +16 -1
  122. package/dist-lib/mud/replay/replayFormat.d.ts +29 -2
  123. package/dist-lib/mud/text/Console.d.ts +255 -49
  124. package/dist-lib/mud/text/FormatState.d.ts +137 -14
  125. package/dist-lib/mud/text/ansiEscapes.d.ts +32 -16
  126. package/dist-lib/mud/text/colorParsers.d.ts +14 -2
  127. package/dist-lib/mud/text/colorSpaceId.d.ts +2 -0
  128. package/dist-lib/mud/text/colors.d.ts +17 -10
  129. package/dist-lib/mud/text/controlCharacterMode.d.ts +1 -1
  130. package/dist-lib/mud/text/hyperlinkVisibility.d.ts +1 -1
  131. package/dist-lib/mud/text/lineBreak.d.ts +5 -0
  132. package/dist-lib/mud/text/serverWrap.d.ts +2 -2
  133. package/dist-lib/mud/text/textAnalyzer.d.ts +79 -0
  134. package/dist-lib/mud/text/unicodeRuns.d.ts +11 -0
  135. package/dist-lib/mud/text/unicodeTables.generated.d.ts +3 -0
  136. package/dist-lib/mud/text/wcwidth.d.ts +27 -22
  137. package/dist-lib/mud/timers/TimerEngine.d.ts +163 -11
  138. package/dist-lib/mud/timers/workerClock.d.ts +67 -0
  139. package/dist-lib/mud/triggers/TriggerEngine.d.ts +449 -47
  140. package/dist-lib/mud/triggers/legacyColorPatterns.d.ts +58 -0
  141. package/dist-lib/mud/triggers/pcre/Pcre2.d.ts +83 -1
  142. package/dist-lib/oauth-callback.html +94 -0
  143. package/dist-lib/pcre2Wasm.d.ts +54 -0
  144. package/dist-lib/pcre2Wasm.js +241 -0
  145. package/dist-lib/scripting/EngineHost.d.ts +45 -21
  146. package/dist-lib/scripting/IScriptingRuntime.d.ts +103 -27
  147. package/dist-lib/scripting/MxpFrameManager.d.ts +10 -1
  148. package/dist-lib/scripting/ScriptingAPI.d.ts +1030 -213
  149. package/dist-lib/scripting/ScriptingEngine.d.ts +727 -106
  150. package/dist-lib/scripting/StopwatchManager.d.ts +97 -36
  151. package/dist-lib/scripting/http/HttpService.d.ts +9 -1
  152. package/dist-lib/scripting/http/userUrl.d.ts +41 -0
  153. package/dist-lib/scripting/lua/LuaRuntime.d.ts +352 -77
  154. package/dist-lib/scripting/lua/argContracts.d.ts +71 -0
  155. package/dist-lib/scripting/lua/bindings/automation.d.ts +1 -1
  156. package/dist-lib/scripting/lua/bindings/commands.d.ts +13 -0
  157. package/dist-lib/scripting/lua/bindings/context.d.ts +20 -2
  158. package/dist-lib/scripting/lua/bindings/diagnostics.d.ts +1 -1
  159. package/dist-lib/scripting/lua/bindings/map.d.ts +1 -1
  160. package/dist-lib/scripting/lua/bindings/media.d.ts +2 -2
  161. package/dist-lib/scripting/lua/bindings/output.d.ts +1 -1
  162. package/dist-lib/scripting/lua/bindings/session.d.ts +2 -2
  163. package/dist-lib/scripting/lua/bindings/textEdit.d.ts +1 -1
  164. package/dist-lib/scripting/lua/bindings/userWindows.d.ts +1 -1
  165. package/dist-lib/scripting/lua/byteArmor.d.ts +36 -0
  166. package/dist-lib/scripting/lua/imageSize.d.ts +7 -0
  167. package/dist-lib/scripting/lua/rex.d.ts +4 -2
  168. package/dist-lib/scripting/lua/sqlRowEncoder.d.ts +6 -1
  169. package/dist-lib/scripting/lua/utf8CaseMap.d.ts +1 -0
  170. package/dist-lib/scripting/lua/utf8Patterns.d.ts +21 -1
  171. package/dist-lib/scripting/lua/wellFormedStrings.d.ts +40 -0
  172. package/dist-lib/scripting/lua/yajl.d.ts +43 -5
  173. package/dist-lib/scripting/profilesPresence.d.ts +20 -2
  174. package/dist-lib/scripting/vfs/ProfileVFS.d.ts +164 -10
  175. package/dist-lib/scripting/vfs/fsErrors.d.ts +28 -0
  176. package/dist-lib/scripting/vfs/idbCommit.d.ts +20 -0
  177. package/dist-lib/storage/appStore.d.ts +24 -9
  178. package/dist-lib/storage/hooks.d.ts +5 -1
  179. package/dist-lib/storage/index.d.ts +2 -2
  180. package/dist-lib/storage/mapStorage.d.ts +2 -0
  181. package/dist-lib/storage/persistentStorage.d.ts +3 -1
  182. package/dist-lib/storage/profileStorage.d.ts +15 -0
  183. package/dist-lib/storage/profileVfsData.d.ts +3 -3
  184. package/dist-lib/storage/schema.d.ts +512 -40
  185. package/dist-lib/storage/storageMigration.d.ts +82 -0
  186. package/dist-lib/storage-g5V1b-c1.js +2039 -0
  187. package/dist-lib/styles.css +1 -1
  188. package/dist-lib/ui/AboutModal.d.ts +1 -1
  189. package/dist-lib/ui/BrandLoginFields.d.ts +1 -1
  190. package/dist-lib/ui/BrowserSignInModal.d.ts +23 -0
  191. package/dist-lib/ui/CmdLineMenuRegistry.d.ts +14 -5
  192. package/dist-lib/ui/CommandBar.d.ts +8 -8
  193. package/dist-lib/ui/ConnectionFormModal.d.ts +20 -1
  194. package/dist-lib/ui/ConnectionScreen.d.ts +9 -1
  195. package/dist-lib/ui/GameLinkPrompt.d.ts +28 -0
  196. package/dist-lib/ui/HelpModal.d.ts +5 -1
  197. package/dist-lib/ui/MapSymbolUsageModal.d.ts +32 -0
  198. package/dist-lib/ui/MouseEventRegistry.d.ts +31 -4
  199. package/dist-lib/ui/NotepadModal.d.ts +22 -0
  200. package/dist-lib/ui/ResizableModal.d.ts +16 -1
  201. package/dist-lib/ui/SettingsModal.d.ts +10 -1
  202. package/dist-lib/ui/TlsAlertBanner.d.ts +3 -1
  203. package/dist-lib/ui/Toolbar.d.ts +22 -1
  204. package/dist-lib/ui/VaultManageButton.d.ts +10 -5
  205. package/dist-lib/ui/VaultModal.d.ts +3 -0
  206. package/dist-lib/ui/buttons/ButtonsBar.d.ts +3 -1
  207. package/dist-lib/ui/buttons/inactiveButtons.d.ts +25 -0
  208. package/dist-lib/ui/cmdline/CommandLineManager.d.ts +19 -0
  209. package/dist-lib/ui/cmdline/plainText.d.ts +16 -0
  210. package/dist-lib/ui/cmdline/subCommandLine.d.ts +78 -0
  211. package/dist-lib/ui/cmdline/useCmdLineSelection.d.ts +26 -0
  212. package/dist-lib/ui/cmdline/useSubCommandLineKeys.d.ts +33 -0
  213. package/dist-lib/ui/codemirror/lineParagraphMarks.d.ts +19 -0
  214. package/dist-lib/ui/codemirror/luaHover.d.ts +7 -0
  215. package/dist-lib/ui/codemirror/options.d.ts +33 -0
  216. package/dist-lib/ui/codemirror/theme.d.ts +29 -5
  217. package/dist-lib/ui/commands/addonCommands.d.ts +134 -0
  218. package/dist-lib/ui/commands/appShortcuts.d.ts +86 -0
  219. package/dist-lib/ui/commands/hostCommands.d.ts +88 -0
  220. package/dist-lib/ui/commands/keyMatch.d.ts +20 -0
  221. package/dist-lib/ui/commands/keySequence.d.ts +57 -0
  222. package/dist-lib/ui/components/ContextMenu.d.ts +21 -1
  223. package/dist-lib/ui/components/FontPicker.d.ts +5 -1
  224. package/dist-lib/ui/components/useModalFocus.d.ts +13 -1
  225. package/dist-lib/ui/helpTopics.d.ts +15 -0
  226. package/dist-lib/ui/labels/LabelManager.d.ts +172 -9
  227. package/dist-lib/ui/labels/LabelOverlay.d.ts +19 -0
  228. package/dist-lib/ui/labels/backgroundImageSize.d.ts +19 -0
  229. package/dist-lib/ui/labels/labelModel.d.ts +64 -0
  230. package/dist-lib/ui/labels/qColor.d.ts +13 -0
  231. package/dist-lib/ui/labels/qtCss.d.ts +12 -4
  232. package/dist-lib/ui/landmarks.d.ts +9 -0
  233. package/dist-lib/ui/launcher/ActionMenu.d.ts +19 -0
  234. package/dist-lib/ui/launcher/GameDetails.d.ts +21 -0
  235. package/dist-lib/ui/launcher/GameSection.d.ts +18 -0
  236. package/dist-lib/ui/launcher/LauncherSearch.d.ts +23 -0
  237. package/dist-lib/ui/launcher/ProfileArt.d.ts +20 -0
  238. package/dist-lib/ui/launcher/ProfileSection.d.ts +43 -0
  239. package/dist-lib/ui/launcher/launcherModel.d.ts +72 -0
  240. package/dist-lib/ui/layout/overlayLayerOrder.d.ts +2 -2
  241. package/dist-lib/ui/menu/MenuBar.d.ts +31 -0
  242. package/dist-lib/ui/menu/SplitButton.d.ts +39 -0
  243. package/dist-lib/ui/menu/anchoredPopup.d.ts +74 -0
  244. package/dist-lib/ui/menu/appMenus.d.ts +65 -0
  245. package/dist-lib/ui/menu/menuModel.d.ts +88 -0
  246. package/dist-lib/ui/menu/toolbarModel.d.ts +56 -0
  247. package/dist-lib/ui/notepad.d.ts +76 -0
  248. package/dist-lib/ui/openSignInPage.d.ts +14 -0
  249. package/dist-lib/ui/output/OutputContextMenu.d.ts +14 -1
  250. package/dist-lib/ui/output/OutputRenderer.d.ts +5 -0
  251. package/dist-lib/ui/output/OutputSearchBar.d.ts +5 -1
  252. package/dist-lib/ui/output/StickyOutputPanel.d.ts +17 -3
  253. package/dist-lib/ui/output/TextAnalyzerModal.d.ts +25 -0
  254. package/dist-lib/ui/output/caretMode.d.ts +3 -2
  255. package/dist-lib/ui/output/clearSplit.d.ts +11 -0
  256. package/dist-lib/ui/output/outputCopy.d.ts +41 -2
  257. package/dist-lib/ui/output/outputRows.d.ts +43 -0
  258. package/dist-lib/ui/output/selectionGesture.d.ts +35 -0
  259. package/dist-lib/ui/output/wordSelection.d.ts +33 -0
  260. package/dist-lib/ui/search/matcher.d.ts +14 -4
  261. package/dist-lib/ui/settings/SettingsShell.d.ts +91 -0
  262. package/dist-lib/ui/settings/ShortcutEditor.d.ts +13 -0
  263. package/dist-lib/ui/sound/SoundManager.d.ts +210 -44
  264. package/dist-lib/ui/sound/closedCaption.d.ts +4 -1
  265. package/dist-lib/ui/sound/mediaDirection.d.ts +35 -0
  266. package/dist-lib/ui/tabCompletion.d.ts +53 -0
  267. package/dist-lib/ui/textedit/TextEditManager.d.ts +11 -2
  268. package/dist-lib/ui/useOpenProfiles.d.ts +1 -1
  269. package/dist-lib/ui/video/VideoManager.d.ts +7 -0
  270. package/dist-lib/ui/windows/WindowManager.d.ts +452 -37
  271. package/dist-lib/ui/windows/panels/ScriptEditorPanel.d.ts +14 -0
  272. package/dist-lib/ui/windows/panels/ScriptSearch.d.ts +6 -1
  273. package/dist-lib/ui/windows/panels/TextPanel.d.ts +4 -1
  274. package/dist-lib/ui/windows/panels/VariablesView.d.ts +37 -7
  275. package/dist-lib/ui/windows/panels/WindowCmdLine.d.ts +4 -2
  276. package/dist-lib/ui/windows/panels/aliasLoop.d.ts +24 -0
  277. package/dist-lib/ui/windows/panels/editorClipboard.d.ts +45 -0
  278. package/dist-lib/ui/windows/panels/editorUndo.d.ts +79 -0
  279. package/dist-lib/ui/windows/panels/mapAreaChange.d.ts +10 -0
  280. package/dist-lib/utils/appShellCache.d.ts +25 -0
  281. package/dist-lib/utils/fontFamilyName.d.ts +13 -0
  282. package/dist-lib/utils/fontLoader.d.ts +31 -0
  283. package/dist-lib/utils/formatBytes.d.ts +4 -0
  284. package/dist-lib/utils/mustBeOneOf.d.ts +9 -0
  285. package/dist-lib/utils/profileLock.d.ts +1 -1
  286. package/dist-lib/utils/systemTheme.d.ts +24 -0
  287. package/dist-lib/utils/timeZone.d.ts +10 -0
  288. package/dist-lib/vault/CredentialVault.d.ts +51 -5
  289. package/dist-lib/vault/deviceUnlock.d.ts +47 -0
  290. package/dist-lib/vault/vaultAccess.d.ts +24 -2
  291. package/dist-lib/vault/vaultHelpTopic.d.ts +9 -0
  292. package/dist-lib/vault/vaultRecord.d.ts +33 -1
  293. package/dist-lib/vfs-sw.js +220 -11
  294. package/dist-lib/vite.d.ts +1 -1
  295. package/dist-lib/vite.js +66 -43
  296. package/package.json +22 -14
  297. package/dist-lib/assets/mapParser.worker-t-3rd1zR.js +0 -9
  298. package/dist-lib/mud/connection/PingTracker.d.ts +0 -41
  299. package/dist-lib/ui/BundledGameGrid.d.ts +0 -21
  300. package/dist-lib/ui/ConnectionGrid.d.ts +0 -21
  301. package/dist-lib/ui/bufferWords.d.ts +0 -38
@@ -2,6 +2,7 @@ import { EventBus } from "../../core/EventBus";
2
2
  import { AnsiAwareBuffer } from "../text/FormatState";
3
3
  import { type ChunkProcessor } from "../triggers/ChunkProcessor";
4
4
  import type { MudClientEvents } from "../events";
5
+ import { type TelnetNegotiatorFlags } from "./TelnetNegotiator";
5
6
  export type { MudClientEvents } from "../events";
6
7
  export { SUPPORTED_SERVER_ENCODINGS, DEFAULT_SERVER_ENCODING, canonicalServerEncoding, canEncodeForServer } from "../protocol";
7
8
  export interface MudClientOptions {
@@ -38,11 +39,11 @@ export interface MudClientOptions {
38
39
  * MUDs render as replacement chars). */
39
40
  charsetEnabled?: boolean;
40
41
  /** Whether to enable MSP (MUD Sound Protocol, telnet option 90). Default
41
- * false. When true the client negotiates the option and strips inline
42
- * `!!SOUND(...)` / `!!MUSIC(...)` tags from MUD text, dispatching them
43
- * as `msp` events. Always parses subnegotiations regardless of this flag
44
- * once negotiated, but in-band parsing is gated to avoid eating literal
45
- * text on MUDs that don't speak MSP. */
42
+ * false. When true the client negotiates the option; commands then arrive
43
+ * as `IAC SB MSP` subnegotiations and are dispatched as `msp` events.
44
+ * Inline `!!SOUND(...)` / `!!MUSIC(...)` tags in MUD text are never
45
+ * parsed — as in Mudlet, they stay in the line for triggers to handle
46
+ * (typically via `receiveMSP`). */
46
47
  mspEnabled?: boolean;
47
48
  /** Whether to accept MXP (telnet option 91) negotiation. Default true.
48
49
  * When false, IAC WILL/DO MXP is ignored so the server never sees a
@@ -62,15 +63,8 @@ export interface MudClientOptions {
62
63
  * client reports the five core variables plus an extended capability set
63
64
  * (ANSI, 256_COLORS, TRUECOLOR, UTF-8, TLS, WORD_WRAP, …), framed as
64
65
  * NEW_ENVIRON_USERVAR. Mudlet exposes MNES and NEW-ENVIRON as two separate
65
- * toggles over the same telnet option; mudix mirrors that. */
66
+ * toggles over the same telnet option; Mudlet Web mirrors that. */
66
67
  newEnvironEnabled?: boolean;
67
- /** Whether the link to the *game server* is TLS-encrypted, reported as the
68
- * NEW-ENVIRON `TLS` capability. Defaults to whether `url` is `wss://` — the
69
- * correct answer for a direct websocket-mode connection. In proxy (`mud`)
70
- * mode the caller passes the answer explicitly, because a `wss://` proxy URL
71
- * only secures the browser↔proxy hop: the proxy↔MUD leg is plaintext telnet
72
- * unless the profile enabled TLS (see connectionSecureTransport). */
73
- secureTransport?: boolean;
74
68
  /** Whether to advertise screen-reader use, reported as the MTTS SCREEN
75
69
  * READER bit and the NEW-ENVIRON `SCREEN_READER` capability
76
70
  * (`setConfig("advertiseScreenReader", …)`). Default false. */
@@ -88,10 +82,10 @@ export interface MudClientOptions {
88
82
  nawsEnabled?: boolean;
89
83
  /** Mudlet's "Fix unnecessary linebreaks on GA servers"
90
84
  * (`setConfig("fixUnnecessaryLinebreaks", …)`, host flag
91
- * `mUSE_IRE_DRIVER_BUGFIX`). Default false. When true *and* the session is
92
- * GA-driven, a single spurious leading newline is stripped from the start
93
- * of each GA-terminated data block — the IRE-server bug Mudlet patches in
94
- * `cTelnet::gotPrompt`. See LineAssembler. */
85
+ * `mUSE_IRE_DRIVER_BUGFIX`). Default false. When true, a single spurious
86
+ * leading newline is stripped from the start of each block of a read that
87
+ * ends in GA/EOR — the IRE-server bug Mudlet patches in
88
+ * `cTelnet::gotPrompt`. See LineAssembler.stripPromptBlockNewline. */
95
89
  fixUnnecessaryLinebreaks?: boolean;
96
90
  /** Mudlet's `Host::mUndoServerWrap` — rejoin the lines the game wrapped
97
91
  * itself, so triggers and rendering see whole logical lines. Default false.
@@ -141,7 +135,7 @@ export interface MudClientOptions {
141
135
  /** WebSocket subprotocols to advertise in the opening handshake's
142
136
  * `Sec-WebSocket-Protocol` header (RFC 6455), in preference order — the
143
137
  * server selects at most one. Mutually-exclusive stream *modes*, not layers:
144
- * `binary` (raw telnet over binary frames — the mode mudix decodes),
138
+ * `binary` (raw telnet over binary frames — the mode Mudlet Web decodes),
145
139
  * `telnet` (FluffOS's equivalent name), `telnet.mudstandards.org` (the
146
140
  * mudstandards.org proposal). Empty means open a bare socket. Advertising is
147
141
  * a trade-off: some servers (FluffOS) route a *no-subprotocol* upgrade to a
@@ -152,10 +146,13 @@ export interface MudClientOptions {
152
146
  subprotocols?: string[];
153
147
  }
154
148
  /** The WebSocket subprotocol name for the mudstandards.org "full telnet stream
155
- * over binary frames" profile (https://mudstandards.org/websocket/). mudix
149
+ * over binary frames" profile (https://mudstandards.org/websocket/). Mudlet Web
156
150
  * already speaks this wire format; advertising the name lets a conforming
157
151
  * server confirm the dialect via the RFC 6455 handshake. */
158
152
  export declare const MUD_TELNET_SUBPROTOCOL = "telnet.mudstandards.org";
153
+ /** Whether a slice that has run `elapsed` ms should give the event loop its
154
+ * turn. Exported for the tests. */
155
+ export declare function inboundSliceDue(elapsed: number, hasInput?: () => boolean): boolean;
159
156
  /**
160
157
  * The MUD-facing transport: telnet over a WebSocket (direct or via the
161
158
  * telnet→WebSocket proxy). Owns the socket lifecycle and the outbound send
@@ -180,6 +177,16 @@ export declare class MudClient {
180
177
  private readonly mccpHandler;
181
178
  private readonly echoHandler;
182
179
  private readonly negotiator;
180
+ /** Writes back the IAC SE a server left off a subnegotiation, before any
181
+ * inbound parser reads the bytes (see SubnegotiationRepair). */
182
+ private readonly subnegRepair;
183
+ /** The negotiator's option toggles, held here because they are the
184
+ * profile's and the profile can change under a live connection. Mudlet
185
+ * reads `mEnableMSSP` and friends at negotiation time, so a setting
186
+ * switched off mid-session must be obeyed by the next offer rather than
187
+ * by the next dial. Mutated in place by setProtocolFlags — the
188
+ * negotiator holds this same object. */
189
+ private readonly negotiatorFlags;
183
190
  /** Latches once `sysCharacterModeDetected` has fired for this connection so
184
191
  * the warning isn't repeated. Reset on each connect(). See
185
192
  * {@link checkCharacterModePattern}. */
@@ -196,27 +203,57 @@ export declare class MudClient {
196
203
  * GA-driven prompt flushing, the idle-flush safety net). */
197
204
  private readonly assembler;
198
205
  private readonly url;
199
- /** Buffers the start of a subnegotiation that arrived without its closing IAC SE. */
200
- private pendingSubneg;
206
+ /** Buffers a telnet sequence the frame ended in the middle of — a lone
207
+ * IAC, an option command missing its option byte, or a subnegotiation
208
+ * without its closing IAC SE — until the next frame completes it. */
209
+ private pendingTelnet;
201
210
  /** True once the WebSocket handshake has completed; used to differentiate
202
211
  * "failed to connect" from "connection lost mid-session" in close events. */
203
212
  private opened;
204
- /** True once we've sent the GMCP `Core.Hello` / `Core.Supports.Set`
205
- * handshake this session, so a server that re-offers GMCP doesn't make us
206
- * announce ourselves twice. Reset on each connect(). */
207
- private gmcpHelloSent;
213
+ /** When the game command now awaiting a reply went out (`performance.now()`),
214
+ * or null when nothing is being timed. Mudlet's
215
+ * `cTelnet::begin/finishNetworkLatencyMeasurement`: on a server that marks
216
+ * its prompts with GA/EOR, the time from a command to the first read
217
+ * off the socket after it is the network latency `getNetworkLatency()` reports
218
+ * — the only reading there is, as Mudlet sends no GMCP `Core.Ping`. Timed from the first command of a
219
+ * burst, so a queued speedwalk isn't credited with the replies to its
220
+ * earlier steps. */
221
+ private latencyStartedAt;
208
222
  /** Set when this dial asked the proxy for TLS (`&tls=1` in the URL), so the
209
223
  * client knows to expect a `tls.established` control frame and to police
210
224
  * the deadline below. */
211
225
  private readonly tlsRequested;
226
+ /** Whether this socket goes to a telnet proxy rather than to the game. Only
227
+ * the wording of a connection error depends on it. */
228
+ private readonly viaProxy;
212
229
  /** True once the proxy confirmed the handshake, or once any game bytes have
213
230
  * arrived (which can only happen through a working tunnel). */
214
231
  private tlsResolved;
215
232
  private tlsDeadline;
233
+ /** The proxy reported a completed TLS handshake with the game on this
234
+ * socket. Half of {@link gameTransportSecure}. */
235
+ private tlsEstablishedThisSocket;
236
+ /** The negotiated `Char.Login` version — `min(client, server)`, learned
237
+ * from `Char.Login.Default` and echoed back on every client→server message
238
+ * so both ends agree on it even though base GMCP negotiation is
239
+ * one-directional. 1 until a server says otherwise, which is also the
240
+ * right answer for a version 1 server. Per socket: reset on connect, not on
241
+ * each `Char.Login.Default` (Mudlet splits resetForNewConnection and
242
+ * resetPerConnectionState the same way). */
243
+ private charLoginVersion;
244
+ /** True once `client.established` has been emitted for the current socket —
245
+ * the several signals that can prove the game leg is up all funnel through
246
+ * {@link markEstablished}, and only the first of them counts. */
247
+ private gameEstablished;
248
+ /** Fires while the game has been silent for {@link IDLE_PROBE_MS}; see
249
+ * {@link probeIdleConnection}. */
250
+ private idleProbe;
251
+ /** `performance.now()` of the last game frame on the current socket. */
252
+ private lastInboundAt;
253
+ /** True once the server has sent a telnet command (any IAC) on the current
254
+ * socket — only then is an `IAC NOP` probe something it knows to ignore. */
255
+ private telnetSeen;
216
256
  commandEcho: boolean;
217
- /** Gates the in-band `!!SOUND(...)` / `!!MUSIC(...)` tag parsing — the tag
218
- * bytes are legitimate text on non-MSP MUDs. */
219
- private readonly mspEnabled;
220
257
  private readonly mspParser;
221
258
  /** WebSocket subprotocols advertised on connect (see MudClientOptions). */
222
259
  private readonly subprotocols;
@@ -233,7 +270,7 @@ export declare class MudClient {
233
270
  /** Handed to the telnet sequence parser and mutated in place, so the parser
234
271
  * reads the current setting rather than the one it was built with. */
235
272
  private readonly telnetParserOpts;
236
- constructor({ url, mccpEnabled, commandEcho, chunkProcessor, promptTimeoutMs, gmcpEnabled, mttsEnabled, msdpEnabled, msspEnabled, charsetEnabled, mspEnabled, mxpEnabled, mnesEnabled, newEnvironEnabled, secureTransport, screenReaderAdvertised, osc8HyperlinksEnabled, nawsEnabled, fixUnnecessaryLinebreaks, undoServerWrap, undoServerWrapWidth, inputLineStrictUnixEndings, specialForceGAOff, versionInTTYPE, promptForVersionInTTYPE, promptForMXPProcessorOn, specialForceMXPProcessorOn, subprotocols, }: MudClientOptions, eventBus: EventBus<MudClientEvents>);
273
+ constructor({ url, mccpEnabled, commandEcho, chunkProcessor, promptTimeoutMs, gmcpEnabled, mttsEnabled, msdpEnabled, msspEnabled, charsetEnabled, mspEnabled, mxpEnabled, mnesEnabled, newEnvironEnabled, screenReaderAdvertised, osc8HyperlinksEnabled, nawsEnabled, fixUnnecessaryLinebreaks, undoServerWrap, undoServerWrapWidth, inputLineStrictUnixEndings, specialForceGAOff, versionInTTYPE, promptForVersionInTTYPE, promptForMXPProcessorOn, specialForceMXPProcessorOn, subprotocols, }: MudClientOptions, eventBus: EventBus<MudClientEvents>);
237
274
  /** Mudlet-parity character-at-a-time detection (cTelnet::sendData's
238
275
  * `armCharacterModeDetection`). ECHO+SGA on its own is *not* the signature:
239
276
  * an ordinary line-mode server masking a password negotiates exactly the
@@ -260,7 +297,7 @@ export declare class MudClient {
260
297
  setMccpEnabled(enabled: boolean): void;
261
298
  isMccpEnabled(): boolean;
262
299
  /** Mudlet `setConfig("fixUnnecessaryLinebreaks", …)`. Takes effect on the
263
- * next GA-driven block; never retroactive. */
300
+ * next block that ends in a prompt marker; never retroactive. */
264
301
  setFixUnnecessaryLinebreaks(enabled: boolean): void;
265
302
  /**
266
303
  * Mudlet `setConfig("specialForceGAOff", …)`. Only an UNCONNECTED client
@@ -286,15 +323,59 @@ export declare class MudClient {
286
323
  addSupportedTelnetOption(option: number): boolean;
287
324
  setPromptTimeoutMs(ms: number): void;
288
325
  getPromptTimeoutMs(): number;
326
+ /** True once the server has sent IAC GA / IAC EOR at least once — Mudlet's
327
+ * `cTelnet::mGA_Driver`. Prompt-line triggers only ever fire on a game
328
+ * that sends one, so the editor greys the `prompt` pattern type without it
329
+ * (dlgTriggerEditor.cpp:7226-7234). */
330
+ get promptMarkerSeen(): boolean;
289
331
  connect(): void;
332
+ /** Announce that the link to the game itself is up, once per socket —
333
+ * Mudlet's `slot_socketConnected`, which is both where it says so
334
+ * (`client.connect` → "Open connection made.", sysConnectionEvent) and
335
+ * where `mConnectionTimer` starts (`client.established`). */
336
+ private markEstablished;
337
+ /** Whether the current socket ever reached the game — false for an attempt
338
+ * that failed before connecting (Mudlet's `slot_socketError` case). */
339
+ get established(): boolean;
290
340
  /** Stop policing the TLS deadline — the handshake is accounted for. */
291
341
  private resolveTls;
292
342
  /** Decode one proxy control frame. Anything unrecognised is ignored so a
293
343
  * newer proxy can add message types without breaking older clients. */
294
344
  private handleControlFrame;
295
345
  disconnect(): void;
346
+ /** A disconnect() whose events are still waiting on unwritten output. */
347
+ private pendingDisconnect;
348
+ /** The tail of disconnect(), once the socket is really gone. */
349
+ private finishDisconnect;
350
+ private armIdleProbe;
351
+ private stopIdleProbe;
352
+ /** Make a long-silent connection prove it is still there (issue #454). A
353
+ * game host that dies without closing leaves the WebSocket looking healthy
354
+ * — through a proxy the browser's leg really is — so nothing ever closes,
355
+ * nothing reconnects, and the player's next command goes into the dead
356
+ * socket. An `IAC NOP` costs the game nothing (telnet servers discard it),
357
+ * but it puts bytes on every leg: a peer that has come back answers them
358
+ * with a reset, one that is gone fails their retransmission, and either
359
+ * way the socket errors and closes, which is the ordinary disconnect and
360
+ * auto-reconnect path. It also keeps a NAT from forgetting a quiet flow.
361
+ *
362
+ * This is the client's own check, for a direct `ws(s)://` endpoint or a
363
+ * proxy without TCP keepalive. The bundled proxy keeps that watch on the
364
+ * game socket itself (`proxy/gameSocket.ts`) and finds a dead peer in about
365
+ * 70 s — before this probe's first NOP, which would otherwise hold off its
366
+ * keepalive by leaving data unacknowledged. */
367
+ private probeIdleConnection;
368
+ /** Raise the disconnect, then hand over the text the final flush left in
369
+ * the message buffer. cTelnet raises sysDisconnectionEvent first and only
370
+ * then is the unterminated last line printed and its triggers run — a
371
+ * `"Server full, bye"` sent without a newline before the close still
372
+ * reaches the screen, the buffer and the trigger engine, just after the
373
+ * event. Before the notices `client.disconnected` posts, which follow it
374
+ * on desktop too. */
375
+ private emitDisconnect;
296
376
  /** Whether MSP is live on this connection (negotiated, not merely allowed
297
377
  * by the profile config) — gates Mudlet's receiveMSP. */
378
+ isGmcpEnabled(): boolean;
298
379
  isMspNegotiated(): boolean;
299
380
  /** Qt's QAbstractSocket::UnconnectedState — no socket at all, or one that
300
381
  * has finished closing. CONNECTING/OPEN/CLOSING are all "not unconnected",
@@ -308,10 +389,17 @@ export declare class MudClient {
308
389
  * character-at-a-time detection. Credentials and internal protocol replies
309
390
  * route through here too and must not. */
310
391
  send(message: string, isGameCommand?: boolean): void;
392
+ /** Start timing a command's round trip — only once the server has shown it
393
+ * marks prompts (GA/EOR latched), since without a marker there is no
394
+ * "reply arrived" to stop at. See {@link latencyStartedAt}. */
395
+ private beginLatencyMeasurement;
396
+ /** Stop the clock at the first socket read after a timed command and
397
+ * publish the reading (ms) as `network.latency`. */
398
+ private finishLatencyMeasurement;
311
399
  private sendRaw;
312
400
  /** Encodes a Latin-1 byte-string to raw bytes and sends it as a binary
313
401
  * WebSocket frame. The proxy worker expects binary, not base64. Every
314
- * outbound byte funnels through here, so it's also where `mudix.debugTelnet`
402
+ * outbound byte funnels through here, so it's also where `mudlet.debugTelnet`
315
403
  * mirrors what we send. */
316
404
  private sendBytes;
317
405
  sendGmcp(path: string, payload?: unknown): void;
@@ -319,39 +407,103 @@ export declare class MudClient {
319
407
  * Mudlet does: `Core.Hello` identifies the client (name + version) and
320
408
  * `Core.Supports.Set` lists the GMCP modules we understand. Many servers
321
409
  * won't push any GMCP data (room, char, vitals, …) until they've received
322
- * this hello, so without it GMCP effectively does nothing. Latched so a
323
- * repeated WILL/DO GMCP doesn't re-announce. Reports our own identity
410
+ * this hello, so without it GMCP effectively does nothing. Every server
411
+ * offer (IAC WILL GMCP) is answered with it, as Mudlet does: a server that
412
+ * turned GMCP off and on again — copyover, reboot — has dropped the module
413
+ * list and would otherwise never send another packet. A server's IAC DO
414
+ * GMCP is answered with WILL alone, as Mudlet does — the handshake waits
415
+ * for the server's own offer (mudlet-web#362). Reports our own identity
324
416
  * (see src/version.ts), matching the TTYPE/MNES/MXP handshakes. */
325
417
  private sendGmcpHandshake;
326
- /** Route GMCP `Char.Login.*` messages. The server sends `Char.Login.Default
327
- * { "type": [...] }` to request login and then *waits* for the client to
328
- * supply credentials — withholding the normal text "By what name…" prompt
329
- * until it hears back (servers that do this gate on the `Char.Login` module
330
- * we advertise in `Core.Supports.Set`). We surface it as `charLogin.request`
331
- * so the UI can pop a credentials form; the UI replies via
332
- * `sendCharLoginCredentials`, or an empty reply (cancel) to fall back to the
333
- * text login (the behaviour Mudlet/Mudlet#7377 is about). `Char.Login.Result`
334
- * carries the outcome. Path match is case-insensitive — GMCP module casing
335
- * varies between servers. */
418
+ /**
419
+ * Whether the link to the *game* is encrypted — Mudlet's
420
+ * `cTelnet::currentlySecure()`, and the gate on every `Char.Login` bearer
421
+ * secret. Not "is the WebSocket wss:": in proxy mode a `wss://` proxy URL
422
+ * only secures the browser↔proxy hop, and the proxy↔game leg is plaintext
423
+ * telnet unless the proxy reports a completed TLS handshake with the game.
424
+ * A direct websocket connection is the game, so its scheme is the answer.
425
+ */
426
+ get gameTransportSecure(): boolean;
427
+ /** The `Char.Login` version negotiated on this socket. */
428
+ get negotiatedCharLoginVersion(): number;
429
+ /** Route GMCP `Char.Login.*` messages. The server sends `Char.Login.Default`
430
+ * to request login and then *waits* for the client to answer — withholding
431
+ * its normal text "By what name…" prompt until it hears back (servers that
432
+ * do this gate on the `Char.Login` module we advertise in
433
+ * `Core.Supports.Set`). Each message is parsed here and surfaced as a
434
+ * `charLogin.*` event; `CharLoginController` decides what to answer. Path
435
+ * match is case-insensitive — GMCP module casing varies between servers.
436
+ *
437
+ * `Char.Login.Token` carries a bearer token that signs the profile in
438
+ * without a password. It is never logged — a malformed frame reports
439
+ * nothing of its body. It does still reach the Lua `gmcp` table like any
440
+ * other message, as it does in Mudlet (cTelnet calls setGMCPTable for
441
+ * Char.Login too); profile scripts already run with full access to this
442
+ * profile. JS strings are immutable and garbage-collected, so Mudlet's
443
+ * SecureStringUtils scrubbing has no equivalent here. */
336
444
  private handleCharLogin;
337
- /** Send the GMCP `Char.Login.Credentials` reply. With an account, sends
338
- * `{ account, password }` (account may be `"account:character"` for games
339
- * with both); with no account it sends the empty `{}` form — the spec's
340
- * "no credentials, fall back to your next auth method" signal, used when the
341
- * user cancels the popup. mudix never stores the password; it only relays it. */
342
- sendCharLoginCredentials(account?: string, password?: string): void;
445
+ /** The two fields every client→server `Char.Login` message may carry: the
446
+ * negotiated version we are acting on, and `token_storage` — whether a
447
+ * reconnect token minted on this connection would actually be kept. A
448
+ * version 1 server gets them too: an unknown member is inert to it. */
449
+ private charLoginCommonFields;
450
+ /**
451
+ * Send `Char.Login.Credentials`. With an account, `{account, password}`
452
+ * (account may be `"account:character"` on games with both) plus the common
453
+ * fields. Without one it is the hand-off: from version 2 the message with no
454
+ * account — carrying `token_storage` is the point, since it reaches the game
455
+ * before it writes its sign-in screen, the last moment it can decide whether
456
+ * to offer to remember the player — and on version 1 the bare `{}` Mudlet
457
+ * has always sent such servers. Mudlet Web never stores the password here;
458
+ * it only relays it.
459
+ */
460
+ sendCharLoginCredentials(account?: string, password?: string, tokenStorage?: boolean): void;
461
+ /**
462
+ * Replay a saved password-less sign-in — `Char.Login.Reconnect`. Returns
463
+ * false when it refused: a token the issuing server scoped to an encrypted
464
+ * transport (`secureOnly`) never goes out in the clear. Re-checked here, at
465
+ * send time, as well as in the decision, in case the transport changed.
466
+ */
467
+ sendCharLoginReconnect(account: string, token: string, secureOnly: boolean, tokenStorage?: boolean): boolean;
468
+ /** Ask the game to restart a provider's browser sign-in — the *resume* form
469
+ * of `Char.Login.Credentials`, `{account, provider}` and no password. */
470
+ sendCharLoginResume(account: string, provider: string, tokenStorage?: boolean): void;
471
+ /**
472
+ * Complete a client-driven OAuth sign-in — `Char.Login.AuthCode`. Returns
473
+ * false when it refused: the standard forbids it on a cleartext connection,
474
+ * since the code and PKCE verifier together let an eavesdropper redeem the
475
+ * code at the provider.
476
+ */
477
+ sendCharLoginAuthCode(auth: {
478
+ code: string;
479
+ codeVerifier: string;
480
+ redirectUri: string;
481
+ nonce?: string;
482
+ }, tokenStorage?: boolean): boolean;
343
483
  sendGmcpRaw(message: string): void;
344
484
  /** Mudlet `sendMSDP(variable, ...values)`. Frames + sends an MSDP
345
485
  * subnegotiation. Returns false when the socket isn't open. */
346
486
  sendMSDP(variable: string, values: string[]): boolean;
347
487
  /** Mudlet `sendATCP(message)`. Frames `IAC SB ATCP <message> IAC SE` (ATCP =
348
488
  * telnet option 200, GMCP's predecessor) and sends it raw. Returns false
349
- * when the socket isn't open. */
489
+ * when ATCP isn't negotiated or the socket isn't open. */
350
490
  sendATCP(message: string): boolean;
351
491
  /** Mudlet `sendTelnetChannel102(msg)`. Frames `IAC SB 102 <msg> IAC SE`
352
- * (the zMUD generic out-of-band channel) and sends it raw. Returns false
353
- * when the socket isn't open. */
492
+ * (the zMUD generic out-of-band channel) and sends it raw. False only
493
+ * when the server has not enabled the channel: Mudlet gates on that
494
+ * alone and reports success whatever the socket then does with the
495
+ * bytes, so a script is told about the option and not the connection. */
354
496
  sendTelnetChannel102(msg: string): boolean;
497
+ /** An `IAC SB 102 <var> <value> IAC SE` body: the option byte, then the
498
+ * two payload bytes Aardwolf's channel carries. Mudlet reads them as
499
+ * numbers (`setChannel102Variables`) and ignores anything shorter. */
500
+ private handleChannel102Subneg;
501
+ /** An `IAC SB ATCP <message> IAC SE` body — Mudlet's ATCP branch of
502
+ * `processTelnetCommand`. The message, decoded under the server encoding,
503
+ * becomes one `atcp` table entry and event (`setATCPVariables`); an empty
504
+ * one is ignored. `Auth.Request` is then answered with the hello. Like
505
+ * desktop, neither depends on ATCP having been negotiated. */
506
+ private handleAtcpSubneg;
355
507
  /** Frame an `IAC SB <opt> <payload> IAC SE` subnegotiation and send it.
356
508
  * `payload` must already be a Latin-1 byte-string (each char → one byte)
357
509
  * with any IAC handled — the framing is all this does, since ATCP and
@@ -364,8 +516,23 @@ export declare class MudClient {
364
516
  getServerEncoding(): string;
365
517
  /** Mudlet `setServerEncoding(name)`. Switch the inbound decoder to `name`
366
518
  * (any value from getServerEncodingsList()). Returns false — leaving the
367
- * current encoding untouched — when the name isn't one we can decode. */
519
+ * current encoding untouched — when the name isn't one we can decode.
520
+ *
521
+ * Asked for while a read's text is being decoded — by one of its
522
+ * triggers — the switch waits for the next text to be decoded: TBuffer
523
+ * reads cTelnet's encoding once, at the start of each translateToPlainText,
524
+ * so the rest of the read keeps the encoding it arrived in. That next text
525
+ * is the next read, or a feed the trigger makes of its own
526
+ * ({@link adoptPendingEncoding}), which then applies to the rest of the
527
+ * read as well. */
368
528
  setServerEncoding(name: string): boolean;
529
+ /** Apply a setServerEncoding() a trigger made part way through a read —
530
+ * where TBuffer::translateToPlainText would next read the encoding. */
531
+ adoptPendingEncoding(): void;
532
+ /** True while a read's text is decoded and handed to its triggers. */
533
+ private decodingRead;
534
+ /** An encoding a trigger switched to while {@link decodingRead}. */
535
+ private pendingEncoding;
369
536
  /** Route an `IAC SB MSP ... IAC SE` body to the MSP parser and dispatch
370
537
  * any parsed commands as `msp` events. Always runs when an MSP subneg
371
538
  * arrives — once the server has bothered to wrap a tag, we trust it. */
@@ -373,18 +540,89 @@ export declare class MudClient {
373
540
  /** Report the main output window's character grid (columns × rows) for NAWS.
374
541
  * The session calls this on every output-area resize. See TelnetNegotiator. */
375
542
  setWindowSize(cols: number, rows: number): void;
543
+ /** Report the main console's wrap column (Mudlet's `Host::mWrapAt`, 0 for
544
+ * off), which caps the NAWS width and is the NEW-ENVIRON WORD_WRAP. */
545
+ setWrapAt(wrapAt: number): void;
546
+ /** Report whether the main console draws its timestamp gutter, which comes
547
+ * off the NAWS width as on desktop. */
548
+ setTimestampsShown(shown: boolean): void;
376
549
  /** Mudlet `sendSocket(data)`. Sends literal bytes over the socket with no
377
550
  * telnet/encoding processing (each char becomes one byte). Returns false
378
551
  * when the socket isn't open. */
379
552
  sendSocket(data: string): boolean;
553
+ /** Apply changed profile protocol toggles to the live connection. Only
554
+ * the ones the negotiator reads: the rest of MudClientOptions is either
555
+ * fixed at dial time (the URL, the subprotocols) or owned by a handler
556
+ * with a setter of its own (MCCP). */
557
+ setProtocolFlags(flags: Partial<TelnetNegotiatorFlags>): void;
380
558
  /** Mudlet `feedTelnet(data)`. Injects raw bytes into the inbound pipeline
381
559
  * as if they had arrived from the server — they pass through telnet
382
560
  * stripping, ANSI parsing, the trigger pipeline, and rendering. `data` is
383
561
  * treated as a Latin-1 byte-string (matching incoming-frame handling). */
384
562
  feedTelnet(data: string): void;
563
+ /** A chunk of a replay. A replay holds what the game sent after
564
+ * decompression, and desktop plays it back through a parser of its own
565
+ * (cTelnet::slot_processReplayChunk) that knows nothing of MCCP, so
566
+ * unlike {@link feedTelnet} this skips it. */
567
+ feedReplay(data: string): void;
568
+ /** One read from the game, or bytes injected as if they were one: split
569
+ * where compression starts or ends, and each piece run through the
570
+ * pipeline on its own. Desktop processes the plain text before an MCCP
571
+ * start (gotRest) before it inflates anything, and the inflated text
572
+ * before what follows the end of the stream, so a trigger on the last
573
+ * line of one part never sees GMCP from the next (mudlet-web#384). The
574
+ * MCCP warnings desktop posts while inflating land between the pieces,
575
+ * where it posts them. Synchronous: the whole read is through when this
576
+ * returns. Socket reads go through {@link pumpInbound} instead. */
577
+ private ingest;
578
+ private readonly inbound;
579
+ /** A slice is running: a drain from inside one (a trigger calling
580
+ * disconnect(), say) leaves the rest of the read to the slices. */
581
+ private inboundRunning;
582
+ private inboundScheduled;
583
+ /** Run a slice of the queued socket reads, and book the next if any are
584
+ * left. */
585
+ private pumpInbound;
586
+ /** Run every queued socket read now, unless a slice is already running. */
587
+ private drainInbound;
588
+ /** Forget the queued reads not yet begun, when a trigger in a slice lets
589
+ * go of the socket: their onmessage would have found its handler gone.
590
+ * The rest of the read the trigger is in carries on, as it always has. */
591
+ private dropQueuedReads;
592
+ /** Take reads off the head of `queue` and through the pipeline. In a
593
+ * `slice`, text goes in INBOUND_SLICE_LINES lines at a time, and this
594
+ * returns false — the rest still queued — once the slice's time is up
595
+ * and the stream is at a clean break. */
596
+ private runInbound;
385
597
  output(text?: string | AnsiAwareBuffer, type?: string, timestamp?: number): void;
386
598
  /** Push a line directly into the message buffer for trigger processing + rendering via flushLines. */
387
599
  pushLine(text: string, type: string): void;
600
+ /** `receivedAt` (`performance.now()`) is given only for bytes read off the
601
+ * socket, so injected ones (feedTelnet, replay) never stop the latency
602
+ * clock. */
388
603
  private processIncomingData;
604
+ /** Negotiate, strip, decode and assemble one run of a frame. `hasPrompt`
605
+ * means the run ends in an IAC GA/EOR. */
606
+ private processSegment;
607
+ private decodeAndAssemble;
389
608
  flushMessageBuffer(): void;
390
609
  }
610
+ /** How long the game may stay silent before the client probes the connection
611
+ * with an `IAC NOP` (and again each time as long again passes). Past the
612
+ * ~70 s the bundled proxy's keepalive takes, so the two don't overlap. */
613
+ export declare const IDLE_PROBE_MS = 120000;
614
+ /**
615
+ * What to tell the user about a socket that closed.
616
+ *
617
+ * `viaProxy` distinguishes the two very different things a close can mean. In
618
+ * proxy mode the socket is to the proxy, so "the proxy refused it" is a real
619
+ * possibility; in websocket mode no proxy is involved at all, and blaming one
620
+ * sent people to check infrastructure that was not in the path (issue #56).
621
+ *
622
+ * A connect that never opened also gets the advice Mudlet gives, because the
623
+ * cause is not decidable from here: a Cloudflare-Worker proxy reports the same
624
+ * "cannot connect to the specified address" for a hostname that does not
625
+ * resolve and for a port with nothing listening, and `connect()` exposes
626
+ * nothing finer. Naming both possibilities beats implying one.
627
+ */
628
+ export declare function formatCloseError(event: CloseEvent, wasOpened: boolean, viaProxy: boolean): string;
@@ -0,0 +1,24 @@
1
+ /**
2
+ * Closes a subnegotiation that runs into the next telnet command without its
3
+ * IAC SE, the way Mudlet's `cTelnet::processSocketData` recovers one (#4385):
4
+ * inside IAC SB, an IAC followed by anything but SE or a second IAC cannot be
5
+ * part of the payload, so the SE is taken to have gone missing. The
6
+ * subnegotiation is ended there and the IAC starts the next command.
7
+ *
8
+ * Done once, on the byte stream every inbound parser reads (the negotiator, the
9
+ * ECHO scan, the option parser), by writing the missing SE back in — so they
10
+ * all agree on where the subnegotiation ended, rather than one acting on the
11
+ * command and another swallowing it into a payload. Stateful across frames: an
12
+ * SB, or the IAC deciding it, can be split between two reads, and an IAC at the
13
+ * end of a frame is passed on as it is, since the SE that may follow it goes
14
+ * after it either way.
15
+ */
16
+ export declare class SubnegotiationRepair {
17
+ private inSb;
18
+ private iac;
19
+ private warned;
20
+ reset(): void;
21
+ /** `data` is a Latin-1 byte-string; returns it with any missing IAC SE
22
+ * written back in. */
23
+ process(data: string): string;
24
+ }