diff options
| author | David Skoland <davidskoland@gmail.com> | 2026-02-07 21:53:59 +0100 |
|---|---|---|
| committer | David Skoland <davidskoland@gmail.com> | 2026-02-07 21:53:59 +0100 |
| commit | 95e4124b0c02b4e5be383c41ed4241566f40e6e6 (patch) | |
| tree | 0a51910da18759700b9e152aa428e76f055b8af4 | |
| parent | 5eeb7ac9d90137c3b5ce9578c47bcc2ccff21c7e (diff) | |
Prefetch char.ini for characters present in area via playerlist
Store player data (charId, area) in an in-memory Map on the client,
updated by PR/PU packet handlers. Use this to eagerly load char.ini
when a player's character appears in our area or when switching areas,
eliminating the lazy-load delay on first IC message.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
| -rw-r--r-- | webAO/client.ts | 2 | ||||
| -rw-r--r-- | webAO/dom/areaClick.ts | 8 | ||||
| -rw-r--r-- | webAO/packets/handlers/handlePR.ts | 9 | ||||
| -rw-r--r-- | webAO/packets/handlers/handlePU.ts | 20 |
4 files changed, 37 insertions, 2 deletions
diff --git a/webAO/client.ts b/webAO/client.ts index b7a15a4..95df67a 100644 --- a/webAO/client.ts +++ b/webAO/client.ts @@ -150,6 +150,7 @@ class Client extends EventEmitter { connect: () => void; loadResources: () => void; isLowMemory: () => void; + players: Map<number, { charId: number; area: number }>; charicon_extensions: string[]; emote_extensions: string[]; emotions_extensions: string[]; @@ -211,6 +212,7 @@ class Client extends EventEmitter { this.temp_packet = ""; loadResources; isLowMemory; + this.players = new Map(); this.charicon_extensions = [".png", ".webp"]; this.emote_extensions = [".gif", ".png", ".apng", ".webp", ".webp.static"]; this.emotions_extensions = [".png", ".webp"]; diff --git a/webAO/dom/areaClick.ts b/webAO/dom/areaClick.ts index 1e41f4b..19953a5 100644 --- a/webAO/dom/areaClick.ts +++ b/webAO/dom/areaClick.ts @@ -1,5 +1,6 @@ import { client } from "../client"; import { updatePlayerAreas } from "./updatePlayerAreas"; +import { ensureCharIni } from "../client/handleCharacterInfo"; /** * Triggered when an item on the area list is clicked. * @param {HTMLElement} el @@ -14,5 +15,12 @@ export function area_click(el: HTMLElement) { document.getElementById("client_log")!.appendChild(areaHr); client.area = Number(el.id.substring(4)); updatePlayerAreas(client.area); + + // Prefetch char.ini for all characters present in the new area + for (const player of client.players.values()) { + if (player.area === client.area && player.charId >= 0) { + ensureCharIni(player.charId); + } + } } window.area_click = area_click; diff --git a/webAO/packets/handlers/handlePR.ts b/webAO/packets/handlers/handlePR.ts index aeb3969..e39103d 100644 --- a/webAO/packets/handlers/handlePR.ts +++ b/webAO/packets/handlers/handlePR.ts @@ -53,6 +53,11 @@ function removePlayer(playerID: number) { */ export const handlePR = (args: string[]) => { const playerID = Number(args[1]); - if (Number(args[2]) === 0) addPlayer(playerID); - else if (Number(args[2]) === 1) removePlayer(playerID); + if (Number(args[2]) === 0) { + addPlayer(playerID); + client.players.set(playerID, { charId: -1, area: 0 }); + } else if (Number(args[2]) === 1) { + removePlayer(playerID); + client.players.delete(playerID); + } }; diff --git a/webAO/packets/handlers/handlePU.ts b/webAO/packets/handlers/handlePU.ts index 0f51029..d8d9b44 100644 --- a/webAO/packets/handlers/handlePU.ts +++ b/webAO/packets/handlers/handlePU.ts @@ -1,6 +1,7 @@ import { client } from "../../client"; import { updatePlayerAreas } from "../../dom/updatePlayerAreas"; import { AO_HOST } from "../../client/aoHost"; +import { ensureCharIni } from "../../client/handleCharacterInfo"; /** * Handles a playerlist update @@ -25,6 +26,18 @@ export const handlePU = (args: string[]) => { playerImg.src = `${AO_HOST}characters/${encodeURI(data.toLowerCase())}/char_icon${iconExt}`; const charName = <HTMLElement>playerRow.childNodes[1]; charName.innerText = `[${args[1]}] ${data}`; + const charId = client.chars.findIndex( + (c: any) => c && c.name.toLowerCase() === data.toLowerCase() + ); + if (charId >= 0) { + const player = client.players.get(Number(args[1])); + if (player) { + player.charId = charId; + if (player.area === client.area) { + ensureCharIni(charId); + } + } + } break; case 2: const showName = <HTMLElement>playerRow.childNodes[2]; @@ -33,6 +46,13 @@ export const handlePU = (args: string[]) => { case 3: playerRow.className = `area${data}`; updatePlayerAreas(client.area); + const puPlayer = client.players.get(Number(args[1])); + if (puPlayer) { + puPlayer.area = Number(data); + if (puPlayer.area === client.area && puPlayer.charId >= 0) { + ensureCharIni(puPlayer.charId); + } + } default: break; } |
