mirror of
https://github.com/sp-tarkov/server.git
synced 2025-02-13 09:50:43 -05:00
This is a big one. 🔥
**Changes:**
- Targets next major release (v4.0.0)
- Switch runtimes from NodeJS to BunJS (bun.sh)
- Typescript library support moved to `ESNext`
- Typescript compile option `verbatimModuleSyntax` enabled
- Updated all interfaces to be imported explicitly as types
- Strict mode enabled
- Reduces the number of tsconfig files
- Pins all dep packages to specific patch versions
- Includes Bun lock file in repo (doesn't cause issues like the
package-lock did)
- Replaces Gulp with a new Typescript based build system
- Adds `core-js` as a workaround for Bun not playing nice with
`reflect-metadata`
- Removes `pkg` and `swc` (Yay Bun!)
- Updated package scripts and entry point system to be more intuitive
- Updated VSCode workspace configurations
- Updated `.gitignore` to align with updated project structure
- Updated Biome configuration to align with updated project structure
- `Program.ts` - Removes call to set encoding on the process
- `global.d.ts` - Added underscores to build globals to match other
global names
- `JsonUtil.ts` - Replaced old `fixJson` package with newer `jsonrepair`
package
- `HashUtil.ts` - Replaced old `buffer-crc32` package with built-in
`node:zlib` package
- `DatabaseImporter.ts` - Updates database validation object to be flat,
where the keys are the relative path to the file
- `BunTimer.ts` - Adds an easy to use timer class that's compatible with
nanoseconds.
**TODO:**
- Look into mod loading. I think we use a TS transpiler for mods and I
believe that can be removed now.
- Bun includes a number of APIs that can be used in place of Node's
packages (built-in or otherwise); HTTP server, WebSocket server, File
IO, Hashing, File Globing, Testing... Each of these should be utilized
where ever possible.
- Update in-repo documentation to reference BunJS instead of NodeJS.
198 lines
9.8 KiB
TypeScript
198 lines
9.8 KiB
TypeScript
import "reflect-metadata";
|
|
import type { IPmcData } from "@spt/models/eft/common/IPmcData";
|
|
import { BotNameService } from "@spt/services/BotNameService";
|
|
import { container } from "tsyringe";
|
|
import { afterEach, beforeEach, describe, expect, it, vi } from "vitest";
|
|
|
|
describe("BotGenerator", () => {
|
|
let botNameService: any;
|
|
|
|
beforeEach(() => {
|
|
botNameService = container.resolve<BotNameService>("BotNameService");
|
|
});
|
|
|
|
afterEach(() => {
|
|
vi.restoreAllMocks();
|
|
});
|
|
|
|
// describe("prepareAndGenerateBots", () =>
|
|
// {
|
|
// it("should return a single generated assault bot", () =>
|
|
// {
|
|
// const mockPlayerProfile = {
|
|
// Info: {
|
|
// Nickname: "Player Nickname",
|
|
// Level: 1
|
|
// }
|
|
// };
|
|
|
|
// vi.spyOn(botGenerator.profileHelper, "getPmcProfile").mockReturnValue(<IPmcData>mockPlayerProfile);
|
|
// vi.spyOn(botGenerator.botEquipmentFilterService.profileHelper, "getPmcProfile").mockReturnValue(<IPmcData>mockPlayerProfile);
|
|
// vi.spyOn(botGenerator.botInventoryGenerator.botWeaponGenerator.botEquipmentModGenerator.profileHelper, "getPmcProfile").mockReturnValue(<IPmcData>mockPlayerProfile);
|
|
|
|
// const sessionId = "12345";
|
|
// const generationDetails: BotGenerationDetails = {
|
|
// isPmc: false,
|
|
// role: "assault",
|
|
// side: "Savage",
|
|
// playerLevel: 1,
|
|
// botRelativeLevelDeltaMax: 10,
|
|
// botCountToGenerate: 1,
|
|
// botDifficulty: "easy",
|
|
// isPlayerScav: false
|
|
// };
|
|
|
|
// const result = botGenerator.prepareAndGenerateBots(sessionId, generationDetails);
|
|
|
|
// expect(result.length).toBe(1);
|
|
// expect(result[0].Info.Side).toBe("Savage");
|
|
// });
|
|
// });
|
|
|
|
describe("generateUniqueBotNickname", () => {
|
|
it("should choose random firstname for non player scav assault bot", () => {
|
|
const botJsonTemplate = { firstName: ["one", "two"], lastName: [] };
|
|
const botGenerationDetails = { isPlayerScav: false, isPmc: false, allPmcsHaveSameNameAsPlayer: false };
|
|
const botRole = "assault";
|
|
|
|
botNameService.botConfig.chanceAssaultScavHasPlayerScavName = 0;
|
|
|
|
const mockPlayerProfile = { Info: { Nickname: "Player Nickname", Level: 1 } };
|
|
vi.spyOn(botNameService.profileHelper, "getPmcProfile").mockReturnValue(<IPmcData>mockPlayerProfile);
|
|
|
|
const result = botNameService.generateUniqueBotNickname(botJsonTemplate, botGenerationDetails, botRole);
|
|
|
|
expect(result).toMatch(/(one|two)/);
|
|
});
|
|
|
|
it("should choose random lastname for non player scav assault bot", () => {
|
|
const botJsonTemplate = { firstName: [], lastName: [["one", "two"]] };
|
|
const botGenerationDetails = { isPlayerScav: false, isPmc: false, allPmcsHaveSameNameAsPlayer: false };
|
|
const botRole = "assault";
|
|
|
|
botNameService.botConfig.chanceAssaultScavHasPlayerScavName = 0;
|
|
|
|
const mockPlayerProfile = { Info: { Nickname: "Player Nickname", Level: 1 } };
|
|
vi.spyOn(botNameService.profileHelper, "getPmcProfile").mockReturnValue(<IPmcData>mockPlayerProfile);
|
|
|
|
const result = botNameService.generateUniqueBotNickname(botJsonTemplate, botGenerationDetails, botRole);
|
|
|
|
expect(result).toMatch(/(one|two)/);
|
|
});
|
|
|
|
it("should choose random firstname and lastname for non player scav assault bot", () => {
|
|
const botJsonTemplate = { firstName: ["first-one", "first-two"], lastName: [["last-one", "last-two"]] };
|
|
const botGenerationDetails = { isPlayerScav: false, isPmc: false, allPmcsHaveSameNameAsPlayer: false };
|
|
const botRole = "assault";
|
|
|
|
botNameService.botConfig.chanceAssaultScavHasPlayerScavName = 0;
|
|
|
|
const mockPlayerProfile = { Info: { Nickname: "Player Nickname", Level: 1 } };
|
|
vi.spyOn(botNameService.profileHelper, "getPmcProfile").mockReturnValue(<IPmcData>mockPlayerProfile);
|
|
|
|
const result = botNameService.generateUniqueBotNickname(botJsonTemplate, botGenerationDetails, botRole);
|
|
|
|
expect(result).toMatch(/first-(one|two) last-(one|two)/);
|
|
});
|
|
|
|
it("should choose random firstname for player scav assault bot", () => {
|
|
const botJsonTemplate = { firstName: ["one", "two"], lastName: [] };
|
|
const botGenerationDetails = { isPlayerScav: true, isPmc: false, allPmcsHaveSameNameAsPlayer: false };
|
|
const botRole = "assault";
|
|
|
|
botNameService.botConfig.chanceAssaultScavHasPlayerScavName = 0;
|
|
|
|
const mockPlayerProfile = { Info: { Nickname: "Player Nickname", Level: 1 } };
|
|
vi.spyOn(botNameService.profileHelper, "getPmcProfile").mockReturnValue(<IPmcData>mockPlayerProfile);
|
|
|
|
const result = botNameService.generateUniqueBotNickname(botJsonTemplate, botGenerationDetails, botRole);
|
|
|
|
expect(result).toMatch(/(one|two)/);
|
|
});
|
|
|
|
it("should choose random lastname for player scav assault bot", () => {
|
|
const botJsonTemplate = { firstName: [], lastName: [["one", "two"]] };
|
|
const botGenerationDetails = { isPlayerScav: true, isPmc: false, allPmcsHaveSameNameAsPlayer: false };
|
|
const botRole = "assault";
|
|
|
|
botNameService.botConfig.chanceAssaultScavHasPlayerScavName = 0;
|
|
|
|
const mockPlayerProfile = { Info: { Nickname: "Player Nickname", Level: 1 } };
|
|
vi.spyOn(botNameService.profileHelper, "getPmcProfile").mockReturnValue(<IPmcData>mockPlayerProfile);
|
|
|
|
const result = botNameService.generateUniqueBotNickname(botJsonTemplate, botGenerationDetails, botRole);
|
|
|
|
expect(result).toMatch(/(one|two)/);
|
|
});
|
|
|
|
it("should choose random firstname and lastname for player scav assault bot", () => {
|
|
const botJsonTemplate = { firstName: ["first-one", "first-two"], lastName: [["last-one", "last-two"]] };
|
|
const botGenerationDetails = { isPlayerScav: true, isPmc: false, allPmcsHaveSameNameAsPlayer: false };
|
|
const botRole = "assault";
|
|
|
|
botNameService.botConfig.chanceAssaultScavHasPlayerScavName = 0;
|
|
|
|
const mockPlayerProfile = { Info: { Nickname: "Player Nickname", Level: 1 } };
|
|
vi.spyOn(botNameService.profileHelper, "getPmcProfile").mockReturnValue(<IPmcData>mockPlayerProfile);
|
|
|
|
const result = botNameService.generateUniqueBotNickname(botJsonTemplate, botGenerationDetails, botRole);
|
|
|
|
expect(result).toMatch(/first-(one|two) last-(one|two)/);
|
|
});
|
|
|
|
it("should append bot type to end of name when showTypeInNickname option is enabled ", () => {
|
|
const botJsonTemplate = { firstName: ["firstname"], lastName: ["lastname"] };
|
|
const botGenerationDetails = { isPlayerScav: false, isPmc: false, allPmcsHaveSameNameAsPlayer: false };
|
|
const botRole = "assault";
|
|
|
|
botNameService.botConfig.chanceAssaultScavHasPlayerScavName = 0;
|
|
botNameService.botConfig.showTypeInNickname = true;
|
|
|
|
const mockPlayerProfile = { Info: { Nickname: "Player Nickname", Level: 1 } };
|
|
vi.spyOn(botNameService.profileHelper, "getPmcProfile").mockReturnValue(<IPmcData>mockPlayerProfile);
|
|
|
|
const result = botNameService.generateUniqueBotNickname(botJsonTemplate, botGenerationDetails, botRole);
|
|
|
|
expect(result).toBe("firstname lastname assault");
|
|
});
|
|
|
|
it("should return name prefix for PMC bot with same name as player if allPmcsHaveSameNameAsPlayer is enabled", () => {
|
|
const botJsonTemplate = { firstName: ["player"], lastName: [] };
|
|
const botGenerationDetails = { isPlayerScav: false, isPmc: true, allPmcsHaveSameNameAsPlayer: true };
|
|
const botRole = "assault";
|
|
|
|
botNameService.botConfig.showTypeInNickname = false;
|
|
botNameService.pmcConfig.addPrefixToSameNamePMCAsPlayerChance = 100;
|
|
|
|
const mockPlayerProfile = { Info: { Nickname: "player", Level: 1 } };
|
|
vi.spyOn(botNameService.profileHelper, "getPmcProfile").mockReturnValue(<IPmcData>mockPlayerProfile);
|
|
vi.spyOn(botNameService.botHelper, "getPmcNicknameOfMaxLength").mockReturnValue("player");
|
|
|
|
const getRandomTextThatMatchesPartialKeySpy = vi
|
|
.spyOn((botNameService as any).localisationService, "getRandomTextThatMatchesPartialKey")
|
|
.mockReturnValue("test");
|
|
|
|
const result = botNameService.generateUniqueBotNickname(botJsonTemplate, botGenerationDetails, botRole);
|
|
|
|
expect(getRandomTextThatMatchesPartialKeySpy).toHaveBeenCalled();
|
|
expect(result).toBe("test player");
|
|
});
|
|
|
|
it("should generate PMC name in brackets behind scav name when chanceAssaultScavHasPlayerScavName is enabled", () => {
|
|
const botJsonTemplate = { firstName: ["scav"], lastName: [] };
|
|
const botGenerationDetails = { isPlayerScav: false, isPmc: false, allPmcsHaveSameNameAsPlayer: false };
|
|
const botRole = "assault";
|
|
|
|
botNameService.botConfig.chanceAssaultScavHasPlayerScavName = 100;
|
|
botNameService.databaseService.getBots().types.usec.firstName = ["player"];
|
|
botNameService.databaseService.getBots().types.bear.firstName = [];
|
|
|
|
const mockPlayerProfile = { Info: { Nickname: "Player", Level: 1 } };
|
|
vi.spyOn(botNameService.profileHelper, "getPmcProfile").mockReturnValue(<IPmcData>mockPlayerProfile);
|
|
|
|
const result = botNameService.generateUniqueBotNickname(botJsonTemplate, botGenerationDetails, botRole);
|
|
expect(result).toBe("scav (player)");
|
|
});
|
|
});
|
|
});
|