61 lines
2.0 KiB
TypeScript
61 lines
2.0 KiB
TypeScript
import { env } from 'cloudflare:workers';
|
|
import { z } from 'zod';
|
|
import { requireAleBridge } from '@/core/ale-auth';
|
|
import { recordAleEvent } from '@/core/ale-store';
|
|
import { queueConversationEvent } from '@/core/conversation-store';
|
|
import { D1Store } from '@/core/store';
|
|
import { applyAuthoritativeAleEvent,execute } from '@/core/service';
|
|
import type { RuntimeConfig } from '@/core/types';
|
|
|
|
const schema=z.object({
|
|
kind:z.string().min(1).max(100),
|
|
payload:z.record(z.unknown()).default({})
|
|
}).strict();
|
|
|
|
const STATEFUL_EVENTS=new Set([
|
|
'bridge.ready',
|
|
'player.login',
|
|
'player.logout',
|
|
'player.snapshot',
|
|
'player.first-login',
|
|
'player.zone',
|
|
'player.map',
|
|
'player.level',
|
|
'player.quest.accept',
|
|
'player.achievement',
|
|
'player.close-call',
|
|
'player.killed-by-creature',
|
|
'player.permanent-death',
|
|
'player.repop',
|
|
'player.resurrect'
|
|
]);
|
|
|
|
export async function POST(request:Request){
|
|
const config=env as unknown as RuntimeConfig;
|
|
try{
|
|
requireAleBridge(request,config);
|
|
const text=await request.text();if(text.length>40000)return Response.json({error:'Event too large'},{status:413});
|
|
const body=schema.parse(JSON.parse(text));
|
|
await recordAleEvent(env.DB!,body.kind,body.payload);
|
|
|
|
if((body.kind==='player.chat'||body.kind==='player.whisper')&&body.payload.isBot!==true){
|
|
await queueConversationEvent(env.DB!,body.kind,body.payload);
|
|
}
|
|
|
|
const store=new D1Store();
|
|
if(STATEFUL_EVENTS.has(body.kind)){
|
|
await applyAuthoritativeAleEvent(store,body.kind,body.payload);
|
|
}
|
|
|
|
if(body.kind==='player.zone'&&body.payload.isBot!==true){
|
|
const zone=String(body.payload.zoneName??body.payload.zone??'').slice(0,120);
|
|
if(zone)await execute(store,{type:'worldTrigger',kind:'zone-change',zone,playerName:String(body.payload.name??'').slice(0,40),detail:'Authoritative ALE human-player zone event'},config);
|
|
}
|
|
|
|
return Response.json({ok:true});
|
|
}catch(e){
|
|
const message=e instanceof Error?e.message:'ALE event failure';
|
|
return Response.json({error:message},{status:message.startsWith('Unauthorized')?401:400});
|
|
}
|
|
}
|