Compare commits
No commits in common. "a12b82f4708d6325bb5d3d06732b233116db3a85" and "a5d4431f5212cfa8a545cc4a8f3f1f85c5436626" have entirely different histories.
a12b82f470
...
a5d4431f52
Binary file not shown.
Before Width: | Height: | Size: 93 KiB |
Binary file not shown.
Before Width: | Height: | Size: 61 KiB |
Binary file not shown.
Before Width: | Height: | Size: 70 KiB |
|
@ -12,13 +12,15 @@ interface Props {
|
||||||
}
|
}
|
||||||
|
|
||||||
const lang = await getLocales(Astro.cookies.get('language')?.value ?? await getHighestWeightedLanguage(Astro.request.headers.get('accept-language')));
|
const lang = await getLocales(Astro.cookies.get('language')?.value ?? await getHighestWeightedLanguage(Astro.request.headers.get('accept-language')));
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
<div class="item-card" data-id={Astro.props.id}>
|
<div class="item-card" data-id={Astro.props.id}>
|
||||||
<img class="item-card-image" src={Astro.props.image} />
|
<img class="item-card-image" src={Astro.props.image} />
|
||||||
<div class="item-card-main-field">
|
<div class="item-card-main-field">
|
||||||
<div class="item-card-name">{Astro.props.name} | {Astro.props.level}</div>
|
<div class="item-card-name">{Astro.props.name} | {Astro.props.level}</div>
|
||||||
<div class="item-card-description">{Astro.props.description}</div>
|
<div class="item-card-description">{Astro.props.description}</div>
|
||||||
<form method="post"><input type="hidden" name="id" value={Astro.props.id} /><input type="submit" class="item-card-build" value={getName(lang, Astro.props.button_type, Astro.props.button_name)} /></form>
|
<a id={`button_${Astro.props.id}`} href="#" class="item-card-build">{getName(lang, Astro.props.button_type, Astro.props.button_name)}</a>
|
||||||
<div class="item-card-info-button">i</div>
|
<div class="item-card-info-button">i</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
|
@ -11,14 +11,14 @@ const lang = await getLocales(Astro.cookies.get('language')?.value ?? await getH
|
||||||
|
|
||||||
const planetId = new ObjectId(Astro.cookies.get('planetid')?.value ?? '');
|
const planetId = new ObjectId(Astro.cookies.get('planetid')?.value ?? '');
|
||||||
|
|
||||||
const planet = locationManager.getPlanet(planetId);
|
const resources = locationManager.getPlanet(planetId)?.resources;
|
||||||
|
|
||||||
if(!planet) return;
|
if(!resources) return;
|
||||||
|
|
||||||
await planet.resources.calculateCurrentAvailableResources();
|
resources.calculateCurrentAvailableResources();
|
||||||
|
|
||||||
const resourceArray: Resource[] = [];
|
const resourceArray: Resource[] = [];
|
||||||
for(const key of planet.resources.resources) {
|
for(const key of resources.resources) {
|
||||||
resourceArray.push(key);
|
resourceArray.push(key);
|
||||||
}
|
}
|
||||||
---
|
---
|
||||||
|
@ -26,9 +26,6 @@ for(const key of planet.resources.resources) {
|
||||||
<div class="resourcebar-item-identifier">
|
<div class="resourcebar-item-identifier">
|
||||||
<div class="resourcebar-circle-id" data-type="solid"></div>
|
<div class="resourcebar-circle-id" data-type="solid"></div>
|
||||||
</div>
|
</div>
|
||||||
<div class="resourcebar-planetname">
|
|
||||||
{planet.name}
|
|
||||||
</div>
|
|
||||||
<div id="resourcebar-elements" class="resourcebar-elements">
|
<div id="resourcebar-elements" class="resourcebar-elements">
|
||||||
{resourceArray.map(res =>
|
{resourceArray.map(res =>
|
||||||
<div class="resourcebar-item"
|
<div class="resourcebar-item"
|
||||||
|
@ -80,11 +77,6 @@ for(const key of planet.resources.resources) {
|
||||||
margin-bottom: 8px;
|
margin-bottom: 8px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.resourcebar-planetname {
|
|
||||||
margin-top: 8px;
|
|
||||||
font-size: 2.5em;
|
|
||||||
margin-left: 25px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.resourcebar-elements {
|
.resourcebar-elements {
|
||||||
flex-grow: 1;
|
flex-grow: 1;
|
||||||
|
@ -133,13 +125,11 @@ for(const key of planet.resources.resources) {
|
||||||
margin-top: 70px;
|
margin-top: 70px;
|
||||||
width: 150%;
|
width: 150%;
|
||||||
border-radius: 10px;
|
border-radius: 10px;
|
||||||
transition: visibility 1s, opacity 1s;
|
transition: opacity 1s;
|
||||||
visibility: hidden;
|
|
||||||
opacity: 0;
|
opacity: 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
.resourcebar-item:hover .resourcebar-item-tooltip {
|
.resourcebar-item:hover .resourcebar-item-tooltip {
|
||||||
visibility: visible;
|
|
||||||
opacity: 1;
|
opacity: 1;
|
||||||
}
|
}
|
||||||
</style>
|
</style>
|
||||||
|
|
|
@ -1,70 +0,0 @@
|
||||||
import DBStructure from "../../types/db/DBStructure";
|
|
||||||
import StructureManager from "./managers/StructureManager";
|
|
||||||
|
|
||||||
export default class Structure {
|
|
||||||
manager: StructureManager
|
|
||||||
data: DBStructure;
|
|
||||||
level: number;
|
|
||||||
|
|
||||||
constructor(manager: StructureManager, data: DBStructure, level: number) {
|
|
||||||
this.manager = manager;
|
|
||||||
this.data = data;
|
|
||||||
this.level = level;
|
|
||||||
}
|
|
||||||
|
|
||||||
// async checkRequiredResources(level: number): Promise<boolean> {
|
|
||||||
// const resources = await this.manager.planet.resources.calculateCurrentAvailableResources();
|
|
||||||
|
|
||||||
// const requirements = this.data.requirements.resources;
|
|
||||||
|
|
||||||
// let canBuild = true;
|
|
||||||
|
|
||||||
// for(let res of requirements) {
|
|
||||||
// const resource = resources.find(r => r.id === res.id);
|
|
||||||
// if(!resource) return false;
|
|
||||||
|
|
||||||
// const required = Math.pow(this.data.multiplier, level) * res.amount;
|
|
||||||
|
|
||||||
// if(resource.amount < required) {
|
|
||||||
// canBuild = false;
|
|
||||||
// break;
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
|
|
||||||
// return canBuild;
|
|
||||||
// }
|
|
||||||
|
|
||||||
// async checkRequirements(): Promise<{ canBuild: boolean, error: string }> {
|
|
||||||
// const playerBuildings = this.manager.buildings;
|
|
||||||
// let playerBuildingsCanBuild = { canBuild: true, missing: "" };
|
|
||||||
// this.data.requirements.buildings.forEach((buildingReq: any) => {
|
|
||||||
// if(playerBuildings.filter((building) => building.data.id === buildingReq.id)[0]?.level ?? 0 < buildingReq.level) {
|
|
||||||
// playerBuildingsCanBuild = { canBuild: false, missing: `${buildingReq.id} level ${buildingReq.level} required, found ${playerBuildings.filter((building) => building.data.id === buildingReq.id)[0]?.level ?? 0}` };
|
|
||||||
// return;
|
|
||||||
// }
|
|
||||||
// });
|
|
||||||
// if(!playerBuildingsCanBuild.canBuild) return {
|
|
||||||
// canBuild: false,
|
|
||||||
// error: playerBuildingsCanBuild.missing
|
|
||||||
// }
|
|
||||||
|
|
||||||
// // research
|
|
||||||
// const playerResearch = this.manager.planet.manager.owner.research;
|
|
||||||
// let playerResearchCanBuild = { canBuild: true, missing: "" };
|
|
||||||
// for(const researchReq of this.data.requirements.research) {
|
|
||||||
// if((playerResearch.research.find((research) => research.id === researchReq.id)?.level ?? 0) < researchReq.level) {
|
|
||||||
// playerResearchCanBuild = { canBuild: false, missing: `${researchReq.id} level ${researchReq.level} required, found ${playerResearch.research.find((research) => research.id === researchReq.id)?.level ?? 0}` };
|
|
||||||
// }
|
|
||||||
// };
|
|
||||||
|
|
||||||
// if(!playerResearchCanBuild.canBuild) return {
|
|
||||||
// canBuild: false,
|
|
||||||
// error: playerResearchCanBuild.missing
|
|
||||||
// }
|
|
||||||
|
|
||||||
// return {
|
|
||||||
// canBuild: true,
|
|
||||||
// error: ""
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
}
|
|
|
@ -1,6 +1,7 @@
|
||||||
import { ObjectId } from "mongodb";
|
import { ObjectId } from "mongodb";
|
||||||
import ResearchManager from "./managers/ResearchManager";
|
import ResearchManager from "./managers/ResearchManager";
|
||||||
import { Planet } from "./managers/PlanetManager";
|
import { Planet } from "./managers/PlanetManager";
|
||||||
|
import FleetManager from "./managers/FleetManager";
|
||||||
|
|
||||||
export default class User {
|
export default class User {
|
||||||
id: ObjectId;
|
id: ObjectId;
|
||||||
|
@ -10,6 +11,7 @@ export default class User {
|
||||||
updatedAt: Date;
|
updatedAt: Date;
|
||||||
lastLogin: Date;
|
lastLogin: Date;
|
||||||
research: ResearchManager;
|
research: ResearchManager;
|
||||||
|
fleet: FleetManager;
|
||||||
mainPlanet!: Planet;
|
mainPlanet!: Planet;
|
||||||
|
|
||||||
constructor(id: ObjectId, username: string, email: string, createdAt: Date, updatedAt: Date, lastLogin: Date) {
|
constructor(id: ObjectId, username: string, email: string, createdAt: Date, updatedAt: Date, lastLogin: Date) {
|
||||||
|
@ -20,6 +22,7 @@ export default class User {
|
||||||
this.updatedAt = updatedAt;
|
this.updatedAt = updatedAt;
|
||||||
this.lastLogin = lastLogin;
|
this.lastLogin = lastLogin;
|
||||||
this.research = new ResearchManager(this);
|
this.research = new ResearchManager(this);
|
||||||
|
this.fleet = new FleetManager(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
async init() {
|
async init() {
|
||||||
|
|
|
@ -1,99 +1,13 @@
|
||||||
import { ObjectId } from "mongodb";
|
import FleetShip from "../FleetShip";
|
||||||
import MissionType from "../../../types/MissionType";
|
import User from "../User";
|
||||||
import DBFleet from "../../../types/db/DBFleet";
|
|
||||||
import { updateFleet } from "../../db/fleet";
|
|
||||||
import { Planet } from "./PlanetManager";
|
|
||||||
|
|
||||||
export type Fleet = {
|
|
||||||
id: ObjectId,
|
|
||||||
source: Planet,
|
|
||||||
destination: Planet,
|
|
||||||
departureTime: Date,
|
|
||||||
arrivalTime: Date,
|
|
||||||
returning: boolean,
|
|
||||||
mission: MissionType,
|
|
||||||
ships: Array<{ id: string, amount: number }>,
|
|
||||||
cargo: Array<{ id: string, amount: number }>
|
|
||||||
}
|
|
||||||
|
|
||||||
export default class FleetManager {
|
export default class FleetManager {
|
||||||
data: Fleet;
|
user: User;
|
||||||
|
fleet: Array<FleetShip> = [];
|
||||||
|
|
||||||
constructor(id: ObjectId, source: Planet, destination: Planet, departureTime: Date, arrivalTime: Date, returning: boolean, mission: MissionType, ships: Array<{ id: string, amount: number }>, cargo: Array<{ id: string, amount: number }>) {
|
constructor(user: User) {
|
||||||
this.data = {
|
this.user = user;
|
||||||
id,
|
|
||||||
source,
|
|
||||||
destination,
|
|
||||||
departureTime,
|
|
||||||
arrivalTime,
|
|
||||||
returning,
|
|
||||||
mission,
|
|
||||||
ships,
|
|
||||||
cargo
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
async checkStatus(): Promise<{ finished: boolean, fleet: Fleet }> {
|
|
||||||
if(this.data.arrivalTime.getTime() < Date.now()) {
|
|
||||||
const finished = await this.finish();
|
|
||||||
return { finished, fleet: this.data };
|
|
||||||
}
|
|
||||||
|
|
||||||
return { finished: false, fleet: this.data };
|
|
||||||
}
|
|
||||||
|
|
||||||
async finish() {
|
|
||||||
if(this.data.returning) {
|
|
||||||
for(const ship of this.data.ships) {
|
|
||||||
this.data.source.ships.addShips(ship.id, ship.amount);
|
|
||||||
}
|
|
||||||
await this.data.source.resources.updateAmount(this.data.cargo);
|
|
||||||
await this.data.source.ships.sync();
|
|
||||||
await this.data.source.resources.sync();
|
|
||||||
return true;
|
|
||||||
} else {
|
|
||||||
switch(this.data.mission) {
|
|
||||||
case 'ATTACK':
|
|
||||||
return false;
|
|
||||||
case 'TRANSPORT':
|
|
||||||
await this.data.destination.resources.updateAmount(this.data.cargo);
|
|
||||||
await this.data.destination.resources.sync();
|
|
||||||
this.data.cargo = [];
|
|
||||||
await this.initiateReturn();
|
|
||||||
return false;
|
|
||||||
case 'TRANSFER':
|
|
||||||
await this.data.destination.resources.updateAmount(this.data.cargo);
|
|
||||||
await this.data.destination.resources.sync();
|
|
||||||
this.data.cargo = [];
|
|
||||||
for(const ship of this.data.ships) {
|
|
||||||
this.data.destination.ships.addShips(ship.id, ship.amount);
|
|
||||||
}
|
|
||||||
await this.data.destination.ships.sync();
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
async initiateReturn() {
|
|
||||||
this.data.returning = true;
|
|
||||||
this.data.departureTime = new Date();
|
|
||||||
this.data.arrivalTime = new Date(this.data.departureTime.getTime() + 1000 * 30);
|
|
||||||
await this.sync();
|
|
||||||
}
|
|
||||||
|
|
||||||
async sync() {
|
|
||||||
const data: DBFleet = {
|
|
||||||
_id: this.data.id,
|
|
||||||
source: this.data.source._id,
|
|
||||||
destination: this.data.destination._id,
|
|
||||||
departureTime: this.data.departureTime,
|
|
||||||
arrivalTime: this.data.arrivalTime,
|
|
||||||
returning: this.data.returning,
|
|
||||||
mission: this.data.mission,
|
|
||||||
ships: this.data.ships,
|
|
||||||
cargo: this.data.cargo
|
|
||||||
}
|
|
||||||
|
|
||||||
await updateFleet(data);
|
|
||||||
}
|
|
||||||
}
|
}
|
|
@ -5,9 +5,6 @@ import { getSectorById } from "../../db/sectors";
|
||||||
import { getSystemById } from "../../db/systems";
|
import { getSystemById } from "../../db/systems";
|
||||||
import { getAllUsers } from "../../db/users";
|
import { getAllUsers } from "../../db/users";
|
||||||
import User from "../User";
|
import User from "../User";
|
||||||
import StructureManager from "./StructureManager";
|
|
||||||
import FleetManager from "./FleetManager";
|
|
||||||
import { getAllFleet } from "../../db/fleet";
|
|
||||||
|
|
||||||
export type Galaxy = {
|
export type Galaxy = {
|
||||||
_id: ObjectId,
|
_id: ObjectId,
|
||||||
|
@ -32,7 +29,6 @@ export type System = {
|
||||||
sector: Sector,
|
sector: Sector,
|
||||||
name: string,
|
name: string,
|
||||||
ownedBy: User,
|
ownedBy: User,
|
||||||
structures: StructureManager,
|
|
||||||
planets: PlanetManager
|
planets: PlanetManager
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -50,15 +46,8 @@ class LocationManager {
|
||||||
|
|
||||||
galaxies: Galaxy[] = [];
|
galaxies: Galaxy[] = [];
|
||||||
users: User[] = [];
|
users: User[] = [];
|
||||||
fleet: FleetManager[] = [];
|
|
||||||
|
|
||||||
async init() {
|
async init() {
|
||||||
const currentTime = new Date();
|
|
||||||
|
|
||||||
this.galaxies = [];
|
|
||||||
this.users = [];
|
|
||||||
this.fleet = [];
|
|
||||||
|
|
||||||
const users = await getAllUsers();
|
const users = await getAllUsers();
|
||||||
users.forEach(async user => {
|
users.forEach(async user => {
|
||||||
this.users.push(new User(user._id, user.username, user.email, user.createdAt, user.updatedAt, user.lastLogin));
|
this.users.push(new User(user._id, user.username, user.email, user.createdAt, user.updatedAt, user.lastLogin));
|
||||||
|
@ -97,13 +86,9 @@ class LocationManager {
|
||||||
sector: sectorObject,
|
sector: sectorObject,
|
||||||
name: systemData.name,
|
name: systemData.name,
|
||||||
ownedBy: user,
|
ownedBy: user,
|
||||||
//@ts-ignore
|
|
||||||
structures: null,
|
|
||||||
planets: new PlanetManager(user)
|
planets: new PlanetManager(user)
|
||||||
};
|
};
|
||||||
|
|
||||||
systemObject.structures = await new StructureManager(systemObject).init(systemData.structures);
|
|
||||||
|
|
||||||
await systemObject.planets.fillData(systemObject, systemData.planets);
|
await systemObject.planets.fillData(systemObject, systemData.planets);
|
||||||
|
|
||||||
sectorObject.systems.push(systemObject);
|
sectorObject.systems.push(systemObject);
|
||||||
|
@ -131,28 +116,6 @@ class LocationManager {
|
||||||
user.mainPlanet = mainPlanet;
|
user.mainPlanet = mainPlanet;
|
||||||
};
|
};
|
||||||
|
|
||||||
const fleets = await getAllFleet();
|
|
||||||
for(const fleet of fleets) {
|
|
||||||
if(fleet.arrivalTime > currentTime) {
|
|
||||||
const source = this.getPlanet(fleet.source);
|
|
||||||
const destination = this.getPlanet(fleet.destination);
|
|
||||||
|
|
||||||
if(source && destination) this.fleet.push(new FleetManager(
|
|
||||||
fleet._id,
|
|
||||||
source,
|
|
||||||
destination,
|
|
||||||
fleet.departureTime,
|
|
||||||
fleet.arrivalTime,
|
|
||||||
fleet.returning,
|
|
||||||
fleet.mission,
|
|
||||||
fleet.ships,
|
|
||||||
fleet.cargo
|
|
||||||
));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
console.log(`Loaded ${this.fleet.length} active fleet from database`);
|
|
||||||
|
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -210,26 +173,8 @@ class LocationManager {
|
||||||
getUser(_id: ObjectId) {
|
getUser(_id: ObjectId) {
|
||||||
return this.users.find(user => user.id.equals(_id));
|
return this.users.find(user => user.id.equals(_id));
|
||||||
}
|
}
|
||||||
|
|
||||||
async updateFleet() {
|
|
||||||
for(const fleet of this.fleet) {
|
|
||||||
const { finished } = await fleet.checkStatus();
|
|
||||||
if(finished) {
|
|
||||||
this.fleet = this.fleet.filter(f => !f.data.id.equals(fleet.data.id));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
async getAllFleetByUserId(userId: string) {
|
|
||||||
await this.updateFleet();
|
|
||||||
return userId === '' ? [] : this.fleet.filter(fleet => fleet.data.source.manager.owner.id.equals(userId) || fleet.data.destination.manager.owner.id.equals(userId));
|
|
||||||
}
|
|
||||||
|
|
||||||
addFleet(fleet: FleetManager) {
|
|
||||||
this.fleet.push(fleet);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
const locationManager = LocationManager.getInstance();
|
const locationManager = LocationManager.getInstance();
|
||||||
await locationManager.init();
|
locationManager.init();
|
||||||
export default locationManager;
|
export default locationManager;
|
|
@ -13,7 +13,6 @@ export type Resource = {
|
||||||
|
|
||||||
export default class ResourceManager {
|
export default class ResourceManager {
|
||||||
resources: Array<Resource> = [];
|
resources: Array<Resource> = [];
|
||||||
resourcesDB: DBResource[] = [];
|
|
||||||
planet: Planet;
|
planet: Planet;
|
||||||
|
|
||||||
constructor(planet: Planet) {
|
constructor(planet: Planet) {
|
||||||
|
@ -23,8 +22,6 @@ export default class ResourceManager {
|
||||||
async init(resourceData: { id: string, amount: number, lastUpdated: Date, perHourMiningRate: number }[]) {
|
async init(resourceData: { id: string, amount: number, lastUpdated: Date, perHourMiningRate: number }[]) {
|
||||||
const resources = await getAllResources();
|
const resources = await getAllResources();
|
||||||
|
|
||||||
this.resourcesDB = resources;
|
|
||||||
|
|
||||||
if(resourceData.length === 0) {
|
if(resourceData.length === 0) {
|
||||||
resourceData = [
|
resourceData = [
|
||||||
{
|
{
|
||||||
|
@ -113,6 +110,7 @@ export default class ResourceManager {
|
||||||
res.lastUpdated = new Date();
|
res.lastUpdated = new Date();
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
||||||
await updatePlanetResources(this.planet._id, this.resources);
|
await updatePlanetResources(this.planet._id, this.resources);
|
||||||
|
|
||||||
return this.resources;
|
return this.resources;
|
||||||
|
@ -137,34 +135,8 @@ export default class ResourceManager {
|
||||||
return difference;
|
return difference;
|
||||||
}
|
}
|
||||||
|
|
||||||
add(resources: Resource[]) {
|
update(resources: Resource[]) {
|
||||||
for(const res of resources) {
|
this.resources = resources;
|
||||||
const resource = this.resources.find(r => r.id === res.id);
|
|
||||||
if(resource) resource.amount += res.amount;
|
|
||||||
else this.resources.push(res);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
async updateAmount(resources: { id: string, amount: number }[]) {
|
|
||||||
await this.calculateCurrentAvailableResources();
|
|
||||||
for(const res of resources) {
|
|
||||||
const resource = this.resources.find(r => r.id === res.id);
|
|
||||||
if(resource) resource.amount += res.amount;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
setAmount(resources: { id: string, amount: number }[]) {
|
|
||||||
for(const res of resources) {
|
|
||||||
const resource = this.resources.find(r => r.id === res.id);
|
|
||||||
if(resource) resource.amount = res.amount;
|
|
||||||
else this.resources.push({
|
|
||||||
id: res.id,
|
|
||||||
amount: res.amount,
|
|
||||||
lastUpdated: new Date(),
|
|
||||||
perHourMiningRate: 0,
|
|
||||||
data: this.resourcesDB.find(r => r.id === res.id)
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
async sync() {
|
async sync() {
|
||||||
|
|
|
@ -1,50 +0,0 @@
|
||||||
import { updatePlanetBuildings } from '../../db/planets';
|
|
||||||
import Building from '../Building';
|
|
||||||
import DBStructure from '../../../types/db/DBStructure';
|
|
||||||
import { System } from './LocationManager';
|
|
||||||
import { getAllStructures } from '../../db/structures';
|
|
||||||
import Structure from '../Structure';
|
|
||||||
import { updateSystemStructures } from '../../db/systems';
|
|
||||||
|
|
||||||
export default class StructureManager {
|
|
||||||
structures: Array<Structure> = [];
|
|
||||||
structuresDB: Array<DBStructure> = []
|
|
||||||
system: System;
|
|
||||||
|
|
||||||
constructor(system: System) {
|
|
||||||
this.system = system;
|
|
||||||
}
|
|
||||||
|
|
||||||
async init(structureData: { id: string, level: number }[]) {
|
|
||||||
this.structuresDB = await getAllStructures();
|
|
||||||
structureData.forEach(structure => {
|
|
||||||
const structureToFind = this.structuresDB.find(s => s.id === structure.id);
|
|
||||||
|
|
||||||
if(structureToFind) this.structures.push(new Structure(
|
|
||||||
this,
|
|
||||||
structureToFind,
|
|
||||||
structure.level
|
|
||||||
))
|
|
||||||
})
|
|
||||||
|
|
||||||
return this;
|
|
||||||
}
|
|
||||||
|
|
||||||
getStructureById(id: string) {
|
|
||||||
return this.structures.find(structure => structure.data.id === id);
|
|
||||||
}
|
|
||||||
|
|
||||||
addStructure(structure: Structure) {
|
|
||||||
const findStructure = this.structures.find(s => s.data.id === structure.data.id);
|
|
||||||
if(!findStructure) this.structures.push(structure);
|
|
||||||
else findStructure.level++;
|
|
||||||
}
|
|
||||||
|
|
||||||
removeStructure(id: string) {
|
|
||||||
this.structures = this.structures.filter(structure => structure.data.id !== id);
|
|
||||||
}
|
|
||||||
|
|
||||||
async sync() {
|
|
||||||
await updateSystemStructures(this.system._id, this.structures.map(structure => { return { id: structure.data.id, level: structure.level } }));
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,5 +1,6 @@
|
||||||
import { ObjectId } from 'mongodb';
|
import { ObjectId } from 'mongodb';
|
||||||
import DBFleet from '../../types/db/DBFleet';
|
import DBFleet from '../../types/db/DBFleet';
|
||||||
|
import { Planet } from '../classes/managers/PlanetManager';
|
||||||
import { Fleet, Planets } from '../db/mongodb';
|
import { Fleet, Planets } from '../db/mongodb';
|
||||||
|
|
||||||
export const getAllFleet = async () => {
|
export const getAllFleet = async () => {
|
||||||
|
@ -25,10 +26,15 @@ export const getAllFleetByUser = async (userId: ObjectId) => {
|
||||||
return Array.from(fleets.values());
|
return Array.from(fleets.values());
|
||||||
}
|
}
|
||||||
|
|
||||||
export const createFleet = async (fleet: DBFleet) => {
|
export const createFleet = async (source: Planet, destination: Planet, mission: string, ships: Array<{ id: string, amount: number }>) => {
|
||||||
return await (await Fleet()).insertOne(fleet);
|
const fleet = {
|
||||||
|
source: source._id,
|
||||||
|
destination: destination._id,
|
||||||
|
finished: false,
|
||||||
|
returning: false,
|
||||||
|
mission,
|
||||||
|
ships
|
||||||
}
|
}
|
||||||
|
|
||||||
export const updateFleet = async (fleet: DBFleet) => {
|
await (await Fleet()).insertOne(fleet);
|
||||||
return await (await Fleet()).updateOne({ _id: fleet._id }, { $set: fleet }, { upsert: true });
|
|
||||||
}
|
}
|
|
@ -7,7 +7,6 @@ export const getLang = async (language = "en") => {
|
||||||
buildings: await lang[1].find({}).toArray(),
|
buildings: await lang[1].find({}).toArray(),
|
||||||
ships: await lang[2].find({}).toArray(),
|
ships: await lang[2].find({}).toArray(),
|
||||||
resources: await lang[3].find({}).toArray(),
|
resources: await lang[3].find({}).toArray(),
|
||||||
research: await lang[4].find({}).toArray(),
|
research: await lang[4].find({}).toArray()
|
||||||
structures: await lang[5].find({}).toArray()
|
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -76,11 +76,6 @@ export const Fleet = async() => {
|
||||||
return db.collection('fleet');
|
return db.collection('fleet');
|
||||||
}
|
}
|
||||||
|
|
||||||
export const Structures = async() => {
|
|
||||||
const db = await getDB();
|
|
||||||
return db.collection('structures');
|
|
||||||
}
|
|
||||||
|
|
||||||
export const Lang = async (language = "en") => {
|
export const Lang = async (language = "en") => {
|
||||||
const db = await getDB(`${config.MONGODB_DB}_${language}`);
|
const db = await getDB(`${config.MONGODB_DB}_${language}`);
|
||||||
return [
|
return [
|
||||||
|
@ -88,7 +83,6 @@ export const Lang = async (language = "en") => {
|
||||||
await db.collection('buildings'),
|
await db.collection('buildings'),
|
||||||
await db.collection('ships'),
|
await db.collection('ships'),
|
||||||
await db.collection('resources'),
|
await db.collection('resources'),
|
||||||
await db.collection('research'),
|
await db.collection('research')
|
||||||
await db.collection('structures')
|
|
||||||
]
|
]
|
||||||
}
|
}
|
|
@ -1,12 +0,0 @@
|
||||||
import DBStructure from '../../types/db/DBStructure';
|
|
||||||
import { Structures } from '../db/mongodb';
|
|
||||||
|
|
||||||
export const getAllStructures = async () => {
|
|
||||||
return (await Structures()).find({}).toArray() as unknown as Array<DBStructure>;
|
|
||||||
}
|
|
||||||
|
|
||||||
export const getStructureById = async (id: string) => {
|
|
||||||
return (await Structures()).findOne({
|
|
||||||
id
|
|
||||||
}) as unknown as DBStructure;
|
|
||||||
}
|
|
|
@ -11,12 +11,3 @@ export const getSystemById = async (id: ObjectId) => {
|
||||||
_id: id
|
_id: id
|
||||||
}) as DBSystem;
|
}) as DBSystem;
|
||||||
}
|
}
|
||||||
|
|
||||||
export const updateSystemStructures = async (systemId: ObjectId, structures: Array<{ id: string, level: number }>) => {
|
|
||||||
const systems = await Systems();
|
|
||||||
await systems.updateOne({ _id: systemId }, {
|
|
||||||
$set: {
|
|
||||||
structures
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
|
@ -1,14 +0,0 @@
|
||||||
export default function parseParams(url: string) {
|
|
||||||
const rawParams = url.split("?")[1]?.split("&");
|
|
||||||
if(typeof rawParams === "undefined") return [];
|
|
||||||
const params: { [key: string]: any } = {};
|
|
||||||
for(const rawParam of rawParams) {
|
|
||||||
const k = rawParam.split("=")[0];
|
|
||||||
const v = rawParam.split("=")[1];
|
|
||||||
if(v === "true" || v === "false") params[k] = v === "true";
|
|
||||||
else if(!Number.isNaN(Number(v))) params[k] = Number(v);
|
|
||||||
else params[k] = v;
|
|
||||||
}
|
|
||||||
|
|
||||||
return params;
|
|
||||||
}
|
|
|
@ -5,9 +5,12 @@ import { getUserById } from "../db/users";
|
||||||
import locationManager from "../classes/managers/LocationManager";
|
import locationManager from "../classes/managers/LocationManager";
|
||||||
|
|
||||||
export default async function validateAccessToken(request: Request): Promise<Response | AccessToken> {
|
export default async function validateAccessToken(request: Request): Promise<Response | AccessToken> {
|
||||||
let accessToken;
|
let accessToken = request.url.split("?")[1]?.split("&").filter((x) => x.split("=")[0] === "token")[0].split("=")[1];
|
||||||
|
|
||||||
|
if(accessToken === undefined) {
|
||||||
const authorization = request.headers.get("Authorization");
|
const authorization = request.headers.get("Authorization");
|
||||||
if(authorization !== null && authorization.startsWith("Bearer ")) accessToken = authorization.split(" ")[1];
|
if(authorization !== null && authorization.startsWith("Bearer ")) accessToken = authorization.split(" ")[1];
|
||||||
|
}
|
||||||
|
|
||||||
const cookies = request.headers.get("Cookie")?.split(";").map((x) => x.trim().split("=")) ?? [];
|
const cookies = request.headers.get("Cookie")?.split(";").map((x) => x.trim().split("=")) ?? [];
|
||||||
|
|
||||||
|
|
|
@ -1,268 +0,0 @@
|
||||||
import { 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 { getAllShips } from "../../../lib/db/ships";
|
|
||||||
import DBShip from "../../../types/db/DBShip";
|
|
||||||
import { Planet } from "../../../lib/classes/managers/PlanetManager";
|
|
||||||
import MissionType from "../../../types/MissionType";
|
|
||||||
import { getAllResources } from "../../../lib/db/resources";
|
|
||||||
import FleetManager from "../../../lib/classes/managers/FleetManager";
|
|
||||||
|
|
||||||
export const POST: APIRoute = async({ request }) => {
|
|
||||||
const response = await validateAccessToken(request);
|
|
||||||
if(response instanceof Response) return response;
|
|
||||||
|
|
||||||
const userDB = await getUserByAccessToken(response);
|
|
||||||
if(userDB === null) {
|
|
||||||
return new Response(
|
|
||||||
JSON.stringify({
|
|
||||||
code: 401,
|
|
||||||
message: "Unauthorized"
|
|
||||||
}), { status: 401 }
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
const user = locationManager.getUser(userDB._id);
|
|
||||||
if(!user) {
|
|
||||||
return new Response(
|
|
||||||
JSON.stringify({
|
|
||||||
code: 401,
|
|
||||||
message: "Unauthorized"
|
|
||||||
}), { status: 401 }
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
let body: { source: string, destination: string, ships: Array<{ id: string, amount: number }>, cargo: Array<{ id: string, amount: number }>, mission: MissionType };
|
|
||||||
try {
|
|
||||||
body = await request.json()
|
|
||||||
} catch(e) {
|
|
||||||
return new Response(
|
|
||||||
JSON.stringify({
|
|
||||||
code: 400,
|
|
||||||
message: "Bad Request",
|
|
||||||
error: "Invalid JSON body"
|
|
||||||
}), { status: 400 }
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
const checkSource = checkPlanetId(body.source, 'source');
|
|
||||||
if(typeof checkSource.error !== "undefined") return new Response(JSON.stringify(checkSource), { status: checkSource.code });
|
|
||||||
|
|
||||||
const checkDestination = checkPlanetId(body.destination, 'destination');
|
|
||||||
if(typeof checkDestination.error !== "undefined") return new Response(JSON.stringify(checkDestination), { status: checkDestination.code });
|
|
||||||
|
|
||||||
const source = checkSource.planet;
|
|
||||||
const destination = checkDestination.planet;
|
|
||||||
|
|
||||||
const shipsDB = await getAllShips();
|
|
||||||
|
|
||||||
const checkShipsBody = checkShips(body.ships, shipsDB, source);
|
|
||||||
if(typeof checkShipsBody.error !== "undefined") return new Response(JSON.stringify(checkShipsBody), { status: checkShipsBody.code });
|
|
||||||
|
|
||||||
const resourcesDB = await getAllResources();
|
|
||||||
await source.resources.calculateCurrentAvailableResources();
|
|
||||||
|
|
||||||
const checkCargoBody = checkCargo(body.cargo, body.ships, source, body.mission);
|
|
||||||
if(typeof checkCargoBody.error !== "undefined") return new Response(JSON.stringify(checkCargoBody), { status: checkCargoBody.code });
|
|
||||||
|
|
||||||
const fleetManager = new FleetManager(
|
|
||||||
new ObjectId(),
|
|
||||||
source,
|
|
||||||
destination,
|
|
||||||
new Date(),
|
|
||||||
new Date(Date.now() + 1000 * 30), //TODO: calculate time based on distance
|
|
||||||
false,
|
|
||||||
body.mission,
|
|
||||||
body.ships,
|
|
||||||
body.cargo
|
|
||||||
);
|
|
||||||
|
|
||||||
const resourceDiff = await source.resources.getDifference(body.cargo.map(c => ({ id: c.id, amount: c.amount })));
|
|
||||||
|
|
||||||
for(const res of resourceDiff) {
|
|
||||||
if(res.amount < 0) {
|
|
||||||
return new Response(
|
|
||||||
JSON.stringify({
|
|
||||||
code: 400,
|
|
||||||
message: "Bad Request",
|
|
||||||
error: "Not enough resource with ID '" + res.id + "' on source planet"
|
|
||||||
}), { status: 400 }
|
|
||||||
)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
source.resources.setAmount(resourceDiff);
|
|
||||||
await source.resources.sync();
|
|
||||||
|
|
||||||
for(const ship of body.ships) {
|
|
||||||
source.ships.removeShips(ship.id, ship.amount);
|
|
||||||
}
|
|
||||||
await source.ships.sync();
|
|
||||||
await fleetManager.sync();
|
|
||||||
|
|
||||||
locationManager.addFleet(fleetManager);
|
|
||||||
|
|
||||||
return new Response(
|
|
||||||
JSON.stringify({
|
|
||||||
code: 200,
|
|
||||||
message: "OK"
|
|
||||||
}), { status: 200 }
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
function checkPlanetId(id: string, type: string) {
|
|
||||||
if(typeof ObjectId === "undefined") return {
|
|
||||||
code: 400,
|
|
||||||
message: "Bad Request",
|
|
||||||
error: `Missing '${type}' in body`
|
|
||||||
}
|
|
||||||
|
|
||||||
let idToCheck;
|
|
||||||
try {
|
|
||||||
idToCheck = new ObjectId(id);
|
|
||||||
} catch(e) {
|
|
||||||
return {
|
|
||||||
code: 400,
|
|
||||||
message: "Bad Request",
|
|
||||||
error: `Invalid ID in '${type}'`
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
const planet = locationManager.getPlanet(idToCheck);
|
|
||||||
|
|
||||||
if(!planet) return {
|
|
||||||
code: 404,
|
|
||||||
message: "Not Found",
|
|
||||||
error: `Non-existent planet provided in '${type}'`
|
|
||||||
}
|
|
||||||
|
|
||||||
return {
|
|
||||||
code: 200,
|
|
||||||
message: "OK",
|
|
||||||
planet
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
function checkShips(ships: Array<{ id: string, amount: number }>, shipsDB: Array<DBShip>, sourcePlanet: Planet) {
|
|
||||||
if(typeof ships === "undefined") return {
|
|
||||||
code: 400,
|
|
||||||
message: "Bad Request",
|
|
||||||
error: "Missing 'ships' in body"
|
|
||||||
}
|
|
||||||
|
|
||||||
for(let i = 0; i < ships.length; i++) {
|
|
||||||
if(typeof ships[i].id === "undefined" || ships[i].id === "") return {
|
|
||||||
code: 400,
|
|
||||||
message: "Bad Request",
|
|
||||||
error: "Missing ship ID at position " + i
|
|
||||||
}
|
|
||||||
|
|
||||||
if(!shipsDB.find(ship => ship.id === ships[i].id)) return {
|
|
||||||
code: 404,
|
|
||||||
message: "Not Found",
|
|
||||||
error: "Non-existent ship ID '" + ships[i].id + "' at position " + i
|
|
||||||
}
|
|
||||||
|
|
||||||
if(typeof ships[i].amount === "undefined") return {
|
|
||||||
code: 400,
|
|
||||||
message: "Bad Request",
|
|
||||||
error: "Missing ship amount for ID '" + ships[i].id + "' at position " + i
|
|
||||||
}
|
|
||||||
|
|
||||||
if(ships[i].amount % 1 !== 0 || ships[i].amount < 0) return {
|
|
||||||
code: 400,
|
|
||||||
message: "Bad Request",
|
|
||||||
error: "Ship amount for ID '" + ships[i].id + "' is not a non-negative integer at position " + i
|
|
||||||
}
|
|
||||||
|
|
||||||
if(ships[i].amount > (sourcePlanet.ships.getShipById(ships[i].id)?.amount ?? 0)) return {
|
|
||||||
code: 400,
|
|
||||||
message: "Bad Request",
|
|
||||||
error: "Not enough ships on planet with ID '" + ships[i].id + "' at position " + i
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return {
|
|
||||||
code: 200,
|
|
||||||
message: "OK"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
function checkCargo(cargo: Array<{ id: string, amount: number }>, ships: Array<{ id: string, amount: number }>, planet: Planet, missionType: MissionType) {
|
|
||||||
if(missionType === "TRANSPORT" && cargo.length === 0) return {
|
|
||||||
code: 400,
|
|
||||||
message: "Bad Request",
|
|
||||||
error: "Missing 'cargo' in body for requested mission 'TRANSPORT'"
|
|
||||||
}
|
|
||||||
|
|
||||||
for(let i = 0; i < cargo.length; i++) {
|
|
||||||
if(typeof cargo[i].id === "undefined") return {
|
|
||||||
code: 400,
|
|
||||||
message: "Bad Request",
|
|
||||||
error: "Missing resource ID at position " + i
|
|
||||||
}
|
|
||||||
|
|
||||||
if(!planet.resources.resourcesDB.find(resource => resource.id === cargo[i].id)) return {
|
|
||||||
code: 404,
|
|
||||||
message: "Not Found",
|
|
||||||
error: "Non-existent resource ID '" + cargo[i].id + "' at position " + i
|
|
||||||
}
|
|
||||||
|
|
||||||
if(typeof cargo[i].amount === "undefined") return {
|
|
||||||
code: 400,
|
|
||||||
message: "Bad Request",
|
|
||||||
error: "Missing resource amount for ID '" + cargo[i].id + "' at position " + i
|
|
||||||
}
|
|
||||||
|
|
||||||
if(cargo[i].amount % 1 !== 0 || cargo[i].amount < 0) return {
|
|
||||||
code: 400,
|
|
||||||
message: "Bad Request",
|
|
||||||
error: "Resource amount for ID '" + cargo[i].id + "' is not a non-negative integer at position " + i
|
|
||||||
}
|
|
||||||
|
|
||||||
if(cargo[i].amount > (planet.resources.resources.find(res => res.id === cargo[i].id)?.amount ?? 0)) return {
|
|
||||||
code: 400,
|
|
||||||
message: "Bad Request",
|
|
||||||
error: "Not enough resources on planet with ID '" + cargo[i].id + "' at position " + i
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
const totalCargoAvailable = {
|
|
||||||
solid: ships.reduce((acc, ship) => acc + (planet.ships.shipsDB.find(s => s.id === ship.id)?.capacity.solid ?? 0) * ship.amount, 0),
|
|
||||||
liquid: ships.reduce((acc, ship) => acc + (planet.ships.shipsDB.find(s => s.id === ship.id)?.capacity.liquid ?? 0) * ship.amount, 0),
|
|
||||||
gas: ships.reduce((acc, ship) => acc + (planet.ships.shipsDB.find(s => s.id === ship.id)?.capacity.gas ?? 0) * ship.amount, 0)
|
|
||||||
}
|
|
||||||
|
|
||||||
const totalCargoUsed = {
|
|
||||||
solid: cargo.reduce((acc, resource) => planet.resources.resourcesDB.find(res => res.id === resource.id)?.type === "solid" ? acc + resource.amount : acc, 0),
|
|
||||||
liquid: cargo.reduce((acc, resource) => planet.resources.resourcesDB.find(res => res.id === resource.id)?.type === "liquid" ? acc + resource.amount : acc, 0),
|
|
||||||
gas: cargo.reduce((acc, resource) => planet.resources.resourcesDB.find(res => res.id === resource.id)?.type === "gas" ? acc + resource.amount : acc, 0)
|
|
||||||
}
|
|
||||||
|
|
||||||
if(totalCargoUsed.solid > totalCargoAvailable.solid) return {
|
|
||||||
code: 400,
|
|
||||||
message: "Bad Request",
|
|
||||||
error: "Not enough solid cargo capacity on ships"
|
|
||||||
}
|
|
||||||
|
|
||||||
if(totalCargoUsed.liquid > totalCargoAvailable.liquid) return {
|
|
||||||
code: 400,
|
|
||||||
message: "Bad Request",
|
|
||||||
error: "Not enough liquid cargo capacity on ships"
|
|
||||||
}
|
|
||||||
|
|
||||||
if(totalCargoUsed.gas > totalCargoAvailable.gas) return {
|
|
||||||
code: 400,
|
|
||||||
message: "Bad Request",
|
|
||||||
error: "Not enough gas cargo capacity on ships"
|
|
||||||
}
|
|
||||||
|
|
||||||
//TODO: check for fuel
|
|
||||||
|
|
||||||
return {
|
|
||||||
code: 200,
|
|
||||||
message: "OK"
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,36 +0,0 @@
|
||||||
import { APIRoute } from "astro";
|
|
||||||
import validateAccessToken from "../../../lib/utils/validateAccessToken";
|
|
||||||
import { getUserByAccessToken } from "../../../lib/db/users";
|
|
||||||
import { getAllFleetByUser } from "../../../lib/db/fleet";
|
|
||||||
import parseParams from "../../../lib/utils/parseParams";
|
|
||||||
|
|
||||||
export const GET: 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 allFleet = (await getAllFleetByUser(user._id)).filter(f => f.arrivalTime.getTime() > Date.now());
|
|
||||||
|
|
||||||
const params = {
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
const URLParams = parseParams(request.url);
|
|
||||||
|
|
||||||
return new Response(
|
|
||||||
JSON.stringify({
|
|
||||||
code: 200,
|
|
||||||
message: "OK",
|
|
||||||
data: allFleet
|
|
||||||
}), { status: 200 }
|
|
||||||
)
|
|
||||||
}
|
|
|
@ -1,110 +0,0 @@
|
||||||
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";
|
|
||||||
import Structure from "../../../lib/classes/Structure";
|
|
||||||
|
|
||||||
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 userSystem = locationManager.getSystem(new ObjectId(body.system));
|
|
||||||
|
|
||||||
if(!userSystem) {
|
|
||||||
return new Response(
|
|
||||||
JSON.stringify({
|
|
||||||
code: 400,
|
|
||||||
message: "Bad Request",
|
|
||||||
error: "Invalid system ID"
|
|
||||||
}), { status: 400 }
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
const structureId: string = body.structureId;
|
|
||||||
|
|
||||||
const structureObj = userSystem.structures.structuresDB.find(s => s.id === structureId);
|
|
||||||
|
|
||||||
if(!structureObj) return new Response(
|
|
||||||
JSON.stringify({
|
|
||||||
code: 400,
|
|
||||||
message: "Bad Request",
|
|
||||||
error: "Invalid structure ID"
|
|
||||||
}), { status: 400 }
|
|
||||||
)
|
|
||||||
|
|
||||||
const structure = new Structure(userSystem.structures, structureObj, 1);
|
|
||||||
|
|
||||||
// const requirements = await structure.checkRequirements();
|
|
||||||
// const resources = await building.checkRequiredResources((userPlanet.buildings.getBuildingById(buildingId)?.level ?? 0) + 1);
|
|
||||||
|
|
||||||
// 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) + 1) * 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,
|
|
||||||
// perHourMiningRate: res.perHourMiningRate,
|
|
||||||
// data
|
|
||||||
// }
|
|
||||||
// });
|
|
||||||
|
|
||||||
// userPlanet.resources.update(resourcesAfter);
|
|
||||||
// userSystem.structures.addStructure(structure);
|
|
||||||
|
|
||||||
// await userSystem.structures.sync();
|
|
||||||
// await userPlanet.resources.sync();
|
|
||||||
|
|
||||||
return new Response(
|
|
||||||
JSON.stringify({
|
|
||||||
code: 200,
|
|
||||||
message: "OK"
|
|
||||||
}), { status: 200 }
|
|
||||||
);
|
|
||||||
}
|
|
|
@ -29,24 +29,6 @@ if(planetId === "") return "No planet selected";
|
||||||
const planet = locationManager.getPlanet(new ObjectId(planetId));
|
const planet = locationManager.getPlanet(new ObjectId(planetId));
|
||||||
if(!planet) return "Planet not found";
|
if(!planet) return "Planet not found";
|
||||||
|
|
||||||
if(Astro.request.method === "POST") {
|
|
||||||
const selectedBuildingId = (await Astro.request.formData()).get('id') as string | null;
|
|
||||||
|
|
||||||
const request = await (await fetch(Astro.url.origin + '/api/build/createBuilding', {
|
|
||||||
method: 'POST',
|
|
||||||
headers: {
|
|
||||||
'Content-Type': 'application/json',
|
|
||||||
'Authorization': 'Bearer ' + loggedToken
|
|
||||||
},
|
|
||||||
body: JSON.stringify({
|
|
||||||
planet: planetId,
|
|
||||||
building: selectedBuildingId
|
|
||||||
})
|
|
||||||
})).json();
|
|
||||||
|
|
||||||
console.log(request);
|
|
||||||
}
|
|
||||||
|
|
||||||
const modalSet: { [key: string]: { resources: Array<any>, research: Array<any>, buildings: Array<any>, energy: number } } = {};
|
const modalSet: { [key: string]: { resources: Array<any>, research: Array<any>, buildings: Array<any>, energy: number } } = {};
|
||||||
|
|
||||||
for(const building of buildingsList) {
|
for(const building of buildingsList) {
|
||||||
|
@ -264,4 +246,29 @@ const buildingsByCategory = buildingsList.reduce((acc: { [key: string]: Array<DB
|
||||||
if(!backgroundDiv) return;
|
if(!backgroundDiv) return;
|
||||||
backgroundDiv.style.display = 'none';
|
backgroundDiv.style.display = 'none';
|
||||||
});
|
});
|
||||||
|
|
||||||
|
const allButtons = document.getElementsByClassName("item-card-build");
|
||||||
|
|
||||||
|
for(const buildingButton of allButtons) {
|
||||||
|
buildingButton.addEventListener("click", async () => {
|
||||||
|
const id = buildingButton.id.split("_")[1];
|
||||||
|
|
||||||
|
const response = await fetch('/api/build/createBuilding', {
|
||||||
|
method: 'POST',
|
||||||
|
headers: {
|
||||||
|
'Content-Type': 'application/json'
|
||||||
|
},
|
||||||
|
body: JSON.stringify({
|
||||||
|
building: id,
|
||||||
|
planet: planetId
|
||||||
|
})
|
||||||
|
});
|
||||||
|
|
||||||
|
if(response.status === 200) {
|
||||||
|
window.location.reload();
|
||||||
|
} else {
|
||||||
|
alert("Failed to build building: " + JSON.stringify(await response.json()));
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
</script>
|
</script>
|
|
@ -7,7 +7,6 @@ import ResourceBar from '../../components/ResourceBar.astro';
|
||||||
import locationManager from '../../lib/classes/managers/LocationManager';
|
import locationManager from '../../lib/classes/managers/LocationManager';
|
||||||
import { getAllFleetByUser } from '../../lib/db/fleet';
|
import { getAllFleetByUser } from '../../lib/db/fleet';
|
||||||
import { getAllShips } from '../../lib/db/ships';
|
import { getAllShips } from '../../lib/db/ships';
|
||||||
import { ObjectId } from 'mongodb';
|
|
||||||
|
|
||||||
const loggedToken = Astro.cookies.get('sessionToken')?.value ?? null;
|
const loggedToken = Astro.cookies.get('sessionToken')?.value ?? null;
|
||||||
const username = Astro.cookies.get('username')?.value ?? "";
|
const username = Astro.cookies.get('username')?.value ?? "";
|
||||||
|
@ -19,67 +18,11 @@ if(checkUser === null || checkUser.username !== username) return Astro.redirect(
|
||||||
const user = locationManager.getUser(checkUser._id);
|
const user = locationManager.getUser(checkUser._id);
|
||||||
if(!user) return Astro.redirect('/logout');
|
if(!user) return Astro.redirect('/logout');
|
||||||
|
|
||||||
const planetId = Astro.cookies.get('planetid')?.value ?? "";
|
|
||||||
if(planetId === "") return "No planet selected";
|
|
||||||
|
|
||||||
const planet = locationManager.getPlanet(new ObjectId(planetId));
|
|
||||||
if(!planet) return "Planet not found";
|
|
||||||
|
|
||||||
const ships = await getAllShips();
|
const ships = await getAllShips();
|
||||||
|
|
||||||
if(Astro.request.method === "POST") {
|
const fleet = await getAllFleetByUser(user.id);
|
||||||
const form = await Astro.request.formData();
|
|
||||||
|
|
||||||
const cargo: Array<{ id: string, amount: number }> = [];
|
|
||||||
|
|
||||||
form.forEach((v, k) => {
|
|
||||||
if(k.match(/cargo\[\d\]\[id\]/)) {
|
|
||||||
const amount = parseInt(form.get(`${k.substring(0, k.indexOf("]"))}][amount]`)?.toString() ?? "0");
|
|
||||||
|
|
||||||
if(amount === 0 || isNaN(amount)) return;
|
|
||||||
|
|
||||||
cargo.push({
|
|
||||||
id: v.toString(),
|
|
||||||
amount
|
|
||||||
});
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
const fleetData = {
|
|
||||||
source: planet._id,
|
|
||||||
destination: new ObjectId(form.get('destination-planet')?.toString() ?? ""),
|
|
||||||
mission: form.get('mission')?.toString() ?? "NULL",
|
|
||||||
ships: ships.map(ship => {
|
|
||||||
const amount = parseInt(form.get(`ship-amount-${ship.id}`)?.toString() ?? "0");
|
|
||||||
if(amount === 0) return null;
|
|
||||||
return {
|
|
||||||
id: ship.id,
|
|
||||||
amount
|
|
||||||
}
|
|
||||||
}).filter(s => s !== null),
|
|
||||||
cargo
|
|
||||||
}
|
|
||||||
const response = await fetch(`${Astro.url.origin}/api/fleet/send`, {
|
|
||||||
method: 'POST',
|
|
||||||
headers: {
|
|
||||||
'Content-Type': 'application/json',
|
|
||||||
'Authorization': `Bearer ${loggedToken}`
|
|
||||||
},
|
|
||||||
body: JSON.stringify(fleetData)
|
|
||||||
});
|
|
||||||
|
|
||||||
console.log(await response.json());
|
|
||||||
|
|
||||||
return Astro.redirect('/game/fleet');
|
|
||||||
}
|
|
||||||
|
|
||||||
await locationManager.updateFleet();
|
|
||||||
|
|
||||||
const fleet = (await getAllFleetByUser(user.id)).filter(f => new Date().getTime() - f.arrivalTime.getTime() < 0);
|
|
||||||
fleet.sort((a, b) => a.departureTime.getTime() - b.departureTime.getTime());
|
|
||||||
|
|
||||||
const userSystems = locationManager.getSystemsOwnedBy(user.id);
|
const userSystems = locationManager.getSystemsOwnedBy(user.id);
|
||||||
const galaxies = locationManager.galaxies;
|
|
||||||
|
|
||||||
let own = 0;
|
let own = 0;
|
||||||
let friendly = 0;
|
let friendly = 0;
|
||||||
|
@ -90,7 +33,7 @@ for(const system of userSystems) {
|
||||||
for(const f of fleet) {
|
for(const f of fleet) {
|
||||||
if(f.source.equals(planet._id)) own++;
|
if(f.source.equals(planet._id)) own++;
|
||||||
else if(f.destination.equals(planet._id)) {
|
else if(f.destination.equals(planet._id)) {
|
||||||
if(f.mission === 'ATTACK') enemy++;
|
if(f.mission === 'attack') enemy++;
|
||||||
else {
|
else {
|
||||||
const source = locationManager.getPlanet(f.source)?.manager.owner.id;
|
const source = locationManager.getPlanet(f.source)?.manager.owner.id;
|
||||||
const destination = locationManager.getPlanet(f.destination)?.manager.owner.id;
|
const destination = locationManager.getPlanet(f.destination)?.manager.owner.id;
|
||||||
|
@ -101,37 +44,13 @@ for(const system of userSystems) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
const sectorsList = galaxies.map(galaxy => {
|
|
||||||
return {
|
|
||||||
_id: galaxy._id,
|
|
||||||
name: galaxy.name,
|
|
||||||
sectors: galaxy.sectors.map(sector => {
|
|
||||||
return {
|
|
||||||
_id: sector._id,
|
|
||||||
name: sector.name,
|
|
||||||
systems: sector.systems.map(system => {
|
|
||||||
return {
|
|
||||||
_id: system._id,
|
|
||||||
name: system.name,
|
|
||||||
planets: system.planets.planets.map(planet => {
|
|
||||||
return {
|
|
||||||
_id: planet._id,
|
|
||||||
name: planet.name
|
|
||||||
}
|
|
||||||
})
|
|
||||||
}
|
|
||||||
})
|
|
||||||
}
|
|
||||||
})
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
const lang = await getLocales(Astro.cookies.get('language')?.value ?? await getHighestWeightedLanguage(Astro.request.headers.get('accept-language')));
|
const lang = await getLocales(Astro.cookies.get('language')?.value ?? await getHighestWeightedLanguage(Astro.request.headers.get('accept-language')));
|
||||||
---
|
---
|
||||||
|
|
||||||
<Layout title="Fleet">
|
<Layout title="Fleet">
|
||||||
<NavBar loggedIn="true" active="fleet" />
|
<NavBar loggedIn="true" active="fleet" />
|
||||||
<ResourceBar />
|
<ResourceBar />
|
||||||
|
|
||||||
<label for="fleet-toggle">
|
<label for="fleet-toggle">
|
||||||
<input type="checkbox" id="fleet-toggle">
|
<input type="checkbox" id="fleet-toggle">
|
||||||
<div class="fleet-status">
|
<div class="fleet-status">
|
||||||
|
@ -139,74 +58,18 @@ const lang = await getLocales(Astro.cookies.get('language')?.value ?? await getH
|
||||||
<ul>
|
<ul>
|
||||||
{fleet.map(f => <li>
|
{fleet.map(f => <li>
|
||||||
<div class="ship-cards">
|
<div class="ship-cards">
|
||||||
{locationManager.getPlanet(f.source)?.name ?? "?"} => {locationManager.getPlanet(f.destination)?.name ?? "?"} | {f.mission}{f.returning ? " (R)" : ""}<br />
|
{locationManager.getPlanet(f.source)?.name ?? "?"} => {locationManager.getPlanet(f.destination)?.name ?? "?"} | {f.mission}<br />
|
||||||
Containing: {f.ships.map(s => {
|
Containing: {f.ships.map(s => {
|
||||||
const ship = ships.find(ship => ship.id === s.id);
|
const ship = ships.find(ship => ship.id === s.id);
|
||||||
return `${getName(lang, 'ships', s.id)} x${s.amount}`;
|
return `${getName(lang, 'ships', s.id)} x${s.amount}`;
|
||||||
}).join(', ')} <br />
|
}).join(', ')} <br />
|
||||||
Cargo: {typeof f.cargo === "undefined" || f.cargo.length === 0 ? <>None</> : f.cargo.map(c => `${c.amount} ${getName(lang, 'resources', c.id)}`).join(', ')} <br />
|
|
||||||
Departured at: {f.departureTime.toISOString()} <br />
|
|
||||||
Arrives: {f.arrivalTime.toISOString()} ({Math.floor((f.arrivalTime.getTime() - new Date().getTime()) / 1000)})
|
|
||||||
</div>
|
</div>
|
||||||
</li>)}
|
</li>)}
|
||||||
</ul>
|
</ul>
|
||||||
</div>
|
</div>
|
||||||
</label>
|
</label>
|
||||||
<div class="fleet-send-container">
|
|
||||||
<form method="post">
|
|
||||||
<h1>Sending fleet from {planet.name}</h1>
|
|
||||||
<hr />
|
|
||||||
<h2>Ships</h2>
|
|
||||||
<div class="fleet-send-ships">
|
|
||||||
{planet.ships.ships.map(ship => <div class="fleet-ship-card">
|
|
||||||
<h3>{getName(lang, 'ships', ship.data.id)} - {ship.amount}</h3>
|
|
||||||
<input type="number" value="0" min="0" max={ship.amount} id={ship.data.id} name={`ship-amount-${ship.data.id}`} />
|
|
||||||
</div>)}
|
|
||||||
</div>
|
|
||||||
<hr />
|
|
||||||
<h2>Mission</h2>
|
|
||||||
<label for="attack"><input type="radio" name="mission" value="ATTACK" id="attack" required />Attack</label>
|
|
||||||
<label for="transport"><input type="radio" name="mission" value="TRANSPORT" id="transport" />Transport</label>
|
|
||||||
<label for="transfer"><input type="radio" name="mission" value="TRANSFER" id="transfer" />Transfer</label>
|
|
||||||
<hr />
|
|
||||||
<h2>Send to:</h2>
|
|
||||||
<div class="fleet-destination">
|
|
||||||
<h3>Galaxy</h3>
|
|
||||||
<select id="destination-galaxy" name="destination-galaxy">
|
|
||||||
{galaxies.map(galaxy => <option value={galaxy._id.toString()}>{galaxy.name}</option>)}
|
|
||||||
</select>
|
|
||||||
<h3>Sector</h3>
|
|
||||||
<select id="destination-sector" name="destination-sector"></select>
|
|
||||||
<h3>System</h3>
|
|
||||||
<select id="destination-system" name="destination-system"></select>
|
|
||||||
<div id="destination-system-error"></div>
|
|
||||||
<h3>Planet</h3>
|
|
||||||
<select id="destination-planet" name="destination-planet"></select>
|
|
||||||
<div id="destination-planet-error"></div>
|
|
||||||
</div>
|
|
||||||
<hr />
|
|
||||||
<h2>Cargo</h2>
|
|
||||||
<div class="cargo-container">
|
|
||||||
<div class="cargo-item">
|
|
||||||
<select name="cargo[0][id]" class="select">
|
|
||||||
<option value="coal">Coal</option>
|
|
||||||
<option value="iron">Iron</option>
|
|
||||||
<option value="gold">Gold</option>
|
|
||||||
<option value="water">Water</option>
|
|
||||||
<option value="sulfuric-acid">Sulfuric Acid</option>
|
|
||||||
<option value="liquid-nitrogen">Liquid Nitrogen</option>
|
|
||||||
<option value="hydrogen">Hydrogen</option>
|
|
||||||
<option value="oxygen">Oxygen</option>
|
|
||||||
<option value="helium-3">Helium-3</option>
|
|
||||||
</select>
|
|
||||||
<input type="number" name="cargo[0][amount]" class="input" />
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div id="cargo-add-new">Add new +</div>
|
|
||||||
<hr />
|
|
||||||
<button type="submit">Send fleet</button>
|
|
||||||
</form>
|
|
||||||
</div>
|
|
||||||
</Layout>
|
</Layout>
|
||||||
|
|
||||||
<style>
|
<style>
|
||||||
|
@ -294,6 +157,7 @@ const lang = await getLocales(Astro.cookies.get('language')?.value ?? await getH
|
||||||
flex-wrap: wrap;
|
flex-wrap: wrap;
|
||||||
row-gap: 40px;
|
row-gap: 40px;
|
||||||
column-gap: 2%;
|
column-gap: 2%;
|
||||||
|
margin-top: 40px;
|
||||||
}
|
}
|
||||||
|
|
||||||
#ship-modal-background {
|
#ship-modal-background {
|
||||||
|
@ -358,177 +222,4 @@ const lang = await getLocales(Astro.cookies.get('language')?.value ?? await getH
|
||||||
height: auto;
|
height: auto;
|
||||||
max-height: 1000px;
|
max-height: 1000px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.fleet-send-container {
|
|
||||||
margin-top: 40px;
|
|
||||||
background-color: gray;
|
|
||||||
border-radius: 10px;
|
|
||||||
padding: 2px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.fleet-send-ships {
|
|
||||||
display: flex;
|
|
||||||
flex-direction: row;
|
|
||||||
flex-wrap: wrap;
|
|
||||||
row-gap: 40px;
|
|
||||||
column-gap: 2%;
|
|
||||||
margin-top: 40px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.fleet-ship-card {
|
|
||||||
background-color: gray;
|
|
||||||
border-radius: 10px;
|
|
||||||
padding: 2px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.fleet-ship-card h3 {
|
|
||||||
margin: 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
.fleet-ship-card input {
|
|
||||||
width: 10rem;
|
|
||||||
color: black;
|
|
||||||
}
|
|
||||||
|
|
||||||
.fleet-destination select {
|
|
||||||
width: 10rem;
|
|
||||||
height: 3rem;
|
|
||||||
color: black;
|
|
||||||
background-color: darkgray;
|
|
||||||
}
|
|
||||||
|
|
||||||
.cargo-add-new {
|
|
||||||
background-color: #aaaaaa;
|
|
||||||
border-radius: 10px;
|
|
||||||
padding: 2px;
|
|
||||||
width: fit-content;
|
|
||||||
color: black;
|
|
||||||
}
|
|
||||||
|
|
||||||
.select, .input {
|
|
||||||
color: black;
|
|
||||||
}
|
|
||||||
</style>
|
</style>
|
||||||
<script define:vars={{ sectorsList }}>
|
|
||||||
const destinationGalaxy = document.getElementById('destination-galaxy');
|
|
||||||
const destinationSector = document.getElementById('destination-sector');
|
|
||||||
const destinationSystem = document.getElementById('destination-system');
|
|
||||||
const destinationPlanet = document.getElementById('destination-planet');
|
|
||||||
|
|
||||||
if(!destinationGalaxy || !destinationSector || !destinationSystem || !destinationPlanet) {
|
|
||||||
console.error('Could not find destination elements');
|
|
||||||
return;
|
|
||||||
};
|
|
||||||
|
|
||||||
destinationGalaxy.addEventListener('change', () => {
|
|
||||||
const galaxy = sectorsList.find(galaxy => galaxy._id === destinationGalaxy.value);
|
|
||||||
if(!galaxy) return;
|
|
||||||
|
|
||||||
destinationSector.innerHTML = '';
|
|
||||||
for(const sector of galaxy.sectors) {
|
|
||||||
const opt = document.createElement('option');
|
|
||||||
opt.value = sector._id;
|
|
||||||
opt.innerText = sector.name;
|
|
||||||
destinationSector.appendChild(opt);
|
|
||||||
}
|
|
||||||
|
|
||||||
if(destinationSector.children.length === 0) {
|
|
||||||
const opt = document.createElement('option');
|
|
||||||
opt.value = '';
|
|
||||||
opt.innerText = 'No sectors';
|
|
||||||
destinationSector.appendChild(opt);
|
|
||||||
}
|
|
||||||
|
|
||||||
destinationSector.dispatchEvent(new Event('change'));
|
|
||||||
});
|
|
||||||
|
|
||||||
destinationSector.addEventListener('change', () => {
|
|
||||||
const galaxy = sectorsList.find(galaxy => galaxy._id === destinationGalaxy.value);
|
|
||||||
if(!galaxy) return;
|
|
||||||
|
|
||||||
const sector = galaxy.sectors.find(sector => sector._id === destinationSector.value);
|
|
||||||
if(!sector) return;
|
|
||||||
|
|
||||||
destinationSystem.innerHTML = '';
|
|
||||||
document.getElementById('destination-system-error').innerHTML = '';
|
|
||||||
for(const system of sector.systems) {
|
|
||||||
const opt = document.createElement('option');
|
|
||||||
opt.value = system._id;
|
|
||||||
opt.innerText = system.name;
|
|
||||||
destinationSystem.appendChild(opt);
|
|
||||||
}
|
|
||||||
|
|
||||||
if(destinationSystem.children.length === 0) {
|
|
||||||
const opt = document.createElement('option');
|
|
||||||
opt.value = '';
|
|
||||||
opt.innerText = 'No systems';
|
|
||||||
destinationSystem.appendChild(opt);
|
|
||||||
|
|
||||||
document.getElementById('destination-system-error').innerHTML = "No systems";
|
|
||||||
}
|
|
||||||
|
|
||||||
destinationSystem.dispatchEvent(new Event('change'));
|
|
||||||
});
|
|
||||||
|
|
||||||
destinationSystem.addEventListener('change', () => {
|
|
||||||
const galaxy = sectorsList.find(galaxy => galaxy._id === destinationGalaxy.value);
|
|
||||||
if(!galaxy) return;
|
|
||||||
|
|
||||||
const sector = galaxy.sectors.find(sector => sector._id === destinationSector.value);
|
|
||||||
if(!sector) return;
|
|
||||||
|
|
||||||
const system = sector.systems.find(system => system._id === destinationSystem.value);
|
|
||||||
if(!system) {
|
|
||||||
destinationPlanet.innerHTML = '';
|
|
||||||
const opt = document.createElement('option');
|
|
||||||
opt.value = '';
|
|
||||||
opt.innerText = 'No planets';
|
|
||||||
destinationPlanet.appendChild(opt);
|
|
||||||
document.getElementById('destination-planet-error').innerHTML = "No planets";
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
destinationPlanet.innerHTML = '';
|
|
||||||
document.getElementById('destination-planet-error').innerHTML = '';
|
|
||||||
|
|
||||||
for(const planet of system.planets) {
|
|
||||||
const opt = document.createElement('option');
|
|
||||||
opt.value = planet._id;
|
|
||||||
opt.innerText = planet.name;
|
|
||||||
destinationPlanet.appendChild(opt);
|
|
||||||
}
|
|
||||||
|
|
||||||
if(destinationPlanet.children.length === 0) {
|
|
||||||
const opt = document.createElement('option');
|
|
||||||
opt.value = '';
|
|
||||||
opt.innerText = 'No planets';
|
|
||||||
destinationPlanet.appendChild(opt);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
destinationGalaxy.dispatchEvent(new Event('change'));
|
|
||||||
|
|
||||||
const addNew = document.getElementById('cargo-add-new');
|
|
||||||
|
|
||||||
addNew.addEventListener('click', () => {
|
|
||||||
const cargoContainer = document.querySelector('.cargo-container');
|
|
||||||
const cargoItem = document.createElement('div');
|
|
||||||
cargoItem.classList.add('cargo-item');
|
|
||||||
cargoItem.innerHTML += `
|
|
||||||
<select name="cargo[${cargoContainer.children.length}][id]" class="select">
|
|
||||||
<option value="coal">Coal</option>
|
|
||||||
<option value="iron">Iron</option>
|
|
||||||
<option value="gold">Gold</option>
|
|
||||||
<option value="water">Water</option>
|
|
||||||
<option value="sulfuric-acid">Sulfuric Acid</option>
|
|
||||||
<option value="liquid-nitrogen">Liquid Nitrogen</option>
|
|
||||||
<option value="hydrogen">Hydrogen</option>
|
|
||||||
<option value="oxygen">Oxygen</option>
|
|
||||||
<option value="helium-3">Helium-3</option>
|
|
||||||
</select>
|
|
||||||
<input type="number" name="cargo[${cargoContainer.children.length}][amount]" class="input" />`;
|
|
||||||
|
|
||||||
cargoContainer.appendChild(cargoItem);
|
|
||||||
});
|
|
||||||
|
|
||||||
</script>
|
|
|
@ -44,7 +44,7 @@ const currentLanguage = Astro.cookies.get('language')?.value ?? "en";
|
||||||
<Layout title="Profile">
|
<Layout title="Profile">
|
||||||
<NavBar loggedIn="true" active="profile" />
|
<NavBar loggedIn="true" active="profile" />
|
||||||
<ResourceBar loggedIn="true" />
|
<ResourceBar loggedIn="true" />
|
||||||
{loggedToken}
|
|
||||||
<div class="wrapper">
|
<div class="wrapper">
|
||||||
<h3>{format(getName(lang, 'general', 'user-creation-date'), user?.createdAt.toISOString().slice(0, 19).replace(/-/g, "/").replace("T", " ").toString() ?? "")}</h3>
|
<h3>{format(getName(lang, 'general', 'user-creation-date'), user?.createdAt.toISOString().slice(0, 19).replace(/-/g, "/").replace("T", " ").toString() ?? "")}</h3>
|
||||||
<a href="/logout" class="a-button">{getName(lang, 'general', 'nav-logout')}</a>
|
<a href="/logout" class="a-button">{getName(lang, 'general', 'nav-logout')}</a>
|
||||||
|
|
|
@ -19,24 +19,6 @@ if(checkUser === null || checkUser.username !== username) return Astro.redirect(
|
||||||
const planetId = Astro.cookies.get('planetid')?.value ?? "";
|
const planetId = Astro.cookies.get('planetid')?.value ?? "";
|
||||||
if(planetId === "") return Astro.redirect('/logout');
|
if(planetId === "") return Astro.redirect('/logout');
|
||||||
|
|
||||||
if(Astro.request.method === "POST") {
|
|
||||||
const selectedResearchId = (await Astro.request.formData()).get('id') as string | null;
|
|
||||||
|
|
||||||
const request = await (await fetch(Astro.url.origin + '/api/research/performResearch', {
|
|
||||||
method: 'POST',
|
|
||||||
headers: {
|
|
||||||
'Content-Type': 'application/json',
|
|
||||||
'Authorization': 'Bearer ' + loggedToken
|
|
||||||
},
|
|
||||||
body: JSON.stringify({
|
|
||||||
research: selectedResearchId,
|
|
||||||
planetId
|
|
||||||
})
|
|
||||||
})).json();
|
|
||||||
|
|
||||||
console.log(request);
|
|
||||||
}
|
|
||||||
|
|
||||||
const locale = Astro.cookies.get('language')?.value ?? await getHighestWeightedLanguage(Astro.request.headers.get('accept-language'));
|
const locale = Astro.cookies.get('language')?.value ?? await getHighestWeightedLanguage(Astro.request.headers.get('accept-language'));
|
||||||
|
|
||||||
const lang = await getLocales(locale);
|
const lang = await getLocales(locale);
|
||||||
|
@ -244,4 +226,29 @@ for(const research of researchList) {
|
||||||
if(!backgroundDiv) return;
|
if(!backgroundDiv) return;
|
||||||
backgroundDiv.style.display = 'none';
|
backgroundDiv.style.display = 'none';
|
||||||
});
|
});
|
||||||
|
|
||||||
|
const allButtons = document.getElementsByClassName("item-card-build");
|
||||||
|
|
||||||
|
for(const researchButton of allButtons) {
|
||||||
|
researchButton.addEventListener("click", async () => {
|
||||||
|
const id = researchButton.id.split("_")[1];
|
||||||
|
|
||||||
|
const response = await fetch('/api/research/performResearch', {
|
||||||
|
method: 'POST',
|
||||||
|
headers: {
|
||||||
|
'Content-Type': 'application/json'
|
||||||
|
},
|
||||||
|
body: JSON.stringify({
|
||||||
|
research: id,
|
||||||
|
planetId
|
||||||
|
})
|
||||||
|
});
|
||||||
|
|
||||||
|
if(response.status === 200) {
|
||||||
|
window.location.reload();
|
||||||
|
} else {
|
||||||
|
alert("Failed to build building: " + JSON.stringify(await response.json()));
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
</script>
|
</script>
|
|
@ -41,16 +41,10 @@ if(Astro.request.method === "POST") {
|
||||||
<NavBar loggedIn="true" active="systemManager" />
|
<NavBar loggedIn="true" active="systemManager" />
|
||||||
<ResourceBar />
|
<ResourceBar />
|
||||||
|
|
||||||
<h1>Selected system: {currentSystem.name} in {currentSystem.sector.name} in {currentSystem.sector.galaxy.name} <a href="/game/systemManager/select">(change)</a></h1>
|
<h1>Selected system: {currentSystem.name} <a href="/game/systemManager/select">(change)</a></h1>
|
||||||
<div class="system-links">
|
<div class="planetList">
|
||||||
<a href="/game/systemManager">Overview</a>
|
|
||||||
<a href="/game/systemManager/structures">System-wide structures</a>
|
|
||||||
<a href="/game/systemManager/spaceStations">Space stations</a>
|
|
||||||
<a href="/game/systemManager/asteroids">Asteroids</a>
|
|
||||||
</div>
|
|
||||||
<div class="planet-list">
|
|
||||||
{currentSystem.planets.planets.length === 0 ? <span>No planets in this sector</span> : currentSystem.planets.planets.map(planet => (
|
{currentSystem.planets.planets.length === 0 ? <span>No planets in this sector</span> : currentSystem.planets.planets.map(planet => (
|
||||||
<div class="planet-card">
|
<div class="planetCard">
|
||||||
<h2>{planet.name}<div><form method="post"><input type="hidden" name="planetId" value={planet._id.toString()} /><input type="submit" value="Select" /></form></div></h2>
|
<h2>{planet.name}<div><form method="post"><input type="hidden" name="planetId" value={planet._id.toString()} /><input type="submit" value="Select" /></form></div></h2>
|
||||||
<p>Fields: {planet.fields}</p>
|
<p>Fields: {planet.fields}</p>
|
||||||
<h3>Buildings:</h3>
|
<h3>Buildings:</h3>
|
||||||
|
@ -75,27 +69,7 @@ if(Astro.request.method === "POST") {
|
||||||
color: white;
|
color: white;
|
||||||
}
|
}
|
||||||
|
|
||||||
h1 a {
|
.planetList {
|
||||||
color: lime;
|
|
||||||
}
|
|
||||||
|
|
||||||
.system-links {
|
|
||||||
display: flex;
|
|
||||||
flex-direction: row;
|
|
||||||
justify-content: center;
|
|
||||||
margin-bottom: 1rem;
|
|
||||||
}
|
|
||||||
|
|
||||||
.system-links a {
|
|
||||||
color: white;
|
|
||||||
background-color: #555;
|
|
||||||
padding: 0.5rem;
|
|
||||||
margin: 0 1rem;
|
|
||||||
border-radius: 5px;
|
|
||||||
text-decoration: none;
|
|
||||||
}
|
|
||||||
|
|
||||||
.planet-list {
|
|
||||||
display: flex;
|
display: flex;
|
||||||
flex-direction: row;
|
flex-direction: row;
|
||||||
flex-wrap: wrap;
|
flex-wrap: wrap;
|
||||||
|
|
|
@ -1,223 +0,0 @@
|
||||||
---
|
|
||||||
import { ObjectId } from "mongodb";
|
|
||||||
import NavBar from "../../../components/NavBar.astro";
|
|
||||||
import ResourceBar from "../../../components/ResourceBar.astro";
|
|
||||||
import Layout from "../../../layouts/Layout.astro";
|
|
||||||
import locationManager from "../../../lib/classes/managers/LocationManager";
|
|
||||||
import { getUserByAccessToken } from "../../../lib/db/users";
|
|
||||||
import { getHighestWeightedLanguage, getLocales, getName, getObj } from "../../../lib/utils/langDriver";
|
|
||||||
import ItemCard from "../../../components/ItemCard.astro";
|
|
||||||
|
|
||||||
const loggedToken = Astro.cookies.get('sessionToken')?.value ?? null;
|
|
||||||
const username = Astro.cookies.get('username')?.value ?? "";
|
|
||||||
if(loggedToken === null || username === "") return Astro.redirect('/logout');
|
|
||||||
|
|
||||||
const checkUser = await getUserByAccessToken(loggedToken);
|
|
||||||
if(checkUser === null || checkUser.username !== username) return Astro.redirect('/logout');
|
|
||||||
|
|
||||||
const currentSystemId = Astro.cookies.get('currentSystem')?.value ?? null;
|
|
||||||
|
|
||||||
if(currentSystemId === null) return Astro.redirect('/game/systemManager/select');
|
|
||||||
|
|
||||||
const currentSystem = locationManager.getSystem(new ObjectId(currentSystemId));
|
|
||||||
|
|
||||||
if(currentSystem === undefined) {
|
|
||||||
Astro.cookies.delete('currentSystem');
|
|
||||||
return Astro.redirect('/game/systemManager/select');
|
|
||||||
}
|
|
||||||
|
|
||||||
if(Astro.request.method === "POST") {
|
|
||||||
const selectedStructureId = (await Astro.request.formData()).get('id') as string | null;
|
|
||||||
|
|
||||||
const request = await (await fetch(Astro.url.origin + '/api/structures/createStructure', {
|
|
||||||
method: 'POST',
|
|
||||||
headers: {
|
|
||||||
'Content-Type': 'application/json',
|
|
||||||
'Authorization': 'Bearer ' + loggedToken
|
|
||||||
},
|
|
||||||
body: JSON.stringify({
|
|
||||||
system: currentSystemId,
|
|
||||||
structureId: selectedStructureId
|
|
||||||
})
|
|
||||||
})).json();
|
|
||||||
|
|
||||||
console.log(request);
|
|
||||||
}
|
|
||||||
|
|
||||||
const lang = await getLocales(Astro.cookies.get('language')?.value ?? await getHighestWeightedLanguage(Astro.request.headers.get('accept-language')));
|
|
||||||
|
|
||||||
const modalSet: { [key: string]: { resources: Array<any>, research: Array<any>, buildings: Array<any>, energy: number } } = {};
|
|
||||||
|
|
||||||
const structureList = currentSystem.structures.structuresDB;
|
|
||||||
for(const structure of structureList) {
|
|
||||||
modalSet[structure.id] = {
|
|
||||||
resources: structure.requirements.resources.map(resource => {
|
|
||||||
return {
|
|
||||||
id: resource.id,
|
|
||||||
amount: Math.pow(structure.multiplier, (currentSystem.structures.getStructureById(structure.id)?.level ?? 0) ) * resource.amount
|
|
||||||
};
|
|
||||||
}),
|
|
||||||
research: structure.requirements.research,
|
|
||||||
buildings: structure.requirements.buildings,
|
|
||||||
energy: structure.energy
|
|
||||||
};
|
|
||||||
}
|
|
||||||
---
|
|
||||||
<Layout title="System Manager">
|
|
||||||
<NavBar loggedIn="true" active="systemManager" />
|
|
||||||
<ResourceBar />
|
|
||||||
|
|
||||||
<h1>Selected system: {currentSystem.name} <a href="/game/systemManager/select">(change)</a></h1>
|
|
||||||
<div class="system-links">
|
|
||||||
<a href="/game/systemManager">Overview</a>
|
|
||||||
<a href="/game/systemManager/structures">System-wide structures</a>
|
|
||||||
<a href="/game/systemManager/spaceStations">Space stations</a>
|
|
||||||
<a href="/game/systemManager/asteroids">Asteroids</a>
|
|
||||||
</div>
|
|
||||||
<div id="structure-modal-background">
|
|
||||||
<div id="structure-modal-details" data-structure-id="">
|
|
||||||
<h3>Required resources</h3>
|
|
||||||
<div class="structure-modal-text" id="structure-modal-req-resources">None</div>
|
|
||||||
<h3>Required buildings</h3>
|
|
||||||
<div class="structure-modal-text" id="structure-modal-req-buildings">None</div>
|
|
||||||
<h3>Required research</h3>
|
|
||||||
<div class="structure-modal-text" id="structure-modal-req-research">None</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div class="structure-list">
|
|
||||||
{currentSystem.structures.structuresDB.map(structure => (
|
|
||||||
<ItemCard
|
|
||||||
id={structure.id}
|
|
||||||
name={getName(lang, 'structures', structure.id)}
|
|
||||||
image={`/images/structures/${structure.id}.jpeg`}
|
|
||||||
level={(currentSystem.structures.getStructureById(structure.id)?.level ?? 0).toString()}
|
|
||||||
description={getObj(lang, 'structures', structure.id).description ?? ""}
|
|
||||||
button_type="general"
|
|
||||||
button_name="nav-build"
|
|
||||||
/>
|
|
||||||
))}
|
|
||||||
</div>
|
|
||||||
</Layout>
|
|
||||||
<style>
|
|
||||||
* {
|
|
||||||
color: white;
|
|
||||||
}
|
|
||||||
|
|
||||||
h1 {
|
|
||||||
text-align: center;
|
|
||||||
color: white;
|
|
||||||
}
|
|
||||||
|
|
||||||
h1 a {
|
|
||||||
color: lime;
|
|
||||||
}
|
|
||||||
|
|
||||||
#structure-modal-background {
|
|
||||||
display: none;
|
|
||||||
position: fixed;
|
|
||||||
top: 0;
|
|
||||||
left: 0;
|
|
||||||
width: 100%;
|
|
||||||
height: 100%;
|
|
||||||
background: rgba(0, 0, 0, 0.5);
|
|
||||||
z-index: 100;
|
|
||||||
}
|
|
||||||
|
|
||||||
#structure-modal-details {
|
|
||||||
display: none;
|
|
||||||
position: fixed;
|
|
||||||
top: 50%;
|
|
||||||
left: 50%;
|
|
||||||
transform: translate(-50%, -50%);
|
|
||||||
width: 80%;
|
|
||||||
max-width: 800px;
|
|
||||||
background: rgba(0, 0, 0, 0.9);
|
|
||||||
border-radius: 8px;
|
|
||||||
padding: 1rem;
|
|
||||||
z-index: 101;
|
|
||||||
}
|
|
||||||
|
|
||||||
.structure-modal-text {
|
|
||||||
font-size: 1.5rem;
|
|
||||||
}
|
|
||||||
|
|
||||||
.system-links {
|
|
||||||
display: flex;
|
|
||||||
flex-direction: row;
|
|
||||||
justify-content: center;
|
|
||||||
margin-bottom: 1rem;
|
|
||||||
}
|
|
||||||
|
|
||||||
.system-links a {
|
|
||||||
color: white;
|
|
||||||
background-color: #555;
|
|
||||||
padding: 0.5rem;
|
|
||||||
margin: 0 1rem;
|
|
||||||
border-radius: 5px;
|
|
||||||
text-decoration: none;
|
|
||||||
}
|
|
||||||
|
|
||||||
.structure-list {
|
|
||||||
display: flex;
|
|
||||||
flex-direction: row;
|
|
||||||
flex-wrap: wrap;
|
|
||||||
justify-content: space-evenly;
|
|
||||||
color: white;
|
|
||||||
row-gap: 40px;
|
|
||||||
column-gap: 2%;
|
|
||||||
}
|
|
||||||
|
|
||||||
.structure-card div {
|
|
||||||
margin-top: auto;
|
|
||||||
margin-bottom: auto;
|
|
||||||
margin-left: 2rem;
|
|
||||||
}
|
|
||||||
</style>
|
|
||||||
<script define:vars={{ modalSet, lang }}>
|
|
||||||
const modalResources = document.getElementById("structure-modal-req-resources");
|
|
||||||
const modalBuildings = document.getElementById("structure-modal-req-buildings");
|
|
||||||
const modalResearch = document.getElementById("structure-modal-req-research");
|
|
||||||
|
|
||||||
document.querySelectorAll('.item-card-info-button').forEach((el) => {
|
|
||||||
el.addEventListener('click', () => {
|
|
||||||
// modal
|
|
||||||
const modalDiv = document.getElementById('structure-modal-details');
|
|
||||||
if(!modalDiv) return;
|
|
||||||
modalDiv.style.display = 'block';
|
|
||||||
|
|
||||||
const reqResources = modalSet[el.parentElement.parentElement.dataset.id]?.resources ?? [];
|
|
||||||
const reqBuildings = modalSet[el.parentElement.parentElement.dataset.id]?.buildings ?? [];
|
|
||||||
const reqResearch = modalSet[el.parentElement.parentElement.dataset.id]?.research ?? [];
|
|
||||||
|
|
||||||
modalResources.innerHTML = reqResources.length === 0 ? "None" : reqResources.map(resource => {
|
|
||||||
return `${lang['resources'].find(r => r.id === resource.id).name}: ${resource.amount}`;
|
|
||||||
}).join("<br />");
|
|
||||||
|
|
||||||
modalBuildings.innerHTML = reqBuildings.length === 0 ? "None" : reqBuildings.map(building => {
|
|
||||||
return `${lang['buildings'].find(b => b.id === building.id).name}: ${building.level}`;
|
|
||||||
}).join("<br />");
|
|
||||||
|
|
||||||
modalResearch.innerHTML = reqResearch.length === 0 ? "None" : reqResearch.map(research => {
|
|
||||||
return `${lang['research'].find(r => r.id === research.id).name}: ${research.level}`;
|
|
||||||
}).join("<br />");
|
|
||||||
|
|
||||||
// background
|
|
||||||
const backgroundDiv = document.getElementById('structure-modal-background');
|
|
||||||
if(!backgroundDiv) return;
|
|
||||||
backgroundDiv.style.display = 'block';
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
// close modal on background click
|
|
||||||
const bg = document.getElementById('structure-modal-background');
|
|
||||||
|
|
||||||
bg?.addEventListener('click', () => {
|
|
||||||
const modalDiv = document.getElementById('structure-modal-details');
|
|
||||||
if(!modalDiv) return;
|
|
||||||
modalDiv.style.display = 'none';
|
|
||||||
|
|
||||||
const backgroundDiv = document.getElementById('structure-modal-background');
|
|
||||||
if(!backgroundDiv) return;
|
|
||||||
backgroundDiv.style.display = 'none';
|
|
||||||
});
|
|
||||||
</script>
|
|
|
@ -1,3 +0,0 @@
|
||||||
type MissionType = "TRANSPORT" | "ATTACK" | "TRANSFER";
|
|
||||||
|
|
||||||
export default MissionType;
|
|
|
@ -1,14 +1,11 @@
|
||||||
import { ObjectId } from "mongodb";
|
import { ObjectId } from "mongodb";
|
||||||
import MissionType from "../MissionType";
|
|
||||||
|
|
||||||
export default interface DBFleet {
|
export default interface DBFleet {
|
||||||
_id: ObjectId;
|
_id: ObjectId;
|
||||||
source: ObjectId;
|
source: ObjectId;
|
||||||
destination: ObjectId;
|
destination: ObjectId;
|
||||||
departureTime: Date;
|
finished: boolean;
|
||||||
arrivalTime: Date;
|
|
||||||
returning: boolean;
|
returning: boolean;
|
||||||
mission: MissionType;
|
mission: string;
|
||||||
ships: Array<{ id: string, amount: number }>;
|
ships: Array<{ id: string, amount: number }>;
|
||||||
cargo: Array<{ id: string, amount: number }>;
|
|
||||||
}
|
}
|
|
@ -1,15 +0,0 @@
|
||||||
import { ObjectId } from "mongodb";
|
|
||||||
|
|
||||||
export default interface DBStructure {
|
|
||||||
_id: ObjectId;
|
|
||||||
id: string;
|
|
||||||
description: string;
|
|
||||||
requirements: {
|
|
||||||
buildings: Array<{ id: string, level: number }>,
|
|
||||||
research: Array<{ id: string, level: number }>,
|
|
||||||
resources: Array<{ id: string, amount: number }>,
|
|
||||||
};
|
|
||||||
energy: number;
|
|
||||||
time: number;
|
|
||||||
multiplier: number;
|
|
||||||
}
|
|
|
@ -4,9 +4,5 @@ export default interface DBSystem {
|
||||||
_id: ObjectId;
|
_id: ObjectId;
|
||||||
name: string;
|
name: string;
|
||||||
ownedBy: ObjectId;
|
ownedBy: ObjectId;
|
||||||
structures: Array<{
|
|
||||||
id: string,
|
|
||||||
level: number
|
|
||||||
}>;
|
|
||||||
planets: Array<ObjectId>;
|
planets: Array<ObjectId>;
|
||||||
}
|
}
|
Loading…
Reference in New Issue