42 lines
1.7 KiB
TypeScript
42 lines
1.7 KiB
TypeScript
/** Server-authoritative lookup for authored office screen surfaces. */
|
|
|
|
import { Plan } from "../../../src/interiors/plan.ts";
|
|
import type { Office } from "../../../src/interiors/types.ts";
|
|
import FRONTIER_VALLEY from "../../../src/offices/frontier-valley.ts";
|
|
import LUMBRIDGE_HQ from "../../../src/offices/lumbridge-hq.ts";
|
|
import MATEO_COURT from "../../../src/offices/mateo-court.ts";
|
|
import type { ScreenShareBinding } from "../../../src/media/signalingTypes.ts";
|
|
|
|
const SCREEN_KINDS = new Set([
|
|
"tera:screen.monitor",
|
|
"tera:screen.wall-display",
|
|
]);
|
|
|
|
const BUNDLED_OFFICES: ReadonlyMap<string, Office> = new Map(
|
|
[LUMBRIDGE_HQ, FRONTIER_VALLEY, MATEO_COURT].map((office) => [office.id, office]),
|
|
);
|
|
|
|
/**
|
|
* A bundled pack is public sample geometry, so its exact authored screen
|
|
* catalogue is the only bundled exception. No real/private pack is inferred.
|
|
*/
|
|
export function bundledMediaOffice(officeId: string): Office | null {
|
|
return BUNDLED_OFFICES.get(officeId) ?? null;
|
|
}
|
|
|
|
/**
|
|
* Confirm an exact client binding against a validated/resolved office pack.
|
|
* Room membership is computed from the prop's authored position rather than
|
|
* trusting a caller-provided label.
|
|
*/
|
|
export function officeHasMediaBinding(office: Office, binding: ScreenShareBinding): boolean {
|
|
if (office.id !== binding.officeId) return false;
|
|
const plan = new Plan(office, { depth: "full", warn: false });
|
|
const level = plan.level(binding.levelId);
|
|
if (!level) return false;
|
|
const prop = level.props.find((candidate) => candidate.id === binding.screenId);
|
|
if (!prop || !SCREEN_KINDS.has(prop.kind)) return false;
|
|
const roomId = plan.roomAt(level.id, prop.position)?.id ?? null;
|
|
return roomId === binding.roomId;
|
|
}
|