AstroCol/src/pages/api/build/createBuilding.ts

109 lines
3.4 KiB
TypeScript

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 }
);
}