aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDavid Skoland <davidskoland@gmail.com>2026-02-07 21:53:59 +0100
committerDavid Skoland <davidskoland@gmail.com>2026-02-07 21:53:59 +0100
commit95e4124b0c02b4e5be383c41ed4241566f40e6e6 (patch)
tree0a51910da18759700b9e152aa428e76f055b8af4
parent5eeb7ac9d90137c3b5ce9578c47bcc2ccff21c7e (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.ts2
-rw-r--r--webAO/dom/areaClick.ts8
-rw-r--r--webAO/packets/handlers/handlePR.ts9
-rw-r--r--webAO/packets/handlers/handlePU.ts20
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;
}