2023-06-02 00:20:49 -03:00
|
|
|
import { Account } from "@/src/models/loginModel";
|
2023-06-04 03:06:22 +02:00
|
|
|
import { createInventory } from "@/src/services/inventoryService";
|
2025-03-21 05:19:42 -07:00
|
|
|
import { IDatabaseAccountJson, IDatabaseAccountRequiredFields } from "@/src/types/loginTypes";
|
2023-06-05 04:16:49 +08:00
|
|
|
import { createShip } from "./shipService";
|
2024-12-23 22:44:01 +01:00
|
|
|
import { Document, Types } from "mongoose";
|
2024-02-18 13:58:43 +01:00
|
|
|
import { Loadout } from "@/src/models/inventoryModels/loadoutModel";
|
|
|
|
import { PersonalRooms } from "@/src/models/personalRoomsModel";
|
2024-05-28 13:45:06 +02:00
|
|
|
import { Request } from "express";
|
2024-12-23 22:44:01 +01:00
|
|
|
import { config } from "@/src/services/configService";
|
2025-02-06 04:42:59 -08:00
|
|
|
import { createStats } from "@/src/services/statsService";
|
2025-03-09 07:47:32 -07:00
|
|
|
import crc32 from "crc-32";
|
2023-05-19 15:22:48 -03:00
|
|
|
|
2024-05-28 13:45:06 +02:00
|
|
|
export const isCorrectPassword = (requestPassword: string, databasePassword: string): boolean => {
|
2023-05-23 20:42:06 -04:00
|
|
|
return requestPassword === databasePassword;
|
2023-05-19 15:22:48 -03:00
|
|
|
};
|
|
|
|
|
2024-12-23 22:44:01 +01:00
|
|
|
export const isNameTaken = async (name: string): Promise<boolean> => {
|
|
|
|
return !!(await Account.findOne({ DisplayName: name }));
|
|
|
|
};
|
|
|
|
|
2025-03-21 05:19:42 -07:00
|
|
|
export const createAccount = async (accountData: IDatabaseAccountRequiredFields): Promise<IDatabaseAccountJson> => {
|
2023-05-23 20:42:06 -04:00
|
|
|
const account = new Account(accountData);
|
|
|
|
try {
|
|
|
|
await account.save();
|
2023-12-14 17:34:15 +01:00
|
|
|
const loadoutId = await createLoadout(account._id);
|
2024-02-18 13:58:43 +01:00
|
|
|
const shipId = await createShip(account._id);
|
|
|
|
await createInventory(account._id, { loadOutPresetId: loadoutId, ship: shipId });
|
|
|
|
await createPersonalRooms(account._id, shipId);
|
2025-02-06 04:42:59 -08:00
|
|
|
await createStats(account._id.toString());
|
2023-05-23 20:42:06 -04:00
|
|
|
return account.toJSON();
|
|
|
|
} catch (error) {
|
|
|
|
if (error instanceof Error) {
|
|
|
|
throw new Error(error.message);
|
|
|
|
}
|
|
|
|
throw new Error("error creating account that is not of instance Error");
|
2023-05-19 15:22:48 -03:00
|
|
|
}
|
|
|
|
};
|
|
|
|
|
2024-12-29 21:47:18 +01:00
|
|
|
export const createLoadout = async (accountId: Types.ObjectId): Promise<Types.ObjectId> => {
|
2024-02-18 13:58:43 +01:00
|
|
|
const loadout = new Loadout({ loadoutOwnerId: accountId });
|
2023-12-14 17:34:15 +01:00
|
|
|
const savedLoadout = await loadout.save();
|
|
|
|
return savedLoadout._id;
|
|
|
|
};
|
2024-02-18 13:58:43 +01:00
|
|
|
|
2024-12-29 21:47:18 +01:00
|
|
|
export const createPersonalRooms = async (accountId: Types.ObjectId, shipId: Types.ObjectId): Promise<void> => {
|
2024-02-18 13:58:43 +01:00
|
|
|
const personalRooms = new PersonalRooms({
|
|
|
|
personalRoomsOwnerId: accountId,
|
|
|
|
activeShipId: shipId
|
|
|
|
});
|
2025-01-20 18:25:50 +01:00
|
|
|
if (config.skipTutorial) {
|
2025-02-23 12:22:54 -08:00
|
|
|
// unlocked during Vor's Prize
|
|
|
|
const defaultFeatures = [
|
|
|
|
"/Lotus/Types/Items/ShipFeatureItems/MercuryNavigationFeatureItem",
|
|
|
|
"/Lotus/Types/Items/ShipFeatureItems/ArsenalFeatureItem",
|
|
|
|
"/Lotus/Types/Items/ShipFeatureItems/SocialMenuFeatureItem",
|
|
|
|
"/Lotus/Types/Items/ShipFeatureItems/FoundryFeatureItem",
|
|
|
|
"/Lotus/Types/Items/ShipFeatureItems/ModsFeatureItem"
|
|
|
|
];
|
|
|
|
personalRooms.Ship.Features.push(...defaultFeatures);
|
2025-01-20 18:25:50 +01:00
|
|
|
}
|
2024-02-18 13:58:43 +01:00
|
|
|
await personalRooms.save();
|
|
|
|
};
|
2024-05-28 13:45:06 +02:00
|
|
|
|
2024-12-23 22:44:01 +01:00
|
|
|
// eslint-disable-next-line @typescript-eslint/ban-types
|
2025-03-21 05:19:42 -07:00
|
|
|
export type TAccountDocument = Document<unknown, {}, IDatabaseAccountJson> &
|
2024-12-23 22:44:01 +01:00
|
|
|
IDatabaseAccountJson & { _id: Types.ObjectId; __v: number };
|
|
|
|
|
|
|
|
export const getAccountForRequest = async (req: Request): Promise<TAccountDocument> => {
|
2024-05-28 13:45:06 +02:00
|
|
|
if (!req.query.accountId) {
|
|
|
|
throw new Error("Request is missing accountId parameter");
|
|
|
|
}
|
2025-03-23 09:05:47 -07:00
|
|
|
const nonce: number = parseInt(req.query.nonce as string);
|
|
|
|
if (!nonce) {
|
2024-05-28 13:45:06 +02:00
|
|
|
throw new Error("Request is missing nonce parameter");
|
|
|
|
}
|
2025-03-23 09:05:47 -07:00
|
|
|
|
2025-03-27 03:33:27 -07:00
|
|
|
const account = await Account.findById(req.query.accountId);
|
|
|
|
if (!account || account.Nonce != nonce) {
|
2024-05-28 13:45:06 +02:00
|
|
|
throw new Error("Invalid accountId-nonce pair");
|
|
|
|
}
|
2025-03-09 07:40:37 -07:00
|
|
|
if (account.Dropped && req.query.ct) {
|
|
|
|
account.Dropped = undefined;
|
|
|
|
await account.save();
|
2025-01-19 01:58:35 +01:00
|
|
|
}
|
2025-03-23 09:05:47 -07:00
|
|
|
return account;
|
|
|
|
};
|
|
|
|
|
|
|
|
export const getAccountIdForRequest = async (req: Request): Promise<string> => {
|
|
|
|
return (await getAccountForRequest(req))._id.toString();
|
2024-05-28 13:45:06 +02:00
|
|
|
};
|
2024-12-23 22:44:01 +01:00
|
|
|
|
|
|
|
export const isAdministrator = (account: TAccountDocument): boolean => {
|
2025-03-23 09:06:08 -07:00
|
|
|
return !!config.administratorNames?.find(x => x == account.DisplayName);
|
2024-12-23 22:44:01 +01:00
|
|
|
};
|
2025-03-09 07:47:32 -07:00
|
|
|
|
|
|
|
const platform_magics = [753, 639, 247, 37, 60];
|
|
|
|
export const getSuffixedName = (account: TAccountDocument): string => {
|
|
|
|
const name = account.DisplayName;
|
|
|
|
const platformId = 0;
|
|
|
|
const suffix = ((crc32.str(name.toLowerCase() + "595") >>> 0) + platform_magics[platformId]) % 1000;
|
|
|
|
return name + "#" + suffix.toString().padStart(3, "0");
|
|
|
|
};
|
2025-03-27 12:57:44 -07:00
|
|
|
|
|
|
|
export const getAccountFromSuffixedName = (name: string): Promise<TAccountDocument | null> => {
|
|
|
|
return Account.findOne({ DisplayName: name.split("#")[0] });
|
|
|
|
};
|