AstroCol/src/lib/classes/managers/LocationManager.ts

266 lines
8.3 KiB
TypeScript

import { ObjectId } from "mongodb";
import { getAllFleet } from "../../db/fleet";
import { getAllGalaxies } from "../../db/galaxies";
import { getSectorById } from "../../db/sectors";
import { getSystemById } from "../../db/systems";
import { getAllUsers } from "../../db/users";
import User from "../User";
import FleetManager from "./FleetManager";
import { Planet } from "./PlanetManager";
import SystemManager, { System } from "./SystemManager";
export type Galaxy = {
_id: ObjectId,
name: string,
sectors: Array<Sector>
coords: {
x: number,
y: number
}
}
export type Sector = {
_id: ObjectId,
galaxy: Galaxy,
name: string,
expedition: null,
systems: Array<SystemManager>
}
class LocationManager {
private static instance: LocationManager;
private constructor() {}
public static getInstance(): LocationManager {
if (!LocationManager.instance) {
LocationManager.instance = new LocationManager();
}
return LocationManager.instance;
}
galaxies: Galaxy[] = [];
users: User[] = [];
fleet: FleetManager[] = [];
async init() {
const currentTime = new Date();
this.galaxies = [];
this.users = [];
this.fleet = [];
const users = await getAllUsers();
users.forEach(async user => {
this.users.push(new User(user._id, user.username, user.email, user.createdAt, user.updatedAt, user.lastLogin));
});
console.log(`Loaded ${users.length} users from database`);
const galaxies = await getAllGalaxies();
for(const galaxy of galaxies) {
const galaxyObject: Galaxy = {
_id: galaxy._id,
name: galaxy.name,
sectors: [],
coords: galaxy.coords
};
for(const sectorId of galaxy.sectors) {
const sectorData = await getSectorById(sectorId);
const sectorObject: Sector = {
_id: sectorData._id,
galaxy: galaxyObject,
name: sectorData.name,
expedition: null,
systems: []
};
for(const systemId of sectorData.systems) {
const systemData = await getSystemById(systemId);
const user = this.users.find(user => user.id.equals(systemData.ownedBy));
if(!user) throw new Error("User not found");
const systemObject: System = {
_id: systemData._id,
sector: sectorObject,
name: systemData.name,
ownedBy: user,
//@ts-ignore
structures: null,
//@ts-ignore
resources: null,
//@ts-ignore
ships: null,
planets: [],
asteroids: [],
};
const s = await new SystemManager(systemObject).fillData(systemData);
sectorObject.systems.push(s);
};
console.log(`Loaded ${sectorObject.systems.length} systems from sector ${sectorObject.name}`);
galaxyObject.sectors.push(sectorObject);
};
console.log(`Loaded ${galaxyObject.sectors.length} sectors from galaxy ${galaxyObject.name}`);
this.galaxies.push(galaxyObject);
};
console.log(`Loaded ${this.galaxies.length} galaxies from database`);
for(const user of this.users) {
await user.init();
const userDB = users.find(u => u._id.equals(user.id));
const mainPlanet = this.getPlanet(userDB?.mainPlanet as ObjectId);
if(!mainPlanet) throw new Error(`Main planet not found for user ${user.username} (${user.id})`);
user.mainPlanet = mainPlanet;
};
const fleets = await getAllFleet();
for(const fleet of fleets) {
if(fleet.arrivalTime > currentTime) {
const source = this.getPlanet(fleet.source) || this.getSystem(fleet.source);
const destination = this.getPlanet(fleet.destination) || this.getSystem(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,
fleet.additionalData
));
}
}
console.log(`Loaded ${this.fleet.length} active fleet from database`);
return this;
}
findId(id: ObjectId) {
let found: SystemManager | Planet | null = null;
for(const galaxy of this.galaxies) {
for(const sector of galaxy.sectors) {
for(const system of sector.systems) {
if(system.data._id.equals(id)) {
found = system;
break;
}
for(const planet of system.planets) {
if(planet._id.equals(id)) {
found = planet;
break;
}
}
}
}
}
return found;
}
getGalaxy(_id: ObjectId) {
return this.galaxies.find(galaxy => galaxy._id.equals(_id));
}
getSector(_id: ObjectId) {
let foundSector: Sector | undefined;
this.galaxies.find(galaxy => galaxy.sectors.find(sector => {
if(sector._id.equals(_id)) foundSector = sector;
}));
return foundSector;
}
getSystem(_id: ObjectId) {
let foundSystem: SystemManager | undefined;
this.galaxies.find(galaxy => galaxy.sectors.find(sector => sector.systems.find(system => {
if(system.data._id.equals(_id)) foundSystem = system
})));
return foundSystem
}
getSystemsOwnedBy(id: ObjectId) {
const systems: SystemManager[] = [];
for(const galaxy of this.galaxies) {
for(const sector of galaxy.sectors) {
for(const system of sector.systems) {
if(system.data.ownedBy.id.equals(id)) systems.push(system);
}
}
}
return systems;
}
getPlanet(_id: ObjectId) {
let foundPlanet: Planet | undefined;
for(const galaxy of this.galaxies) {
for(const sector of galaxy.sectors) {
for(const system of sector.systems) {
foundPlanet = system.planets.find(planet => planet._id.equals(_id));
if(foundPlanet) break;
}
if(foundPlanet) break;
}
if(foundPlanet) break;
}
return foundPlanet;
}
getUser(_id: ObjectId) {
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 => {
let found = false;
if(fleet.data.source instanceof SystemManager) found = fleet.data.source.data.ownedBy.id.equals(userId);
else found = fleet.data.source.system.data.ownedBy.id.equals(userId);
if(fleet.data.destination instanceof SystemManager) found = fleet.data.destination.data.ownedBy.id.equals(userId);
else if(!("expedition" in fleet.data.destination)) found = fleet.data.destination.system.data.ownedBy.id.equals(userId);
return found;
});
}
addFleet(fleet: FleetManager) {
this.fleet.push(fleet);
}
}
const locationManager = LocationManager.getInstance();
(async () => {
await locationManager.init();
})();
export default locationManager;