import { type APIRoute } from "astro"; import validateAccessToken from "../../../lib/utils/validateAccessToken"; import { getUserByAccessToken } from "../../../lib/db/users"; import { ObjectId } from "mongodb"; import locationManager from "../../../lib/classes/managers/LocationManager"; import Building from "../../../lib/classes/Building"; import { getAllResources } from "../../../lib/db/resources"; export const POST: APIRoute = async({ request }) => { const response = await validateAccessToken(request); if(response instanceof Response) return response; const user = await getUserByAccessToken(response); if(user === null) { return new Response( JSON.stringify({ code: 401, message: "Unauthorized" }), { status: 401 } ) } let body; try { body = await request.json() } catch(e) { return new Response( JSON.stringify({ code: 400, message: "Bad Request", error: "Invalid JSON body" }), { status: 400 } ) } const userPlanet = locationManager.getPlanet(new ObjectId(body.planet)); if(!userPlanet) { return new Response( JSON.stringify({ code: 400, message: "Bad Request", error: "Invalid planet ID" }), { status: 400 } ) } const buildingId: string = body.building; const buildingObj = userPlanet.buildings.buildingsDB.find(b => b.id === buildingId); if(!buildingObj) return new Response( JSON.stringify({ code: 400, message: "Bad Request", error: "Invalid building ID" }), { status: 400 } ) const building = new Building(userPlanet.buildings, buildingObj, 1); const requirements = await building.checkRequirements(); const resources = await building.checkRequiredResources((userPlanet.buildings.getBuildingById(buildingId)?.level ?? 0)); if(!requirements.canBuild || !resources) { return new Response( JSON.stringify({ code: 400, message: "Bad Request", error: `${requirements.error} | ${resources ? "" : "Not enough resources"}` }), { status: 400 } ) } const resourcesDiff = await userPlanet.resources.getDifference(building.data.requirements.resources.map(res => { return { id: res.id, amount: Math.pow(building.data.multiplier, (userPlanet.buildings.getBuildingById(buildingId)?.level ?? 0)) * res.amount } })); const resourceDB = await getAllResources(); const resourcesAfter = resourcesDiff.map(res => { const data = resourceDB.find(r => r.id === res.id); if(!data) throw new Error("Resource not found"); return { id: res.id, amount: res.amount, lastUpdated: res.lastUpdated, data } }); userPlanet.resources.setAmount(resourcesAfter.map(res => { return { id: res.id, amount: res.amount } })); userPlanet.buildings.addBuilding(building); await userPlanet.buildings.sync(); await userPlanet.resources.sync(); userPlanet.energy.update(); return new Response( JSON.stringify({ code: 200, message: "OK" }), { status: 200 } ); }