MSAgent-Chat/msagent.js/src/character.ts

76 lines
2.1 KiB
TypeScript
Raw Normal View History

import { BufferStream, SeekDir } from './buffer.js';
import { LOCATION } from './structs/core.js';
import { AcsCharacterInfo } from './structs/character.js';
import { AcsAnimationEntry } from './structs/animation.js';
import { AcsImageEntry } from './structs/image.js';
2024-07-09 19:47:10 -04:00
import { Agent } from './agent.js';
// Data
2024-07-09 19:47:10 -04:00
export class AcsData {
characterInfo = new AcsCharacterInfo();
animInfo: AcsAnimationEntry[] = [];
images: AcsImageEntry[] = [];
}
// Cache of ACS data per character (for agentCreateCharacterFromUrl)
let acsDataCache = new Map<string, AcsData>();
// Purges the ACS cache.
export function agentPurgeACSCache() {
acsDataCache.clear();
}
export function agentCharacterParseACS(buffer: BufferStream): AcsData {
// Make sure the magic is correct for the ACS file.
if (buffer.readU32LE() != 0xabcdabc3) {
throw new Error('The provided data buffer does not contain valid ACS data.');
}
let acsData = new AcsData();
// Read the rest of the header.
let characterInfoLocation = LOCATION.read(buffer);
let animationInfoLocation = LOCATION.read(buffer);
let imageInfoLocation = LOCATION.read(buffer);
let audioInfoLocation = LOCATION.read(buffer);
buffer.withOffset(characterInfoLocation.offset, () => {
acsData.characterInfo = AcsCharacterInfo.read(buffer);
});
buffer.withOffset(animationInfoLocation.offset, () => {
acsData.animInfo = buffer.readCountedList(() => {
return AcsAnimationEntry.read(buffer);
});
});
buffer.withOffset(imageInfoLocation.offset, () => {
acsData.images = buffer.readCountedList(() => {
return AcsImageEntry.read(buffer);
});
});
2024-07-09 19:47:10 -04:00
return acsData;
}
export function agentCreateCharacter(data: AcsData): Agent {
return new Agent(data);
}
2024-07-10 00:08:01 -04:00
2024-07-14 15:26:05 -04:00
export async function agentCreateCharacterFromUrl(url: string): Promise<Agent> {
// just return the cache object
2024-07-14 15:26:05 -04:00
if (acsDataCache.has(url)) {
return agentCreateCharacter(acsDataCache.get(url)!);
} else {
let res = await fetch(url);
let data = await res.arrayBuffer();
let buffer = new Uint8Array(data);
let acsData = agentCharacterParseACS(new BufferStream(buffer));
acsDataCache.set(url, acsData);
return agentCreateCharacter(acsData);
}
}