3.10.3-dev #43
@ -1,4 +1,4 @@
|
||||
# Mod examples for v3.10.2
|
||||
# Mod examples for v3.10.3
|
||||
|
||||
A collection of example mods that perform typical actions in SPT
|
||||
|
||||
|
@ -3,11 +3,13 @@ import { OnUpdate } from "@spt/di/OnUpdate";
|
||||
import { ICoreConfig } from "@spt/models/spt/config/ICoreConfig";
|
||||
import { ConfigServer } from "@spt/servers/ConfigServer";
|
||||
import { SaveServer } from "@spt/servers/SaveServer";
|
||||
import { BackupService } from "@spt/services/BackupService";
|
||||
export declare class SaveCallbacks implements OnLoad, OnUpdate {
|
||||
protected saveServer: SaveServer;
|
||||
protected configServer: ConfigServer;
|
||||
protected backupService: BackupService;
|
||||
protected coreConfig: ICoreConfig;
|
||||
constructor(saveServer: SaveServer, configServer: ConfigServer);
|
||||
constructor(saveServer: SaveServer, configServer: ConfigServer, backupService: BackupService);
|
||||
onLoad(): Promise<void>;
|
||||
getRoute(): string;
|
||||
onUpdate(secondsSinceLastRun: number): Promise<boolean>;
|
||||
|
@ -1,5 +1,8 @@
|
||||
import { IDialogueChatBot } from "@spt/helpers/Dialogue/IDialogueChatBot";
|
||||
import { DialogueHelper } from "@spt/helpers/DialogueHelper";
|
||||
import { NotificationSendHelper } from "@spt/helpers/NotificationSendHelper";
|
||||
import { ProfileHelper } from "@spt/helpers/ProfileHelper";
|
||||
import { IDeleteFriendRequest } from "@spt/models/eft/dialog/IDeleteFriendRequest";
|
||||
import { IFriendRequestData } from "@spt/models/eft/dialog/IFriendRequestData";
|
||||
import { IFriendRequestSendResponse } from "@spt/models/eft/dialog/IFriendRequestSendResponse";
|
||||
import { IGetAllAttachmentsResponse } from "@spt/models/eft/dialog/IGetAllAttachmentsResponse";
|
||||
@ -20,11 +23,13 @@ export declare class DialogueController {
|
||||
protected saveServer: SaveServer;
|
||||
protected timeUtil: TimeUtil;
|
||||
protected dialogueHelper: DialogueHelper;
|
||||
protected notificationSendHelper: NotificationSendHelper;
|
||||
protected profileHelper: ProfileHelper;
|
||||
protected mailSendService: MailSendService;
|
||||
protected localisationService: LocalisationService;
|
||||
protected configServer: ConfigServer;
|
||||
protected dialogueChatBots: IDialogueChatBot[];
|
||||
constructor(logger: ILogger, saveServer: SaveServer, timeUtil: TimeUtil, dialogueHelper: DialogueHelper, mailSendService: MailSendService, localisationService: LocalisationService, configServer: ConfigServer, dialogueChatBots: IDialogueChatBot[]);
|
||||
constructor(logger: ILogger, saveServer: SaveServer, timeUtil: TimeUtil, dialogueHelper: DialogueHelper, notificationSendHelper: NotificationSendHelper, profileHelper: ProfileHelper, mailSendService: MailSendService, localisationService: LocalisationService, configServer: ConfigServer, dialogueChatBots: IDialogueChatBot[]);
|
||||
registerChatBot(chatBot: IDialogueChatBot): void;
|
||||
/** Handle onUpdate spt event */
|
||||
update(): void;
|
||||
@ -151,4 +156,6 @@ export declare class DialogueController {
|
||||
protected messageHasExpired(message: IMessage): boolean;
|
||||
/** Handle client/friend/request/send */
|
||||
sendFriendRequest(sessionID: string, request: IFriendRequestData): IFriendRequestSendResponse;
|
||||
/** Handle client/friend/delete */
|
||||
deleteFriend(sessionID: string, request: IDeleteFriendRequest): void;
|
||||
}
|
||||
|
@ -72,6 +72,7 @@ export declare class QuestController {
|
||||
*/
|
||||
protected addTaskConditionCountersToProfile(questConditions: IQuestCondition[], pmcData: IPmcData, questId: string): void;
|
||||
/**
|
||||
* TODO - Move this code into RepeatableQuestController
|
||||
* Handle the client accepting a repeatable quest and starting it
|
||||
* Send starting rewards if any to player and
|
||||
* Send start notification if any to player
|
||||
@ -81,7 +82,6 @@ export declare class QuestController {
|
||||
* @returns IItemEventRouterResponse
|
||||
*/
|
||||
acceptRepeatableQuest(pmcData: IPmcData, acceptedQuest: IAcceptQuestRequestData, sessionID: string): IItemEventRouterResponse;
|
||||
protected createAcceptedQuestClientResponse(sessionID: string, pmcData: IPmcData, repeatableQuestProfile: IRepeatableQuest): IItemEventRouterResponse;
|
||||
/**
|
||||
* Look for an accepted quest inside player profile, return matching
|
||||
* @param pmcData Profile to search through
|
||||
|
@ -147,6 +147,18 @@ export declare class RepeatableQuestController {
|
||||
* @returns IItemEventRouterResponse
|
||||
*/
|
||||
changeRepeatableQuest(pmcData: IPmcData, changeRequest: IRepeatableQuestChangeRequest, sessionID: string): IItemEventRouterResponse;
|
||||
/**
|
||||
* Remove the provided quest from pmc and scav character profiles
|
||||
* @param fullProfile Profile to remove quest from
|
||||
* @param questToReplaceId Quest id to remove from profile
|
||||
*/
|
||||
protected removeQuestFromProfile(fullProfile: ISptProfile, questToReplaceId: string): void;
|
||||
/**
|
||||
* Clean up the repeatables `changeRequirement` dictionary of expired data
|
||||
* @param repeatablesOfTypeInProfile The repeatables that have the replaced and new quest
|
||||
* @param replacedQuestId Id of the replaced quest
|
||||
*/
|
||||
protected cleanUpRepeatableChangeRequirements(repeatablesOfTypeInProfile: IPmcDataRepeatableQuest, replacedQuestId: string): void;
|
||||
/**
|
||||
* Find a repeatable (daily/weekly/scav) from a players profile by its id
|
||||
* @param questId Id of quest to find
|
||||
@ -154,7 +166,7 @@ export declare class RepeatableQuestController {
|
||||
* @returns IGetRepeatableByIdResult
|
||||
*/
|
||||
protected getRepeatableById(questId: string, pmcData: IPmcData): IGetRepeatableByIdResult;
|
||||
protected attemptToGenerateRepeatableQuest(pmcData: IPmcData, questTypePool: IQuestTypePool, repeatableConfig: IRepeatableQuestConfig): IRepeatableQuest;
|
||||
protected attemptToGenerateRepeatableQuest(sessionId: string, pmcData: IPmcData, questTypePool: IQuestTypePool, repeatableConfig: IRepeatableQuestConfig): IRepeatableQuest;
|
||||
/**
|
||||
* Some accounts have access to free repeatable quest refreshes
|
||||
* Track the usage of them inside players profile
|
||||
|
@ -33,13 +33,14 @@ export declare class RepeatableQuestGenerator {
|
||||
/**
|
||||
* This method is called by /GetClientRepeatableQuests/ and creates one element of quest type format (see assets/database/templates/repeatableQuests.json).
|
||||
* It randomly draws a quest type (currently Elimination, Completion or Exploration) as well as a trader who is providing the quest
|
||||
* @param sessionId Session id
|
||||
* @param pmcLevel Player's level for requested items and reward generation
|
||||
* @param pmcTraderInfo Players traper standing/rep levels
|
||||
* @param questTypePool Possible quest types pool
|
||||
* @param repeatableConfig Repeatable quest config
|
||||
* @returns IRepeatableQuest
|
||||
*/
|
||||
generateRepeatableQuest(pmcLevel: number, pmcTraderInfo: Record<string, ITraderInfo>, questTypePool: IQuestTypePool, repeatableConfig: IRepeatableQuestConfig): IRepeatableQuest;
|
||||
generateRepeatableQuest(sessionId: string, pmcLevel: number, pmcTraderInfo: Record<string, ITraderInfo>, questTypePool: IQuestTypePool, repeatableConfig: IRepeatableQuestConfig): IRepeatableQuest;
|
||||
/**
|
||||
* Generate a randomised Elimination quest
|
||||
* @param pmcLevel Player's level for requested items and reward generation
|
||||
@ -48,7 +49,7 @@ export declare class RepeatableQuestGenerator {
|
||||
* @param repeatableConfig The configuration for the repeatably kind (daily, weekly) as configured in QuestConfig for the requestd quest
|
||||
* @returns Object of quest type format for "Elimination" (see assets/database/templates/repeatableQuests.json)
|
||||
*/
|
||||
protected generateEliminationQuest(pmcLevel: number, traderId: string, questTypePool: IQuestTypePool, repeatableConfig: IRepeatableQuestConfig): IRepeatableQuest;
|
||||
protected generateEliminationQuest(sessionid: string, pmcLevel: number, traderId: string, questTypePool: IQuestTypePool, repeatableConfig: IRepeatableQuestConfig): IRepeatableQuest;
|
||||
/**
|
||||
* Get a number of kills neded to complete elimination quest
|
||||
* @param targetKey Target type desired e.g. anyPmc/bossBully/Savage
|
||||
@ -83,7 +84,7 @@ export declare class RepeatableQuestGenerator {
|
||||
* @param {object} repeatableConfig The configuration for the repeatably kind (daily, weekly) as configured in QuestConfig for the requestd quest
|
||||
* @returns {object} object of quest type format for "Completion" (see assets/database/templates/repeatableQuests.json)
|
||||
*/
|
||||
protected generateCompletionQuest(pmcLevel: number, traderId: string, repeatableConfig: IRepeatableQuestConfig): IRepeatableQuest;
|
||||
protected generateCompletionQuest(sessionId: string, pmcLevel: number, traderId: string, repeatableConfig: IRepeatableQuestConfig): IRepeatableQuest;
|
||||
/**
|
||||
* A repeatable quest, besides some more or less static components, exists of reward and condition (see assets/database/templates/repeatableQuests.json)
|
||||
* This is a helper method for GenerateCompletionQuest to create a completion condition (of which a completion quest theoretically can have many)
|
||||
@ -102,7 +103,7 @@ export declare class RepeatableQuestGenerator {
|
||||
* @param {object} repeatableConfig The configuration for the repeatably kind (daily, weekly) as configured in QuestConfig for the requestd quest
|
||||
* @returns {object} object of quest type format for "Exploration" (see assets/database/templates/repeatableQuests.json)
|
||||
*/
|
||||
protected generateExplorationQuest(pmcLevel: number, traderId: string, questTypePool: IQuestTypePool, repeatableConfig: IRepeatableQuestConfig): IRepeatableQuest;
|
||||
protected generateExplorationQuest(sessionId: string, pmcLevel: number, traderId: string, questTypePool: IQuestTypePool, repeatableConfig: IRepeatableQuestConfig): IRepeatableQuest;
|
||||
/**
|
||||
* Filter a maps exits to just those for the desired side
|
||||
* @param locationKey Map id (e.g. factory4_day)
|
||||
@ -110,7 +111,7 @@ export declare class RepeatableQuestGenerator {
|
||||
* @returns Array of Exit objects
|
||||
*/
|
||||
protected getLocationExitsForSide(locationKey: string, playerSide: string): IExit[];
|
||||
protected generatePickupQuest(pmcLevel: number, traderId: string, questTypePool: IQuestTypePool, repeatableConfig: IRepeatableQuestConfig): IRepeatableQuest;
|
||||
protected generatePickupQuest(sessionId: string, pmcLevel: number, traderId: string, questTypePool: IQuestTypePool, repeatableConfig: IRepeatableQuestConfig): IRepeatableQuest;
|
||||
/**
|
||||
* Convert a location into an quest code can read (e.g. factory4_day into 55f2d3fd4bdc2d5f408b4567)
|
||||
* @param locationKey e.g factory4_day
|
||||
@ -135,5 +136,5 @@ export declare class RepeatableQuestGenerator {
|
||||
* @returns {object} Object which contains the base elements for repeatable quests of the requests type
|
||||
* (needs to be filled with reward and conditions by called to make a valid quest)
|
||||
*/
|
||||
protected generateRepeatableTemplate(type: string, traderId: string, side: string): IRepeatableQuest;
|
||||
protected generateRepeatableTemplate(type: string, traderId: string, side: string, sessionId: string): IRepeatableQuest;
|
||||
}
|
||||
|
@ -12,6 +12,7 @@ import { DatabaseService } from "@spt/services/DatabaseService";
|
||||
import { ItemFilterService } from "@spt/services/ItemFilterService";
|
||||
import { LocalisationService } from "@spt/services/LocalisationService";
|
||||
import { SeasonalEventService } from "@spt/services/SeasonalEventService";
|
||||
import { HashUtil } from "@spt/utils/HashUtil";
|
||||
import { MathUtil } from "@spt/utils/MathUtil";
|
||||
import { ObjectId } from "@spt/utils/ObjectId";
|
||||
import { RandomUtil } from "@spt/utils/RandomUtil";
|
||||
@ -19,6 +20,7 @@ import { ICloner } from "@spt/utils/cloners/ICloner";
|
||||
export declare class RepeatableQuestRewardGenerator {
|
||||
protected logger: ILogger;
|
||||
protected randomUtil: RandomUtil;
|
||||
protected hashUtil: HashUtil;
|
||||
protected mathUtil: MathUtil;
|
||||
protected databaseService: DatabaseService;
|
||||
protected itemHelper: ItemHelper;
|
||||
@ -31,7 +33,7 @@ export declare class RepeatableQuestRewardGenerator {
|
||||
protected configServer: ConfigServer;
|
||||
protected cloner: ICloner;
|
||||
protected questConfig: IQuestConfig;
|
||||
constructor(logger: ILogger, randomUtil: RandomUtil, mathUtil: MathUtil, databaseService: DatabaseService, itemHelper: ItemHelper, presetHelper: PresetHelper, handbookHelper: HandbookHelper, localisationService: LocalisationService, objectId: ObjectId, itemFilterService: ItemFilterService, seasonalEventService: SeasonalEventService, configServer: ConfigServer, cloner: ICloner);
|
||||
constructor(logger: ILogger, randomUtil: RandomUtil, hashUtil: HashUtil, mathUtil: MathUtil, databaseService: DatabaseService, itemHelper: ItemHelper, presetHelper: PresetHelper, handbookHelper: HandbookHelper, localisationService: LocalisationService, objectId: ObjectId, itemFilterService: ItemFilterService, seasonalEventService: SeasonalEventService, configServer: ConfigServer, cloner: ICloner);
|
||||
/**
|
||||
* Generate the reward for a mission. A reward can consist of:
|
||||
* - Experience
|
||||
@ -127,7 +129,7 @@ export declare class RepeatableQuestRewardGenerator {
|
||||
* @param preset Optional array of preset items
|
||||
* @returns {object} Object of "Reward"-item-type
|
||||
*/
|
||||
protected generateItemReward(tpl: string, count: number, index: number): IQuestReward;
|
||||
protected generateItemReward(tpl: string, count: number, index: number, foundInRaid?: boolean): IQuestReward;
|
||||
/**
|
||||
* Helper to create a reward item structured as required by the client
|
||||
*
|
||||
@ -137,7 +139,7 @@ export declare class RepeatableQuestRewardGenerator {
|
||||
* @param preset Optional array of preset items
|
||||
* @returns {object} Object of "Reward"-item-type
|
||||
*/
|
||||
protected generatePresetReward(tpl: string, count: number, index: number, preset?: IItem[]): IQuestReward;
|
||||
protected generatePresetReward(tpl: string, count: number, index: number, preset?: IItem[], foundInRaid?: boolean): IQuestReward;
|
||||
/**
|
||||
* Picks rewardable items from items.json
|
||||
* This means they must:
|
||||
|
@ -2,6 +2,7 @@ import { ItemHelper } from "@spt/helpers/ItemHelper";
|
||||
import { IPmcData } from "@spt/models/eft/common/IPmcData";
|
||||
import { Common, ICounterKeyValue, IStats } from "@spt/models/eft/common/tables/IBotBase";
|
||||
import { IItem } from "@spt/models/eft/common/tables/IItem";
|
||||
import { ISearchFriendResponse } from "@spt/models/eft/profile/ISearchFriendResponse";
|
||||
import { ISptProfile } from "@spt/models/eft/profile/ISptProfile";
|
||||
import { IValidateNicknameRequestData } from "@spt/models/eft/profile/IValidateNicknameRequestData";
|
||||
import { BonusType } from "@spt/models/enums/BonusType";
|
||||
@ -90,6 +91,24 @@ export declare class ProfileHelper {
|
||||
* @returns ISptProfile object
|
||||
*/
|
||||
getFullProfile(sessionID: string): ISptProfile | undefined;
|
||||
/**
|
||||
* Get full representation of a players profile JSON by the account ID, or undefined if not found
|
||||
* @param accountId Account ID to find
|
||||
* @returns
|
||||
*/
|
||||
getFullProfileByAccountId(accountID: string): ISptProfile | undefined;
|
||||
/**
|
||||
* Retrieve a ChatRoomMember formatted profile for the given session ID
|
||||
* @param sessionID The session ID to return the profile for
|
||||
* @returns
|
||||
*/
|
||||
getChatRoomMemberFromSessionId(sessionID: string): ISearchFriendResponse | undefined;
|
||||
/**
|
||||
* Retrieve a ChatRoomMember formatted profile for the given PMC profile data
|
||||
* @param pmcProfile The PMC profile data to format into a ChatRoomMember structure
|
||||
* @returns
|
||||
*/
|
||||
getChatRoomMemberFromPmcProfile(pmcProfile: IPmcData): ISearchFriendResponse;
|
||||
/**
|
||||
* Get a PMC profile by its session id
|
||||
* @param sessionID Profile id to return
|
||||
|
@ -11,23 +11,36 @@ export interface ILocationBase {
|
||||
Banners: IBanner[];
|
||||
BossLocationSpawn: IBossLocationSpawn[];
|
||||
BotAssault: number;
|
||||
/** Weighting on how likely a bot will be Easy difficulty */
|
||||
BotEasy: number;
|
||||
/** Weighting on how likely a bot will be Hard difficulty */
|
||||
BotHard: number;
|
||||
/** Weighting on how likely a bot will be Impossible difficulty */
|
||||
BotImpossible: number;
|
||||
BotLocationModifier: IBotLocationModifier;
|
||||
BotMarksman: number;
|
||||
/** Maximum Number of bots that are currently alive/loading/delayed */
|
||||
BotMax: number;
|
||||
/** Is not used in 33420 */
|
||||
BotMaxPlayer: number;
|
||||
/** Is not used in 33420 */
|
||||
BotMaxTimePlayer: number;
|
||||
/** Does not even exist in the client in 33420 */
|
||||
BotMaxPvE: number;
|
||||
/** Weighting on how likely a bot will be Normal difficulty */
|
||||
BotNormal: number;
|
||||
/** How many bot slots that need to be open before trying to spawn new bots. */
|
||||
BotSpawnCountStep: number;
|
||||
/** How often to check if bots are spawn-able. In seconds */
|
||||
BotSpawnPeriodCheck: number;
|
||||
/** The bot spawn will toggle on and off in intervals of Off(Min/Max) and On(Min/Max) */
|
||||
BotSpawnTimeOffMax: number;
|
||||
BotSpawnTimeOffMin: number;
|
||||
BotSpawnTimeOnMax: number;
|
||||
BotSpawnTimeOnMin: number;
|
||||
/** How soon bots will be allowed to spawn */
|
||||
BotStart: number;
|
||||
/** After this long bots will no longer spawn */
|
||||
BotStop: number;
|
||||
Description: string;
|
||||
DisabledForScav: boolean;
|
||||
|
@ -33,6 +33,11 @@ export interface IQuest {
|
||||
changeQuestMessageText: string;
|
||||
/** "Pmc" or "Scav" */
|
||||
side: string;
|
||||
acceptanceAndFinishingSource: string;
|
||||
progressSource: string;
|
||||
rankingModes: string[];
|
||||
gameModes: string[];
|
||||
arenaLocations: string[];
|
||||
/** Status of quest to player */
|
||||
sptStatus?: QuestStatus;
|
||||
}
|
||||
@ -148,8 +153,10 @@ export interface IQuestReward {
|
||||
loyaltyLevel?: number;
|
||||
/** Hideout area id */
|
||||
traderId?: string;
|
||||
isEncoded?: boolean;
|
||||
unknown?: boolean;
|
||||
findInRaid?: boolean;
|
||||
gameMode?: string[];
|
||||
/** Game editions whitelisted to get reward */
|
||||
availableInGameEditions?: string[];
|
||||
/** Game editions blacklisted from getting reward */
|
||||
|
@ -3,6 +3,12 @@ export interface IRepeatableQuest extends IQuest {
|
||||
changeCost: IChangeCost[];
|
||||
changeStandingCost: number;
|
||||
sptRepatableGroupName: string;
|
||||
acceptanceAndFinishingSource: string;
|
||||
progressSource: string;
|
||||
rankingModes: string[];
|
||||
gameModes: string[];
|
||||
arenaLocations: string[];
|
||||
questStatus: IRepeatableQuestStatus;
|
||||
}
|
||||
export interface IRepeatableQuestDatabase {
|
||||
templates: IRepeatableTemplates;
|
||||
@ -10,6 +16,14 @@ export interface IRepeatableQuestDatabase {
|
||||
data: IOptions;
|
||||
samples: ISampleQuests[];
|
||||
}
|
||||
export interface IRepeatableQuestStatus {
|
||||
id: string;
|
||||
uid: string;
|
||||
qid: string;
|
||||
startTime: number;
|
||||
status: number;
|
||||
statusTimers: any;
|
||||
}
|
||||
export interface IRepeatableTemplates {
|
||||
Elimination: IQuest;
|
||||
Completion: IQuest;
|
||||
|
@ -8,4 +8,5 @@ export interface Info {
|
||||
Side: string;
|
||||
Level: number;
|
||||
MemberCategory: number;
|
||||
SelectedMemberCategory: number;
|
||||
}
|
||||
|
@ -19,6 +19,8 @@ export interface ISptProfile {
|
||||
traderPurchases?: Record<string, Record<string, ITraderPurchaseData>>;
|
||||
/** Achievements earned by player */
|
||||
achievements: Record<string, number>;
|
||||
/** List of friend profile IDs */
|
||||
friends: string[];
|
||||
}
|
||||
export declare class ITraderPurchaseData {
|
||||
count: number;
|
||||
|
5
TypeScript/10ScopesAndTypes/types/models/eft/ws/IWsFriendsListAccept.d.ts
vendored
Normal file
5
TypeScript/10ScopesAndTypes/types/models/eft/ws/IWsFriendsListAccept.d.ts
vendored
Normal file
@ -0,0 +1,5 @@
|
||||
import { IWsNotificationEvent } from "@spt/models/eft/ws/IWsNotificationEvent";
|
||||
import { ISearchFriendResponse } from "../profile/ISearchFriendResponse";
|
||||
export interface IWsFriendsListAccept extends IWsNotificationEvent {
|
||||
profile: ISearchFriendResponse;
|
||||
}
|
@ -1,4 +1,4 @@
|
||||
export interface IWsNotificationEvent {
|
||||
type: string;
|
||||
eventId: string;
|
||||
eventId?: string;
|
||||
}
|
||||
|
@ -1,5 +1,6 @@
|
||||
export declare enum ConfigTypes {
|
||||
AIRDROP = "spt-airdrop",
|
||||
BACKUP = "spt-backup",
|
||||
BOT = "spt-bot",
|
||||
PMC = "spt-pmc",
|
||||
CORE = "spt-core",
|
||||
|
12
TypeScript/10ScopesAndTypes/types/models/spt/config/IBackupConfig.d.ts
vendored
Normal file
12
TypeScript/10ScopesAndTypes/types/models/spt/config/IBackupConfig.d.ts
vendored
Normal file
@ -0,0 +1,12 @@
|
||||
import { IBaseConfig } from "@spt/models/spt/config/IBaseConfig";
|
||||
export interface IBackupConfig extends IBaseConfig {
|
||||
kind: "spt-backup";
|
||||
enabled: boolean;
|
||||
maxBackups: number;
|
||||
directory: string;
|
||||
backupInterval: IBackupConfigInterval;
|
||||
}
|
||||
export interface IBackupConfigInterval {
|
||||
enabled: boolean;
|
||||
intervalMinutes: number;
|
||||
}
|
@ -7,6 +7,8 @@ export interface IItemConfig extends IBaseConfig {
|
||||
lootableItemBlacklist: string[];
|
||||
/** items that should not be given as rewards */
|
||||
rewardItemBlacklist: string[];
|
||||
/** Item base types that should not be given as rewards */
|
||||
rewardItemTypeBlacklist: string[];
|
||||
/** Items that can only be found on bosses */
|
||||
bossItems: string[];
|
||||
handbookPriceOverride: Record<string, IHandbookPriceOverride>;
|
||||
|
98
TypeScript/10ScopesAndTypes/types/services/BackupService.d.ts
vendored
Normal file
98
TypeScript/10ScopesAndTypes/types/services/BackupService.d.ts
vendored
Normal file
@ -0,0 +1,98 @@
|
||||
import { PreSptModLoader } from "@spt/loaders/PreSptModLoader";
|
||||
import { IBackupConfig } from "@spt/models/spt/config/IBackupConfig";
|
||||
import { ILogger } from "@spt/models/spt/utils/ILogger";
|
||||
import { ConfigServer } from "@spt/servers/ConfigServer";
|
||||
export declare class BackupService {
|
||||
protected logger: ILogger;
|
||||
protected preSptModLoader: PreSptModLoader;
|
||||
protected configServer: ConfigServer;
|
||||
protected backupConfig: IBackupConfig;
|
||||
protected readonly activeServerMods: string[];
|
||||
protected readonly profileDir = "./user/profiles";
|
||||
constructor(logger: ILogger, preSptModLoader: PreSptModLoader, configServer: ConfigServer);
|
||||
/**
|
||||
* Initializes the backup process.
|
||||
*
|
||||
* This method orchestrates the profile backup service. Handles copying profiles to a backup directory and cleaning
|
||||
* up old backups if the number exceeds the configured maximum.
|
||||
*
|
||||
* @returns A promise that resolves when the backup process is complete.
|
||||
*/
|
||||
init(): Promise<void>;
|
||||
/**
|
||||
* Fetches the names of all JSON files in the profile directory.
|
||||
*
|
||||
* This method normalizes the profile directory path and reads all files within it. It then filters the files to
|
||||
* include only those with a `.json` extension and returns their names.
|
||||
*
|
||||
* @returns A promise that resolves to an array of JSON file names.
|
||||
*/
|
||||
protected fetchProfileFiles(): Promise<string[]>;
|
||||
/**
|
||||
* Check to see if the backup service is enabled via the config.
|
||||
*
|
||||
* @returns True if enabled, false otherwise.
|
||||
*/
|
||||
protected isEnabled(): boolean;
|
||||
/**
|
||||
* Generates the target directory path for the backup. The directory path is constructed using the `directory` from
|
||||
* the configuration and the current backup date.
|
||||
*
|
||||
* @returns The target directory path for the backup.
|
||||
*/
|
||||
protected generateBackupTargetDir(): string;
|
||||
/**
|
||||
* Generates a formatted backup date string in the format `YYYY-MM-DD_hh-mm-ss`.
|
||||
*
|
||||
* @returns The formatted backup date string.
|
||||
*/
|
||||
protected generateBackupDate(): string;
|
||||
/**
|
||||
* Cleans up old backups in the backup directory.
|
||||
*
|
||||
* This method reads the backup directory, and sorts backups by modification time. If the number of backups exceeds
|
||||
* the configured maximum, it deletes the oldest backups.
|
||||
*
|
||||
* @returns A promise that resolves when the cleanup is complete.
|
||||
*/
|
||||
protected cleanBackups(): Promise<void>;
|
||||
/**
|
||||
* Retrieves and sorts the backup file paths from the specified directory.
|
||||
*
|
||||
* @param dir - The directory to search for backup files.
|
||||
* @returns A promise that resolves to an array of sorted backup file paths.
|
||||
*/
|
||||
private getBackupPaths;
|
||||
/**
|
||||
* Compares two backup folder names based on their extracted dates.
|
||||
*
|
||||
* @param a - The name of the first backup folder.
|
||||
* @param b - The name of the second backup folder.
|
||||
* @returns The difference in time between the two dates in milliseconds, or `null` if either date is invalid.
|
||||
*/
|
||||
private compareBackupDates;
|
||||
/**
|
||||
* Extracts a date from a folder name string formatted as `YYYY-MM-DD_hh-mm-ss`.
|
||||
*
|
||||
* @param folderName - The name of the folder from which to extract the date.
|
||||
* @returns A Date object if the folder name is in the correct format, otherwise null.
|
||||
*/
|
||||
private extractDateFromFolderName;
|
||||
/**
|
||||
* Removes excess backups from the backup directory.
|
||||
*
|
||||
* @param backups - An array of backup file names to be removed.
|
||||
* @returns A promise that resolves when all specified backups have been removed.
|
||||
*/
|
||||
private removeExcessBackups;
|
||||
/**
|
||||
* Start the backup interval if enabled in the configuration.
|
||||
*/
|
||||
protected startBackupInterval(): void;
|
||||
/**
|
||||
* Get an array of active server mod details.
|
||||
*
|
||||
* @returns An array of mod names.
|
||||
*/
|
||||
protected getActiveServerMods(): string[];
|
||||
}
|
@ -54,6 +54,16 @@ export declare class CircleOfCultistService {
|
||||
* @returns IItemEventRouterResponse
|
||||
*/
|
||||
startSacrifice(sessionId: string, pmcData: IPmcData, request: IHideoutCircleOfCultistProductionStartRequestData): IItemEventRouterResponse;
|
||||
/**
|
||||
* Attempt to add all rewards to cultist circle, if they dont fit remove one and try again until they fit
|
||||
* @param sessionId Session id
|
||||
* @param pmcData Player profile
|
||||
* @param rewards Rewards to send to player
|
||||
* @param containerGrid Cultist grid to add rewards to
|
||||
* @param cultistCircleStashId Stash id
|
||||
* @param output Client output
|
||||
*/
|
||||
protected addRewardsToCircleContainer(sessionId: string, pmcData: IPmcData, rewards: IItem[][], containerGrid: number[][], cultistCircleStashId: string, output: IItemEventRouterResponse): void;
|
||||
/**
|
||||
* Create a map of the possible direct rewards, keyed by the items needed to be sacrificed
|
||||
* @param directRewards Direct rewards array from hideout config
|
||||
@ -156,7 +166,7 @@ export declare class CircleOfCultistService {
|
||||
* @param itemRewardBlacklist Items not to add to pool
|
||||
* @param rewardPool Pool to add items to
|
||||
*/
|
||||
protected addTaskItemRequirementsToRewardPool(pmcData: IPmcData, itemRewardBlacklist: string[], rewardPool: Set<string>): void;
|
||||
protected addTaskItemRequirementsToRewardPool(pmcData: IPmcData, itemRewardBlacklist: Set<string>, rewardPool: Set<string>): void;
|
||||
/**
|
||||
* Adds items the player needs to complete hideout crafts/upgrades to the reward pool
|
||||
* @param hideoutDbData Hideout area data
|
||||
@ -164,7 +174,7 @@ export declare class CircleOfCultistService {
|
||||
* @param itemRewardBlacklist Items not to add to pool
|
||||
* @param rewardPool Pool to add items to
|
||||
*/
|
||||
protected addHideoutUpgradeRequirementsToRewardPool(hideoutDbData: IHideout, pmcData: IPmcData, itemRewardBlacklist: string[], rewardPool: Set<string>): void;
|
||||
protected addHideoutUpgradeRequirementsToRewardPool(hideoutDbData: IHideout, pmcData: IPmcData, itemRewardBlacklist: Set<string>, rewardPool: Set<string>): void;
|
||||
/**
|
||||
* Get all active hideout areas
|
||||
* @param areas Hideout areas to iterate over
|
||||
@ -174,11 +184,11 @@ export declare class CircleOfCultistService {
|
||||
/**
|
||||
* Get array of random reward items
|
||||
* @param rewardPool Reward pool to add to
|
||||
* @param itemRewardBlacklist Reward Blacklist
|
||||
* @param itemRewardBlacklist Item tpls to ignore
|
||||
* @param itemsShouldBeHighValue Should these items meet the valuable threshold
|
||||
* @returns rewardPool
|
||||
* @returns Set of item tpls
|
||||
*/
|
||||
protected generateRandomisedItemsAndAddToRewardPool(rewardPool: Set<string>, itemRewardBlacklist: string[], itemsShouldBeHighValue: boolean): Set<string>;
|
||||
protected generateRandomisedItemsAndAddToRewardPool(rewardPool: Set<string>, itemRewardBlacklist: Set<string>, itemsShouldBeHighValue: boolean): Set<string>;
|
||||
/**
|
||||
* Iterate over passed in hideout requirements and return the Item
|
||||
* @param requirements Requirements to iterate over
|
||||
|
@ -36,6 +36,11 @@ export declare class ItemFilterService {
|
||||
* @returns string array of item tpls
|
||||
*/
|
||||
getItemRewardBlacklist(): string[];
|
||||
/**
|
||||
* Get an array of item types that should never be given as a reward to player
|
||||
* @returns string array of item base ids
|
||||
*/
|
||||
getItemRewardBaseTypeBlacklist(): string[];
|
||||
/**
|
||||
* Return every template id blacklisted in config/item.json
|
||||
* @returns string array of blacklisted tempalte ids
|
||||
|
@ -4,10 +4,10 @@ import { ICoreConfig } from "@spt/models/spt/config/ICoreConfig";
|
||||
import { ILogger } from "@spt/models/spt/utils/ILogger";
|
||||
import { ConfigServer } from "@spt/servers/ConfigServer";
|
||||
import { HttpServer } from "@spt/servers/HttpServer";
|
||||
import { DatabaseService } from "@spt/services/DatabaseService";
|
||||
import { LocalisationService } from "@spt/services/LocalisationService";
|
||||
import { EncodingUtil } from "@spt/utils/EncodingUtil";
|
||||
import { TimeUtil } from "@spt/utils/TimeUtil";
|
||||
import { DatabaseService } from "@spt/services/DatabaseService";
|
||||
export declare class App {
|
||||
protected logger: ILogger;
|
||||
protected timeUtil: TimeUtil;
|
||||
|
@ -106,6 +106,11 @@ export declare class RandomUtil {
|
||||
protected cloner: ICloner;
|
||||
protected logger: ILogger;
|
||||
constructor(cloner: ICloner, logger: ILogger);
|
||||
/**
|
||||
* The IEEE-754 standard for double-precision floating-point numbers limits the number of digits (including both
|
||||
* integer + fractional parts) to about 15–17 significant digits. 15 is a safe upper bound, so we'll use that.
|
||||
*/
|
||||
private static readonly MAX_SIGNIFICANT_DIGITS;
|
||||
/**
|
||||
* Generates a secure random number between 0 (inclusive) and 1 (exclusive).
|
||||
*
|
||||
@ -116,6 +121,16 @@ export declare class RandomUtil {
|
||||
* @returns A secure random number between 0 (inclusive) and 1 (exclusive).
|
||||
*/
|
||||
private getSecureRandomNumber;
|
||||
/**
|
||||
* Determines the number of decimal places in a number.
|
||||
*
|
||||
* @param num - The number to analyze.
|
||||
* @returns The number of decimal places, or 0 if none exist.
|
||||
* @remarks There is a mathematical way to determine this, but it's not as simple as it seams due to floating point
|
||||
* precision issues. This method is a simple workaround that converts the number to a string and splits it.
|
||||
* It's not the most efficient but it *is* the most reliable and easy to understand. Come at me.
|
||||
*/
|
||||
private getNumberPrecision;
|
||||
/**
|
||||
* Generates a random integer between the specified minimum and maximum values, inclusive.
|
||||
*
|
||||
@ -173,7 +188,7 @@ export declare class RandomUtil {
|
||||
/**
|
||||
* Returns a random string from the provided array of strings.
|
||||
*
|
||||
* This method is separate from getArrayValue so we can use a generic inferance with getArrayValue.
|
||||
* This method is separate from getArrayValue so we can use a generic inference with getArrayValue.
|
||||
*
|
||||
* @param arr - The array of strings to select a random value from.
|
||||
* @returns A randomly selected string from the array.
|
||||
@ -225,12 +240,27 @@ export declare class RandomUtil {
|
||||
getNormallyDistributedRandomNumber(mean: number, sigma: number, attempt?: number): number;
|
||||
/**
|
||||
* Generates a random integer between the specified range.
|
||||
* Low and high parameters are floored to integers.
|
||||
*
|
||||
* TODO: v3.11 - This method should not accept non-integer numbers.
|
||||
*
|
||||
* @param low - The lower bound of the range (inclusive).
|
||||
* @param high - The upper bound of the range (exclusive). If not provided, the range will be from 0 to `low`.
|
||||
* @returns A random integer within the specified range.
|
||||
*/
|
||||
randInt(low: number, high?: number): number;
|
||||
/**
|
||||
* Generates a random number between two given values with optional precision.
|
||||
*
|
||||
* @param value1 - The first value to determine the range.
|
||||
* @param value2 - The second value to determine the range. If not provided, 0 is used.
|
||||
* @param precision - The number of decimal places to round the result to. Must be a positive integer between 0
|
||||
* and MAX_PRECISION, inclusive. If not provided, precision is determined by the input values.
|
||||
* @returns A random floating-point number between `value1` and `value2` (inclusive) with the specified precision.
|
||||
* @throws Will throw an error if `precision` is not a positive integer, if `value1` or `value2` are not finite
|
||||
* numbers, or if the precision exceeds the maximum allowed for the given values.
|
||||
*/
|
||||
randNum(value1: number, value2?: number, precision?: number | null): number;
|
||||
/**
|
||||
* Draws a specified number of random elements from a given list.
|
||||
*
|
||||
|
@ -3,11 +3,13 @@ import { OnUpdate } from "@spt/di/OnUpdate";
|
||||
import { ICoreConfig } from "@spt/models/spt/config/ICoreConfig";
|
||||
import { ConfigServer } from "@spt/servers/ConfigServer";
|
||||
import { SaveServer } from "@spt/servers/SaveServer";
|
||||
import { BackupService } from "@spt/services/BackupService";
|
||||
export declare class SaveCallbacks implements OnLoad, OnUpdate {
|
||||
protected saveServer: SaveServer;
|
||||
protected configServer: ConfigServer;
|
||||
protected backupService: BackupService;
|
||||
protected coreConfig: ICoreConfig;
|
||||
constructor(saveServer: SaveServer, configServer: ConfigServer);
|
||||
constructor(saveServer: SaveServer, configServer: ConfigServer, backupService: BackupService);
|
||||
onLoad(): Promise<void>;
|
||||
getRoute(): string;
|
||||
onUpdate(secondsSinceLastRun: number): Promise<boolean>;
|
||||
|
@ -1,5 +1,8 @@
|
||||
import { IDialogueChatBot } from "@spt/helpers/Dialogue/IDialogueChatBot";
|
||||
import { DialogueHelper } from "@spt/helpers/DialogueHelper";
|
||||
import { NotificationSendHelper } from "@spt/helpers/NotificationSendHelper";
|
||||
import { ProfileHelper } from "@spt/helpers/ProfileHelper";
|
||||
import { IDeleteFriendRequest } from "@spt/models/eft/dialog/IDeleteFriendRequest";
|
||||
import { IFriendRequestData } from "@spt/models/eft/dialog/IFriendRequestData";
|
||||
import { IFriendRequestSendResponse } from "@spt/models/eft/dialog/IFriendRequestSendResponse";
|
||||
import { IGetAllAttachmentsResponse } from "@spt/models/eft/dialog/IGetAllAttachmentsResponse";
|
||||
@ -20,11 +23,13 @@ export declare class DialogueController {
|
||||
protected saveServer: SaveServer;
|
||||
protected timeUtil: TimeUtil;
|
||||
protected dialogueHelper: DialogueHelper;
|
||||
protected notificationSendHelper: NotificationSendHelper;
|
||||
protected profileHelper: ProfileHelper;
|
||||
protected mailSendService: MailSendService;
|
||||
protected localisationService: LocalisationService;
|
||||
protected configServer: ConfigServer;
|
||||
protected dialogueChatBots: IDialogueChatBot[];
|
||||
constructor(logger: ILogger, saveServer: SaveServer, timeUtil: TimeUtil, dialogueHelper: DialogueHelper, mailSendService: MailSendService, localisationService: LocalisationService, configServer: ConfigServer, dialogueChatBots: IDialogueChatBot[]);
|
||||
constructor(logger: ILogger, saveServer: SaveServer, timeUtil: TimeUtil, dialogueHelper: DialogueHelper, notificationSendHelper: NotificationSendHelper, profileHelper: ProfileHelper, mailSendService: MailSendService, localisationService: LocalisationService, configServer: ConfigServer, dialogueChatBots: IDialogueChatBot[]);
|
||||
registerChatBot(chatBot: IDialogueChatBot): void;
|
||||
/** Handle onUpdate spt event */
|
||||
update(): void;
|
||||
@ -151,4 +156,6 @@ export declare class DialogueController {
|
||||
protected messageHasExpired(message: IMessage): boolean;
|
||||
/** Handle client/friend/request/send */
|
||||
sendFriendRequest(sessionID: string, request: IFriendRequestData): IFriendRequestSendResponse;
|
||||
/** Handle client/friend/delete */
|
||||
deleteFriend(sessionID: string, request: IDeleteFriendRequest): void;
|
||||
}
|
||||
|
@ -72,6 +72,7 @@ export declare class QuestController {
|
||||
*/
|
||||
protected addTaskConditionCountersToProfile(questConditions: IQuestCondition[], pmcData: IPmcData, questId: string): void;
|
||||
/**
|
||||
* TODO - Move this code into RepeatableQuestController
|
||||
* Handle the client accepting a repeatable quest and starting it
|
||||
* Send starting rewards if any to player and
|
||||
* Send start notification if any to player
|
||||
@ -81,7 +82,6 @@ export declare class QuestController {
|
||||
* @returns IItemEventRouterResponse
|
||||
*/
|
||||
acceptRepeatableQuest(pmcData: IPmcData, acceptedQuest: IAcceptQuestRequestData, sessionID: string): IItemEventRouterResponse;
|
||||
protected createAcceptedQuestClientResponse(sessionID: string, pmcData: IPmcData, repeatableQuestProfile: IRepeatableQuest): IItemEventRouterResponse;
|
||||
/**
|
||||
* Look for an accepted quest inside player profile, return matching
|
||||
* @param pmcData Profile to search through
|
||||
|
@ -147,6 +147,18 @@ export declare class RepeatableQuestController {
|
||||
* @returns IItemEventRouterResponse
|
||||
*/
|
||||
changeRepeatableQuest(pmcData: IPmcData, changeRequest: IRepeatableQuestChangeRequest, sessionID: string): IItemEventRouterResponse;
|
||||
/**
|
||||
* Remove the provided quest from pmc and scav character profiles
|
||||
* @param fullProfile Profile to remove quest from
|
||||
* @param questToReplaceId Quest id to remove from profile
|
||||
*/
|
||||
protected removeQuestFromProfile(fullProfile: ISptProfile, questToReplaceId: string): void;
|
||||
/**
|
||||
* Clean up the repeatables `changeRequirement` dictionary of expired data
|
||||
* @param repeatablesOfTypeInProfile The repeatables that have the replaced and new quest
|
||||
* @param replacedQuestId Id of the replaced quest
|
||||
*/
|
||||
protected cleanUpRepeatableChangeRequirements(repeatablesOfTypeInProfile: IPmcDataRepeatableQuest, replacedQuestId: string): void;
|
||||
/**
|
||||
* Find a repeatable (daily/weekly/scav) from a players profile by its id
|
||||
* @param questId Id of quest to find
|
||||
@ -154,7 +166,7 @@ export declare class RepeatableQuestController {
|
||||
* @returns IGetRepeatableByIdResult
|
||||
*/
|
||||
protected getRepeatableById(questId: string, pmcData: IPmcData): IGetRepeatableByIdResult;
|
||||
protected attemptToGenerateRepeatableQuest(pmcData: IPmcData, questTypePool: IQuestTypePool, repeatableConfig: IRepeatableQuestConfig): IRepeatableQuest;
|
||||
protected attemptToGenerateRepeatableQuest(sessionId: string, pmcData: IPmcData, questTypePool: IQuestTypePool, repeatableConfig: IRepeatableQuestConfig): IRepeatableQuest;
|
||||
/**
|
||||
* Some accounts have access to free repeatable quest refreshes
|
||||
* Track the usage of them inside players profile
|
||||
|
@ -33,13 +33,14 @@ export declare class RepeatableQuestGenerator {
|
||||
/**
|
||||
* This method is called by /GetClientRepeatableQuests/ and creates one element of quest type format (see assets/database/templates/repeatableQuests.json).
|
||||
* It randomly draws a quest type (currently Elimination, Completion or Exploration) as well as a trader who is providing the quest
|
||||
* @param sessionId Session id
|
||||
* @param pmcLevel Player's level for requested items and reward generation
|
||||
* @param pmcTraderInfo Players traper standing/rep levels
|
||||
* @param questTypePool Possible quest types pool
|
||||
* @param repeatableConfig Repeatable quest config
|
||||
* @returns IRepeatableQuest
|
||||
*/
|
||||
generateRepeatableQuest(pmcLevel: number, pmcTraderInfo: Record<string, ITraderInfo>, questTypePool: IQuestTypePool, repeatableConfig: IRepeatableQuestConfig): IRepeatableQuest;
|
||||
generateRepeatableQuest(sessionId: string, pmcLevel: number, pmcTraderInfo: Record<string, ITraderInfo>, questTypePool: IQuestTypePool, repeatableConfig: IRepeatableQuestConfig): IRepeatableQuest;
|
||||
/**
|
||||
* Generate a randomised Elimination quest
|
||||
* @param pmcLevel Player's level for requested items and reward generation
|
||||
@ -48,7 +49,7 @@ export declare class RepeatableQuestGenerator {
|
||||
* @param repeatableConfig The configuration for the repeatably kind (daily, weekly) as configured in QuestConfig for the requestd quest
|
||||
* @returns Object of quest type format for "Elimination" (see assets/database/templates/repeatableQuests.json)
|
||||
*/
|
||||
protected generateEliminationQuest(pmcLevel: number, traderId: string, questTypePool: IQuestTypePool, repeatableConfig: IRepeatableQuestConfig): IRepeatableQuest;
|
||||
protected generateEliminationQuest(sessionid: string, pmcLevel: number, traderId: string, questTypePool: IQuestTypePool, repeatableConfig: IRepeatableQuestConfig): IRepeatableQuest;
|
||||
/**
|
||||
* Get a number of kills neded to complete elimination quest
|
||||
* @param targetKey Target type desired e.g. anyPmc/bossBully/Savage
|
||||
@ -83,7 +84,7 @@ export declare class RepeatableQuestGenerator {
|
||||
* @param {object} repeatableConfig The configuration for the repeatably kind (daily, weekly) as configured in QuestConfig for the requestd quest
|
||||
* @returns {object} object of quest type format for "Completion" (see assets/database/templates/repeatableQuests.json)
|
||||
*/
|
||||
protected generateCompletionQuest(pmcLevel: number, traderId: string, repeatableConfig: IRepeatableQuestConfig): IRepeatableQuest;
|
||||
protected generateCompletionQuest(sessionId: string, pmcLevel: number, traderId: string, repeatableConfig: IRepeatableQuestConfig): IRepeatableQuest;
|
||||
/**
|
||||
* A repeatable quest, besides some more or less static components, exists of reward and condition (see assets/database/templates/repeatableQuests.json)
|
||||
* This is a helper method for GenerateCompletionQuest to create a completion condition (of which a completion quest theoretically can have many)
|
||||
@ -102,7 +103,7 @@ export declare class RepeatableQuestGenerator {
|
||||
* @param {object} repeatableConfig The configuration for the repeatably kind (daily, weekly) as configured in QuestConfig for the requestd quest
|
||||
* @returns {object} object of quest type format for "Exploration" (see assets/database/templates/repeatableQuests.json)
|
||||
*/
|
||||
protected generateExplorationQuest(pmcLevel: number, traderId: string, questTypePool: IQuestTypePool, repeatableConfig: IRepeatableQuestConfig): IRepeatableQuest;
|
||||
protected generateExplorationQuest(sessionId: string, pmcLevel: number, traderId: string, questTypePool: IQuestTypePool, repeatableConfig: IRepeatableQuestConfig): IRepeatableQuest;
|
||||
/**
|
||||
* Filter a maps exits to just those for the desired side
|
||||
* @param locationKey Map id (e.g. factory4_day)
|
||||
@ -110,7 +111,7 @@ export declare class RepeatableQuestGenerator {
|
||||
* @returns Array of Exit objects
|
||||
*/
|
||||
protected getLocationExitsForSide(locationKey: string, playerSide: string): IExit[];
|
||||
protected generatePickupQuest(pmcLevel: number, traderId: string, questTypePool: IQuestTypePool, repeatableConfig: IRepeatableQuestConfig): IRepeatableQuest;
|
||||
protected generatePickupQuest(sessionId: string, pmcLevel: number, traderId: string, questTypePool: IQuestTypePool, repeatableConfig: IRepeatableQuestConfig): IRepeatableQuest;
|
||||
/**
|
||||
* Convert a location into an quest code can read (e.g. factory4_day into 55f2d3fd4bdc2d5f408b4567)
|
||||
* @param locationKey e.g factory4_day
|
||||
@ -135,5 +136,5 @@ export declare class RepeatableQuestGenerator {
|
||||
* @returns {object} Object which contains the base elements for repeatable quests of the requests type
|
||||
* (needs to be filled with reward and conditions by called to make a valid quest)
|
||||
*/
|
||||
protected generateRepeatableTemplate(type: string, traderId: string, side: string): IRepeatableQuest;
|
||||
protected generateRepeatableTemplate(type: string, traderId: string, side: string, sessionId: string): IRepeatableQuest;
|
||||
}
|
||||
|
@ -12,6 +12,7 @@ import { DatabaseService } from "@spt/services/DatabaseService";
|
||||
import { ItemFilterService } from "@spt/services/ItemFilterService";
|
||||
import { LocalisationService } from "@spt/services/LocalisationService";
|
||||
import { SeasonalEventService } from "@spt/services/SeasonalEventService";
|
||||
import { HashUtil } from "@spt/utils/HashUtil";
|
||||
import { MathUtil } from "@spt/utils/MathUtil";
|
||||
import { ObjectId } from "@spt/utils/ObjectId";
|
||||
import { RandomUtil } from "@spt/utils/RandomUtil";
|
||||
@ -19,6 +20,7 @@ import { ICloner } from "@spt/utils/cloners/ICloner";
|
||||
export declare class RepeatableQuestRewardGenerator {
|
||||
protected logger: ILogger;
|
||||
protected randomUtil: RandomUtil;
|
||||
protected hashUtil: HashUtil;
|
||||
protected mathUtil: MathUtil;
|
||||
protected databaseService: DatabaseService;
|
||||
protected itemHelper: ItemHelper;
|
||||
@ -31,7 +33,7 @@ export declare class RepeatableQuestRewardGenerator {
|
||||
protected configServer: ConfigServer;
|
||||
protected cloner: ICloner;
|
||||
protected questConfig: IQuestConfig;
|
||||
constructor(logger: ILogger, randomUtil: RandomUtil, mathUtil: MathUtil, databaseService: DatabaseService, itemHelper: ItemHelper, presetHelper: PresetHelper, handbookHelper: HandbookHelper, localisationService: LocalisationService, objectId: ObjectId, itemFilterService: ItemFilterService, seasonalEventService: SeasonalEventService, configServer: ConfigServer, cloner: ICloner);
|
||||
constructor(logger: ILogger, randomUtil: RandomUtil, hashUtil: HashUtil, mathUtil: MathUtil, databaseService: DatabaseService, itemHelper: ItemHelper, presetHelper: PresetHelper, handbookHelper: HandbookHelper, localisationService: LocalisationService, objectId: ObjectId, itemFilterService: ItemFilterService, seasonalEventService: SeasonalEventService, configServer: ConfigServer, cloner: ICloner);
|
||||
/**
|
||||
* Generate the reward for a mission. A reward can consist of:
|
||||
* - Experience
|
||||
@ -127,7 +129,7 @@ export declare class RepeatableQuestRewardGenerator {
|
||||
* @param preset Optional array of preset items
|
||||
* @returns {object} Object of "Reward"-item-type
|
||||
*/
|
||||
protected generateItemReward(tpl: string, count: number, index: number): IQuestReward;
|
||||
protected generateItemReward(tpl: string, count: number, index: number, foundInRaid?: boolean): IQuestReward;
|
||||
/**
|
||||
* Helper to create a reward item structured as required by the client
|
||||
*
|
||||
@ -137,7 +139,7 @@ export declare class RepeatableQuestRewardGenerator {
|
||||
* @param preset Optional array of preset items
|
||||
* @returns {object} Object of "Reward"-item-type
|
||||
*/
|
||||
protected generatePresetReward(tpl: string, count: number, index: number, preset?: IItem[]): IQuestReward;
|
||||
protected generatePresetReward(tpl: string, count: number, index: number, preset?: IItem[], foundInRaid?: boolean): IQuestReward;
|
||||
/**
|
||||
* Picks rewardable items from items.json
|
||||
* This means they must:
|
||||
|
@ -2,6 +2,7 @@ import { ItemHelper } from "@spt/helpers/ItemHelper";
|
||||
import { IPmcData } from "@spt/models/eft/common/IPmcData";
|
||||
import { Common, ICounterKeyValue, IStats } from "@spt/models/eft/common/tables/IBotBase";
|
||||
import { IItem } from "@spt/models/eft/common/tables/IItem";
|
||||
import { ISearchFriendResponse } from "@spt/models/eft/profile/ISearchFriendResponse";
|
||||
import { ISptProfile } from "@spt/models/eft/profile/ISptProfile";
|
||||
import { IValidateNicknameRequestData } from "@spt/models/eft/profile/IValidateNicknameRequestData";
|
||||
import { BonusType } from "@spt/models/enums/BonusType";
|
||||
@ -90,6 +91,24 @@ export declare class ProfileHelper {
|
||||
* @returns ISptProfile object
|
||||
*/
|
||||
getFullProfile(sessionID: string): ISptProfile | undefined;
|
||||
/**
|
||||
* Get full representation of a players profile JSON by the account ID, or undefined if not found
|
||||
* @param accountId Account ID to find
|
||||
* @returns
|
||||
*/
|
||||
getFullProfileByAccountId(accountID: string): ISptProfile | undefined;
|
||||
/**
|
||||
* Retrieve a ChatRoomMember formatted profile for the given session ID
|
||||
* @param sessionID The session ID to return the profile for
|
||||
* @returns
|
||||
*/
|
||||
getChatRoomMemberFromSessionId(sessionID: string): ISearchFriendResponse | undefined;
|
||||
/**
|
||||
* Retrieve a ChatRoomMember formatted profile for the given PMC profile data
|
||||
* @param pmcProfile The PMC profile data to format into a ChatRoomMember structure
|
||||
* @returns
|
||||
*/
|
||||
getChatRoomMemberFromPmcProfile(pmcProfile: IPmcData): ISearchFriendResponse;
|
||||
/**
|
||||
* Get a PMC profile by its session id
|
||||
* @param sessionID Profile id to return
|
||||
|
@ -11,23 +11,36 @@ export interface ILocationBase {
|
||||
Banners: IBanner[];
|
||||
BossLocationSpawn: IBossLocationSpawn[];
|
||||
BotAssault: number;
|
||||
/** Weighting on how likely a bot will be Easy difficulty */
|
||||
BotEasy: number;
|
||||
/** Weighting on how likely a bot will be Hard difficulty */
|
||||
BotHard: number;
|
||||
/** Weighting on how likely a bot will be Impossible difficulty */
|
||||
BotImpossible: number;
|
||||
BotLocationModifier: IBotLocationModifier;
|
||||
BotMarksman: number;
|
||||
/** Maximum Number of bots that are currently alive/loading/delayed */
|
||||
BotMax: number;
|
||||
/** Is not used in 33420 */
|
||||
BotMaxPlayer: number;
|
||||
/** Is not used in 33420 */
|
||||
BotMaxTimePlayer: number;
|
||||
/** Does not even exist in the client in 33420 */
|
||||
BotMaxPvE: number;
|
||||
/** Weighting on how likely a bot will be Normal difficulty */
|
||||
BotNormal: number;
|
||||
/** How many bot slots that need to be open before trying to spawn new bots. */
|
||||
BotSpawnCountStep: number;
|
||||
/** How often to check if bots are spawn-able. In seconds */
|
||||
BotSpawnPeriodCheck: number;
|
||||
/** The bot spawn will toggle on and off in intervals of Off(Min/Max) and On(Min/Max) */
|
||||
BotSpawnTimeOffMax: number;
|
||||
BotSpawnTimeOffMin: number;
|
||||
BotSpawnTimeOnMax: number;
|
||||
BotSpawnTimeOnMin: number;
|
||||
/** How soon bots will be allowed to spawn */
|
||||
BotStart: number;
|
||||
/** After this long bots will no longer spawn */
|
||||
BotStop: number;
|
||||
Description: string;
|
||||
DisabledForScav: boolean;
|
||||
|
@ -33,6 +33,11 @@ export interface IQuest {
|
||||
changeQuestMessageText: string;
|
||||
/** "Pmc" or "Scav" */
|
||||
side: string;
|
||||
acceptanceAndFinishingSource: string;
|
||||
progressSource: string;
|
||||
rankingModes: string[];
|
||||
gameModes: string[];
|
||||
arenaLocations: string[];
|
||||
/** Status of quest to player */
|
||||
sptStatus?: QuestStatus;
|
||||
}
|
||||
@ -148,8 +153,10 @@ export interface IQuestReward {
|
||||
loyaltyLevel?: number;
|
||||
/** Hideout area id */
|
||||
traderId?: string;
|
||||
isEncoded?: boolean;
|
||||
unknown?: boolean;
|
||||
findInRaid?: boolean;
|
||||
gameMode?: string[];
|
||||
/** Game editions whitelisted to get reward */
|
||||
availableInGameEditions?: string[];
|
||||
/** Game editions blacklisted from getting reward */
|
||||
|
@ -3,6 +3,12 @@ export interface IRepeatableQuest extends IQuest {
|
||||
changeCost: IChangeCost[];
|
||||
changeStandingCost: number;
|
||||
sptRepatableGroupName: string;
|
||||
acceptanceAndFinishingSource: string;
|
||||
progressSource: string;
|
||||
rankingModes: string[];
|
||||
gameModes: string[];
|
||||
arenaLocations: string[];
|
||||
questStatus: IRepeatableQuestStatus;
|
||||
}
|
||||
export interface IRepeatableQuestDatabase {
|
||||
templates: IRepeatableTemplates;
|
||||
@ -10,6 +16,14 @@ export interface IRepeatableQuestDatabase {
|
||||
data: IOptions;
|
||||
samples: ISampleQuests[];
|
||||
}
|
||||
export interface IRepeatableQuestStatus {
|
||||
id: string;
|
||||
uid: string;
|
||||
qid: string;
|
||||
startTime: number;
|
||||
status: number;
|
||||
statusTimers: any;
|
||||
}
|
||||
export interface IRepeatableTemplates {
|
||||
Elimination: IQuest;
|
||||
Completion: IQuest;
|
||||
|
@ -8,4 +8,5 @@ export interface Info {
|
||||
Side: string;
|
||||
Level: number;
|
||||
MemberCategory: number;
|
||||
SelectedMemberCategory: number;
|
||||
}
|
||||
|
@ -19,6 +19,8 @@ export interface ISptProfile {
|
||||
traderPurchases?: Record<string, Record<string, ITraderPurchaseData>>;
|
||||
/** Achievements earned by player */
|
||||
achievements: Record<string, number>;
|
||||
/** List of friend profile IDs */
|
||||
friends: string[];
|
||||
}
|
||||
export declare class ITraderPurchaseData {
|
||||
count: number;
|
||||
|
5
TypeScript/11BundleLoadingSample/types/models/eft/ws/IWsFriendsListAccept.d.ts
vendored
Normal file
5
TypeScript/11BundleLoadingSample/types/models/eft/ws/IWsFriendsListAccept.d.ts
vendored
Normal file
@ -0,0 +1,5 @@
|
||||
import { IWsNotificationEvent } from "@spt/models/eft/ws/IWsNotificationEvent";
|
||||
import { ISearchFriendResponse } from "../profile/ISearchFriendResponse";
|
||||
export interface IWsFriendsListAccept extends IWsNotificationEvent {
|
||||
profile: ISearchFriendResponse;
|
||||
}
|
@ -1,4 +1,4 @@
|
||||
export interface IWsNotificationEvent {
|
||||
type: string;
|
||||
eventId: string;
|
||||
eventId?: string;
|
||||
}
|
||||
|
@ -1,5 +1,6 @@
|
||||
export declare enum ConfigTypes {
|
||||
AIRDROP = "spt-airdrop",
|
||||
BACKUP = "spt-backup",
|
||||
BOT = "spt-bot",
|
||||
PMC = "spt-pmc",
|
||||
CORE = "spt-core",
|
||||
|
12
TypeScript/11BundleLoadingSample/types/models/spt/config/IBackupConfig.d.ts
vendored
Normal file
12
TypeScript/11BundleLoadingSample/types/models/spt/config/IBackupConfig.d.ts
vendored
Normal file
@ -0,0 +1,12 @@
|
||||
import { IBaseConfig } from "@spt/models/spt/config/IBaseConfig";
|
||||
export interface IBackupConfig extends IBaseConfig {
|
||||
kind: "spt-backup";
|
||||
enabled: boolean;
|
||||
maxBackups: number;
|
||||
directory: string;
|
||||
backupInterval: IBackupConfigInterval;
|
||||
}
|
||||
export interface IBackupConfigInterval {
|
||||
enabled: boolean;
|
||||
intervalMinutes: number;
|
||||
}
|
@ -7,6 +7,8 @@ export interface IItemConfig extends IBaseConfig {
|
||||
lootableItemBlacklist: string[];
|
||||
/** items that should not be given as rewards */
|
||||
rewardItemBlacklist: string[];
|
||||
/** Item base types that should not be given as rewards */
|
||||
rewardItemTypeBlacklist: string[];
|
||||
/** Items that can only be found on bosses */
|
||||
bossItems: string[];
|
||||
handbookPriceOverride: Record<string, IHandbookPriceOverride>;
|
||||
|
98
TypeScript/11BundleLoadingSample/types/services/BackupService.d.ts
vendored
Normal file
98
TypeScript/11BundleLoadingSample/types/services/BackupService.d.ts
vendored
Normal file
@ -0,0 +1,98 @@
|
||||
import { PreSptModLoader } from "@spt/loaders/PreSptModLoader";
|
||||
import { IBackupConfig } from "@spt/models/spt/config/IBackupConfig";
|
||||
import { ILogger } from "@spt/models/spt/utils/ILogger";
|
||||
import { ConfigServer } from "@spt/servers/ConfigServer";
|
||||
export declare class BackupService {
|
||||
protected logger: ILogger;
|
||||
protected preSptModLoader: PreSptModLoader;
|
||||
protected configServer: ConfigServer;
|
||||
protected backupConfig: IBackupConfig;
|
||||
protected readonly activeServerMods: string[];
|
||||
protected readonly profileDir = "./user/profiles";
|
||||
constructor(logger: ILogger, preSptModLoader: PreSptModLoader, configServer: ConfigServer);
|
||||
/**
|
||||
* Initializes the backup process.
|
||||
*
|
||||
* This method orchestrates the profile backup service. Handles copying profiles to a backup directory and cleaning
|
||||
* up old backups if the number exceeds the configured maximum.
|
||||
*
|
||||
* @returns A promise that resolves when the backup process is complete.
|
||||
*/
|
||||
init(): Promise<void>;
|
||||
/**
|
||||
* Fetches the names of all JSON files in the profile directory.
|
||||
*
|
||||
* This method normalizes the profile directory path and reads all files within it. It then filters the files to
|
||||
* include only those with a `.json` extension and returns their names.
|
||||
*
|
||||
* @returns A promise that resolves to an array of JSON file names.
|
||||
*/
|
||||
protected fetchProfileFiles(): Promise<string[]>;
|
||||
/**
|
||||
* Check to see if the backup service is enabled via the config.
|
||||
*
|
||||
* @returns True if enabled, false otherwise.
|
||||
*/
|
||||
protected isEnabled(): boolean;
|
||||
/**
|
||||
* Generates the target directory path for the backup. The directory path is constructed using the `directory` from
|
||||
* the configuration and the current backup date.
|
||||
*
|
||||
* @returns The target directory path for the backup.
|
||||
*/
|
||||
protected generateBackupTargetDir(): string;
|
||||
/**
|
||||
* Generates a formatted backup date string in the format `YYYY-MM-DD_hh-mm-ss`.
|
||||
*
|
||||
* @returns The formatted backup date string.
|
||||
*/
|
||||
protected generateBackupDate(): string;
|
||||
/**
|
||||
* Cleans up old backups in the backup directory.
|
||||
*
|
||||
* This method reads the backup directory, and sorts backups by modification time. If the number of backups exceeds
|
||||
* the configured maximum, it deletes the oldest backups.
|
||||
*
|
||||
* @returns A promise that resolves when the cleanup is complete.
|
||||
*/
|
||||
protected cleanBackups(): Promise<void>;
|
||||
/**
|
||||
* Retrieves and sorts the backup file paths from the specified directory.
|
||||
*
|
||||
* @param dir - The directory to search for backup files.
|
||||
* @returns A promise that resolves to an array of sorted backup file paths.
|
||||
*/
|
||||
private getBackupPaths;
|
||||
/**
|
||||
* Compares two backup folder names based on their extracted dates.
|
||||
*
|
||||
* @param a - The name of the first backup folder.
|
||||
* @param b - The name of the second backup folder.
|
||||
* @returns The difference in time between the two dates in milliseconds, or `null` if either date is invalid.
|
||||
*/
|
||||
private compareBackupDates;
|
||||
/**
|
||||
* Extracts a date from a folder name string formatted as `YYYY-MM-DD_hh-mm-ss`.
|
||||
*
|
||||
* @param folderName - The name of the folder from which to extract the date.
|
||||
* @returns A Date object if the folder name is in the correct format, otherwise null.
|
||||
*/
|
||||
private extractDateFromFolderName;
|
||||
/**
|
||||
* Removes excess backups from the backup directory.
|
||||
*
|
||||
* @param backups - An array of backup file names to be removed.
|
||||
* @returns A promise that resolves when all specified backups have been removed.
|
||||
*/
|
||||
private removeExcessBackups;
|
||||
/**
|
||||
* Start the backup interval if enabled in the configuration.
|
||||
*/
|
||||
protected startBackupInterval(): void;
|
||||
/**
|
||||
* Get an array of active server mod details.
|
||||
*
|
||||
* @returns An array of mod names.
|
||||
*/
|
||||
protected getActiveServerMods(): string[];
|
||||
}
|
@ -54,6 +54,16 @@ export declare class CircleOfCultistService {
|
||||
* @returns IItemEventRouterResponse
|
||||
*/
|
||||
startSacrifice(sessionId: string, pmcData: IPmcData, request: IHideoutCircleOfCultistProductionStartRequestData): IItemEventRouterResponse;
|
||||
/**
|
||||
* Attempt to add all rewards to cultist circle, if they dont fit remove one and try again until they fit
|
||||
* @param sessionId Session id
|
||||
* @param pmcData Player profile
|
||||
* @param rewards Rewards to send to player
|
||||
* @param containerGrid Cultist grid to add rewards to
|
||||
* @param cultistCircleStashId Stash id
|
||||
* @param output Client output
|
||||
*/
|
||||
protected addRewardsToCircleContainer(sessionId: string, pmcData: IPmcData, rewards: IItem[][], containerGrid: number[][], cultistCircleStashId: string, output: IItemEventRouterResponse): void;
|
||||
/**
|
||||
* Create a map of the possible direct rewards, keyed by the items needed to be sacrificed
|
||||
* @param directRewards Direct rewards array from hideout config
|
||||
@ -156,7 +166,7 @@ export declare class CircleOfCultistService {
|
||||
* @param itemRewardBlacklist Items not to add to pool
|
||||
* @param rewardPool Pool to add items to
|
||||
*/
|
||||
protected addTaskItemRequirementsToRewardPool(pmcData: IPmcData, itemRewardBlacklist: string[], rewardPool: Set<string>): void;
|
||||
protected addTaskItemRequirementsToRewardPool(pmcData: IPmcData, itemRewardBlacklist: Set<string>, rewardPool: Set<string>): void;
|
||||
/**
|
||||
* Adds items the player needs to complete hideout crafts/upgrades to the reward pool
|
||||
* @param hideoutDbData Hideout area data
|
||||
@ -164,7 +174,7 @@ export declare class CircleOfCultistService {
|
||||
* @param itemRewardBlacklist Items not to add to pool
|
||||
* @param rewardPool Pool to add items to
|
||||
*/
|
||||
protected addHideoutUpgradeRequirementsToRewardPool(hideoutDbData: IHideout, pmcData: IPmcData, itemRewardBlacklist: string[], rewardPool: Set<string>): void;
|
||||
protected addHideoutUpgradeRequirementsToRewardPool(hideoutDbData: IHideout, pmcData: IPmcData, itemRewardBlacklist: Set<string>, rewardPool: Set<string>): void;
|
||||
/**
|
||||
* Get all active hideout areas
|
||||
* @param areas Hideout areas to iterate over
|
||||
@ -174,11 +184,11 @@ export declare class CircleOfCultistService {
|
||||
/**
|
||||
* Get array of random reward items
|
||||
* @param rewardPool Reward pool to add to
|
||||
* @param itemRewardBlacklist Reward Blacklist
|
||||
* @param itemRewardBlacklist Item tpls to ignore
|
||||
* @param itemsShouldBeHighValue Should these items meet the valuable threshold
|
||||
* @returns rewardPool
|
||||
* @returns Set of item tpls
|
||||
*/
|
||||
protected generateRandomisedItemsAndAddToRewardPool(rewardPool: Set<string>, itemRewardBlacklist: string[], itemsShouldBeHighValue: boolean): Set<string>;
|
||||
protected generateRandomisedItemsAndAddToRewardPool(rewardPool: Set<string>, itemRewardBlacklist: Set<string>, itemsShouldBeHighValue: boolean): Set<string>;
|
||||
/**
|
||||
* Iterate over passed in hideout requirements and return the Item
|
||||
* @param requirements Requirements to iterate over
|
||||
|
@ -36,6 +36,11 @@ export declare class ItemFilterService {
|
||||
* @returns string array of item tpls
|
||||
*/
|
||||
getItemRewardBlacklist(): string[];
|
||||
/**
|
||||
* Get an array of item types that should never be given as a reward to player
|
||||
* @returns string array of item base ids
|
||||
*/
|
||||
getItemRewardBaseTypeBlacklist(): string[];
|
||||
/**
|
||||
* Return every template id blacklisted in config/item.json
|
||||
* @returns string array of blacklisted tempalte ids
|
||||
|
@ -4,10 +4,10 @@ import { ICoreConfig } from "@spt/models/spt/config/ICoreConfig";
|
||||
import { ILogger } from "@spt/models/spt/utils/ILogger";
|
||||
import { ConfigServer } from "@spt/servers/ConfigServer";
|
||||
import { HttpServer } from "@spt/servers/HttpServer";
|
||||
import { DatabaseService } from "@spt/services/DatabaseService";
|
||||
import { LocalisationService } from "@spt/services/LocalisationService";
|
||||
import { EncodingUtil } from "@spt/utils/EncodingUtil";
|
||||
import { TimeUtil } from "@spt/utils/TimeUtil";
|
||||
import { DatabaseService } from "@spt/services/DatabaseService";
|
||||
export declare class App {
|
||||
protected logger: ILogger;
|
||||
protected timeUtil: TimeUtil;
|
||||
|
@ -106,6 +106,11 @@ export declare class RandomUtil {
|
||||
protected cloner: ICloner;
|
||||
protected logger: ILogger;
|
||||
constructor(cloner: ICloner, logger: ILogger);
|
||||
/**
|
||||
* The IEEE-754 standard for double-precision floating-point numbers limits the number of digits (including both
|
||||
* integer + fractional parts) to about 15–17 significant digits. 15 is a safe upper bound, so we'll use that.
|
||||
*/
|
||||
private static readonly MAX_SIGNIFICANT_DIGITS;
|
||||
/**
|
||||
* Generates a secure random number between 0 (inclusive) and 1 (exclusive).
|
||||
*
|
||||
@ -116,6 +121,16 @@ export declare class RandomUtil {
|
||||
* @returns A secure random number between 0 (inclusive) and 1 (exclusive).
|
||||
*/
|
||||
private getSecureRandomNumber;
|
||||
/**
|
||||
* Determines the number of decimal places in a number.
|
||||
*
|
||||
* @param num - The number to analyze.
|
||||
* @returns The number of decimal places, or 0 if none exist.
|
||||
* @remarks There is a mathematical way to determine this, but it's not as simple as it seams due to floating point
|
||||
* precision issues. This method is a simple workaround that converts the number to a string and splits it.
|
||||
* It's not the most efficient but it *is* the most reliable and easy to understand. Come at me.
|
||||
*/
|
||||
private getNumberPrecision;
|
||||
/**
|
||||
* Generates a random integer between the specified minimum and maximum values, inclusive.
|
||||
*
|
||||
@ -173,7 +188,7 @@ export declare class RandomUtil {
|
||||
/**
|
||||
* Returns a random string from the provided array of strings.
|
||||
*
|
||||
* This method is separate from getArrayValue so we can use a generic inferance with getArrayValue.
|
||||
* This method is separate from getArrayValue so we can use a generic inference with getArrayValue.
|
||||
*
|
||||
* @param arr - The array of strings to select a random value from.
|
||||
* @returns A randomly selected string from the array.
|
||||
@ -225,12 +240,27 @@ export declare class RandomUtil {
|
||||
getNormallyDistributedRandomNumber(mean: number, sigma: number, attempt?: number): number;
|
||||
/**
|
||||
* Generates a random integer between the specified range.
|
||||
* Low and high parameters are floored to integers.
|
||||
*
|
||||
* TODO: v3.11 - This method should not accept non-integer numbers.
|
||||
*
|
||||
* @param low - The lower bound of the range (inclusive).
|
||||
* @param high - The upper bound of the range (exclusive). If not provided, the range will be from 0 to `low`.
|
||||
* @returns A random integer within the specified range.
|
||||
*/
|
||||
randInt(low: number, high?: number): number;
|
||||
/**
|
||||
* Generates a random number between two given values with optional precision.
|
||||
*
|
||||
* @param value1 - The first value to determine the range.
|
||||
* @param value2 - The second value to determine the range. If not provided, 0 is used.
|
||||
* @param precision - The number of decimal places to round the result to. Must be a positive integer between 0
|
||||
* and MAX_PRECISION, inclusive. If not provided, precision is determined by the input values.
|
||||
* @returns A random floating-point number between `value1` and `value2` (inclusive) with the specified precision.
|
||||
* @throws Will throw an error if `precision` is not a positive integer, if `value1` or `value2` are not finite
|
||||
* numbers, or if the precision exceeds the maximum allowed for the given values.
|
||||
*/
|
||||
randNum(value1: number, value2?: number, precision?: number | null): number;
|
||||
/**
|
||||
* Draws a specified number of random elements from a given list.
|
||||
*
|
||||
|
@ -3,11 +3,13 @@ import { OnUpdate } from "@spt/di/OnUpdate";
|
||||
import { ICoreConfig } from "@spt/models/spt/config/ICoreConfig";
|
||||
import { ConfigServer } from "@spt/servers/ConfigServer";
|
||||
import { SaveServer } from "@spt/servers/SaveServer";
|
||||
import { BackupService } from "@spt/services/BackupService";
|
||||
export declare class SaveCallbacks implements OnLoad, OnUpdate {
|
||||
protected saveServer: SaveServer;
|
||||
protected configServer: ConfigServer;
|
||||
protected backupService: BackupService;
|
||||
protected coreConfig: ICoreConfig;
|
||||
constructor(saveServer: SaveServer, configServer: ConfigServer);
|
||||
constructor(saveServer: SaveServer, configServer: ConfigServer, backupService: BackupService);
|
||||
onLoad(): Promise<void>;
|
||||
getRoute(): string;
|
||||
onUpdate(secondsSinceLastRun: number): Promise<boolean>;
|
||||
|
@ -1,5 +1,8 @@
|
||||
import { IDialogueChatBot } from "@spt/helpers/Dialogue/IDialogueChatBot";
|
||||
import { DialogueHelper } from "@spt/helpers/DialogueHelper";
|
||||
import { NotificationSendHelper } from "@spt/helpers/NotificationSendHelper";
|
||||
import { ProfileHelper } from "@spt/helpers/ProfileHelper";
|
||||
import { IDeleteFriendRequest } from "@spt/models/eft/dialog/IDeleteFriendRequest";
|
||||
import { IFriendRequestData } from "@spt/models/eft/dialog/IFriendRequestData";
|
||||
import { IFriendRequestSendResponse } from "@spt/models/eft/dialog/IFriendRequestSendResponse";
|
||||
import { IGetAllAttachmentsResponse } from "@spt/models/eft/dialog/IGetAllAttachmentsResponse";
|
||||
@ -20,11 +23,13 @@ export declare class DialogueController {
|
||||
protected saveServer: SaveServer;
|
||||
protected timeUtil: TimeUtil;
|
||||
protected dialogueHelper: DialogueHelper;
|
||||
protected notificationSendHelper: NotificationSendHelper;
|
||||
protected profileHelper: ProfileHelper;
|
||||
protected mailSendService: MailSendService;
|
||||
protected localisationService: LocalisationService;
|
||||
protected configServer: ConfigServer;
|
||||
protected dialogueChatBots: IDialogueChatBot[];
|
||||
constructor(logger: ILogger, saveServer: SaveServer, timeUtil: TimeUtil, dialogueHelper: DialogueHelper, mailSendService: MailSendService, localisationService: LocalisationService, configServer: ConfigServer, dialogueChatBots: IDialogueChatBot[]);
|
||||
constructor(logger: ILogger, saveServer: SaveServer, timeUtil: TimeUtil, dialogueHelper: DialogueHelper, notificationSendHelper: NotificationSendHelper, profileHelper: ProfileHelper, mailSendService: MailSendService, localisationService: LocalisationService, configServer: ConfigServer, dialogueChatBots: IDialogueChatBot[]);
|
||||
registerChatBot(chatBot: IDialogueChatBot): void;
|
||||
/** Handle onUpdate spt event */
|
||||
update(): void;
|
||||
@ -151,4 +156,6 @@ export declare class DialogueController {
|
||||
protected messageHasExpired(message: IMessage): boolean;
|
||||
/** Handle client/friend/request/send */
|
||||
sendFriendRequest(sessionID: string, request: IFriendRequestData): IFriendRequestSendResponse;
|
||||
/** Handle client/friend/delete */
|
||||
deleteFriend(sessionID: string, request: IDeleteFriendRequest): void;
|
||||
}
|
||||
|
@ -72,6 +72,7 @@ export declare class QuestController {
|
||||
*/
|
||||
protected addTaskConditionCountersToProfile(questConditions: IQuestCondition[], pmcData: IPmcData, questId: string): void;
|
||||
/**
|
||||
* TODO - Move this code into RepeatableQuestController
|
||||
* Handle the client accepting a repeatable quest and starting it
|
||||
* Send starting rewards if any to player and
|
||||
* Send start notification if any to player
|
||||
@ -81,7 +82,6 @@ export declare class QuestController {
|
||||
* @returns IItemEventRouterResponse
|
||||
*/
|
||||
acceptRepeatableQuest(pmcData: IPmcData, acceptedQuest: IAcceptQuestRequestData, sessionID: string): IItemEventRouterResponse;
|
||||
protected createAcceptedQuestClientResponse(sessionID: string, pmcData: IPmcData, repeatableQuestProfile: IRepeatableQuest): IItemEventRouterResponse;
|
||||
/**
|
||||
* Look for an accepted quest inside player profile, return matching
|
||||
* @param pmcData Profile to search through
|
||||
|
@ -147,6 +147,18 @@ export declare class RepeatableQuestController {
|
||||
* @returns IItemEventRouterResponse
|
||||
*/
|
||||
changeRepeatableQuest(pmcData: IPmcData, changeRequest: IRepeatableQuestChangeRequest, sessionID: string): IItemEventRouterResponse;
|
||||
/**
|
||||
* Remove the provided quest from pmc and scav character profiles
|
||||
* @param fullProfile Profile to remove quest from
|
||||
* @param questToReplaceId Quest id to remove from profile
|
||||
*/
|
||||
protected removeQuestFromProfile(fullProfile: ISptProfile, questToReplaceId: string): void;
|
||||
/**
|
||||
* Clean up the repeatables `changeRequirement` dictionary of expired data
|
||||
* @param repeatablesOfTypeInProfile The repeatables that have the replaced and new quest
|
||||
* @param replacedQuestId Id of the replaced quest
|
||||
*/
|
||||
protected cleanUpRepeatableChangeRequirements(repeatablesOfTypeInProfile: IPmcDataRepeatableQuest, replacedQuestId: string): void;
|
||||
/**
|
||||
* Find a repeatable (daily/weekly/scav) from a players profile by its id
|
||||
* @param questId Id of quest to find
|
||||
@ -154,7 +166,7 @@ export declare class RepeatableQuestController {
|
||||
* @returns IGetRepeatableByIdResult
|
||||
*/
|
||||
protected getRepeatableById(questId: string, pmcData: IPmcData): IGetRepeatableByIdResult;
|
||||
protected attemptToGenerateRepeatableQuest(pmcData: IPmcData, questTypePool: IQuestTypePool, repeatableConfig: IRepeatableQuestConfig): IRepeatableQuest;
|
||||
protected attemptToGenerateRepeatableQuest(sessionId: string, pmcData: IPmcData, questTypePool: IQuestTypePool, repeatableConfig: IRepeatableQuestConfig): IRepeatableQuest;
|
||||
/**
|
||||
* Some accounts have access to free repeatable quest refreshes
|
||||
* Track the usage of them inside players profile
|
||||
|
@ -33,13 +33,14 @@ export declare class RepeatableQuestGenerator {
|
||||
/**
|
||||
* This method is called by /GetClientRepeatableQuests/ and creates one element of quest type format (see assets/database/templates/repeatableQuests.json).
|
||||
* It randomly draws a quest type (currently Elimination, Completion or Exploration) as well as a trader who is providing the quest
|
||||
* @param sessionId Session id
|
||||
* @param pmcLevel Player's level for requested items and reward generation
|
||||
* @param pmcTraderInfo Players traper standing/rep levels
|
||||
* @param questTypePool Possible quest types pool
|
||||
* @param repeatableConfig Repeatable quest config
|
||||
* @returns IRepeatableQuest
|
||||
*/
|
||||
generateRepeatableQuest(pmcLevel: number, pmcTraderInfo: Record<string, ITraderInfo>, questTypePool: IQuestTypePool, repeatableConfig: IRepeatableQuestConfig): IRepeatableQuest;
|
||||
generateRepeatableQuest(sessionId: string, pmcLevel: number, pmcTraderInfo: Record<string, ITraderInfo>, questTypePool: IQuestTypePool, repeatableConfig: IRepeatableQuestConfig): IRepeatableQuest;
|
||||
/**
|
||||
* Generate a randomised Elimination quest
|
||||
* @param pmcLevel Player's level for requested items and reward generation
|
||||
@ -48,7 +49,7 @@ export declare class RepeatableQuestGenerator {
|
||||
* @param repeatableConfig The configuration for the repeatably kind (daily, weekly) as configured in QuestConfig for the requestd quest
|
||||
* @returns Object of quest type format for "Elimination" (see assets/database/templates/repeatableQuests.json)
|
||||
*/
|
||||
protected generateEliminationQuest(pmcLevel: number, traderId: string, questTypePool: IQuestTypePool, repeatableConfig: IRepeatableQuestConfig): IRepeatableQuest;
|
||||
protected generateEliminationQuest(sessionid: string, pmcLevel: number, traderId: string, questTypePool: IQuestTypePool, repeatableConfig: IRepeatableQuestConfig): IRepeatableQuest;
|
||||
/**
|
||||
* Get a number of kills neded to complete elimination quest
|
||||
* @param targetKey Target type desired e.g. anyPmc/bossBully/Savage
|
||||
@ -83,7 +84,7 @@ export declare class RepeatableQuestGenerator {
|
||||
* @param {object} repeatableConfig The configuration for the repeatably kind (daily, weekly) as configured in QuestConfig for the requestd quest
|
||||
* @returns {object} object of quest type format for "Completion" (see assets/database/templates/repeatableQuests.json)
|
||||
*/
|
||||
protected generateCompletionQuest(pmcLevel: number, traderId: string, repeatableConfig: IRepeatableQuestConfig): IRepeatableQuest;
|
||||
protected generateCompletionQuest(sessionId: string, pmcLevel: number, traderId: string, repeatableConfig: IRepeatableQuestConfig): IRepeatableQuest;
|
||||
/**
|
||||
* A repeatable quest, besides some more or less static components, exists of reward and condition (see assets/database/templates/repeatableQuests.json)
|
||||
* This is a helper method for GenerateCompletionQuest to create a completion condition (of which a completion quest theoretically can have many)
|
||||
@ -102,7 +103,7 @@ export declare class RepeatableQuestGenerator {
|
||||
* @param {object} repeatableConfig The configuration for the repeatably kind (daily, weekly) as configured in QuestConfig for the requestd quest
|
||||
* @returns {object} object of quest type format for "Exploration" (see assets/database/templates/repeatableQuests.json)
|
||||
*/
|
||||
protected generateExplorationQuest(pmcLevel: number, traderId: string, questTypePool: IQuestTypePool, repeatableConfig: IRepeatableQuestConfig): IRepeatableQuest;
|
||||
protected generateExplorationQuest(sessionId: string, pmcLevel: number, traderId: string, questTypePool: IQuestTypePool, repeatableConfig: IRepeatableQuestConfig): IRepeatableQuest;
|
||||
/**
|
||||
* Filter a maps exits to just those for the desired side
|
||||
* @param locationKey Map id (e.g. factory4_day)
|
||||
@ -110,7 +111,7 @@ export declare class RepeatableQuestGenerator {
|
||||
* @returns Array of Exit objects
|
||||
*/
|
||||
protected getLocationExitsForSide(locationKey: string, playerSide: string): IExit[];
|
||||
protected generatePickupQuest(pmcLevel: number, traderId: string, questTypePool: IQuestTypePool, repeatableConfig: IRepeatableQuestConfig): IRepeatableQuest;
|
||||
protected generatePickupQuest(sessionId: string, pmcLevel: number, traderId: string, questTypePool: IQuestTypePool, repeatableConfig: IRepeatableQuestConfig): IRepeatableQuest;
|
||||
/**
|
||||
* Convert a location into an quest code can read (e.g. factory4_day into 55f2d3fd4bdc2d5f408b4567)
|
||||
* @param locationKey e.g factory4_day
|
||||
@ -135,5 +136,5 @@ export declare class RepeatableQuestGenerator {
|
||||
* @returns {object} Object which contains the base elements for repeatable quests of the requests type
|
||||
* (needs to be filled with reward and conditions by called to make a valid quest)
|
||||
*/
|
||||
protected generateRepeatableTemplate(type: string, traderId: string, side: string): IRepeatableQuest;
|
||||
protected generateRepeatableTemplate(type: string, traderId: string, side: string, sessionId: string): IRepeatableQuest;
|
||||
}
|
||||
|
@ -12,6 +12,7 @@ import { DatabaseService } from "@spt/services/DatabaseService";
|
||||
import { ItemFilterService } from "@spt/services/ItemFilterService";
|
||||
import { LocalisationService } from "@spt/services/LocalisationService";
|
||||
import { SeasonalEventService } from "@spt/services/SeasonalEventService";
|
||||
import { HashUtil } from "@spt/utils/HashUtil";
|
||||
import { MathUtil } from "@spt/utils/MathUtil";
|
||||
import { ObjectId } from "@spt/utils/ObjectId";
|
||||
import { RandomUtil } from "@spt/utils/RandomUtil";
|
||||
@ -19,6 +20,7 @@ import { ICloner } from "@spt/utils/cloners/ICloner";
|
||||
export declare class RepeatableQuestRewardGenerator {
|
||||
protected logger: ILogger;
|
||||
protected randomUtil: RandomUtil;
|
||||
protected hashUtil: HashUtil;
|
||||
protected mathUtil: MathUtil;
|
||||
protected databaseService: DatabaseService;
|
||||
protected itemHelper: ItemHelper;
|
||||
@ -31,7 +33,7 @@ export declare class RepeatableQuestRewardGenerator {
|
||||
protected configServer: ConfigServer;
|
||||
protected cloner: ICloner;
|
||||
protected questConfig: IQuestConfig;
|
||||
constructor(logger: ILogger, randomUtil: RandomUtil, mathUtil: MathUtil, databaseService: DatabaseService, itemHelper: ItemHelper, presetHelper: PresetHelper, handbookHelper: HandbookHelper, localisationService: LocalisationService, objectId: ObjectId, itemFilterService: ItemFilterService, seasonalEventService: SeasonalEventService, configServer: ConfigServer, cloner: ICloner);
|
||||
constructor(logger: ILogger, randomUtil: RandomUtil, hashUtil: HashUtil, mathUtil: MathUtil, databaseService: DatabaseService, itemHelper: ItemHelper, presetHelper: PresetHelper, handbookHelper: HandbookHelper, localisationService: LocalisationService, objectId: ObjectId, itemFilterService: ItemFilterService, seasonalEventService: SeasonalEventService, configServer: ConfigServer, cloner: ICloner);
|
||||
/**
|
||||
* Generate the reward for a mission. A reward can consist of:
|
||||
* - Experience
|
||||
@ -127,7 +129,7 @@ export declare class RepeatableQuestRewardGenerator {
|
||||
* @param preset Optional array of preset items
|
||||
* @returns {object} Object of "Reward"-item-type
|
||||
*/
|
||||
protected generateItemReward(tpl: string, count: number, index: number): IQuestReward;
|
||||
protected generateItemReward(tpl: string, count: number, index: number, foundInRaid?: boolean): IQuestReward;
|
||||
/**
|
||||
* Helper to create a reward item structured as required by the client
|
||||
*
|
||||
@ -137,7 +139,7 @@ export declare class RepeatableQuestRewardGenerator {
|
||||
* @param preset Optional array of preset items
|
||||
* @returns {object} Object of "Reward"-item-type
|
||||
*/
|
||||
protected generatePresetReward(tpl: string, count: number, index: number, preset?: IItem[]): IQuestReward;
|
||||
protected generatePresetReward(tpl: string, count: number, index: number, preset?: IItem[], foundInRaid?: boolean): IQuestReward;
|
||||
/**
|
||||
* Picks rewardable items from items.json
|
||||
* This means they must:
|
||||
|
@ -2,6 +2,7 @@ import { ItemHelper } from "@spt/helpers/ItemHelper";
|
||||
import { IPmcData } from "@spt/models/eft/common/IPmcData";
|
||||
import { Common, ICounterKeyValue, IStats } from "@spt/models/eft/common/tables/IBotBase";
|
||||
import { IItem } from "@spt/models/eft/common/tables/IItem";
|
||||
import { ISearchFriendResponse } from "@spt/models/eft/profile/ISearchFriendResponse";
|
||||
import { ISptProfile } from "@spt/models/eft/profile/ISptProfile";
|
||||
import { IValidateNicknameRequestData } from "@spt/models/eft/profile/IValidateNicknameRequestData";
|
||||
import { BonusType } from "@spt/models/enums/BonusType";
|
||||
@ -90,6 +91,24 @@ export declare class ProfileHelper {
|
||||
* @returns ISptProfile object
|
||||
*/
|
||||
getFullProfile(sessionID: string): ISptProfile | undefined;
|
||||
/**
|
||||
* Get full representation of a players profile JSON by the account ID, or undefined if not found
|
||||
* @param accountId Account ID to find
|
||||
* @returns
|
||||
*/
|
||||
getFullProfileByAccountId(accountID: string): ISptProfile | undefined;
|
||||
/**
|
||||
* Retrieve a ChatRoomMember formatted profile for the given session ID
|
||||
* @param sessionID The session ID to return the profile for
|
||||
* @returns
|
||||
*/
|
||||
getChatRoomMemberFromSessionId(sessionID: string): ISearchFriendResponse | undefined;
|
||||
/**
|
||||
* Retrieve a ChatRoomMember formatted profile for the given PMC profile data
|
||||
* @param pmcProfile The PMC profile data to format into a ChatRoomMember structure
|
||||
* @returns
|
||||
*/
|
||||
getChatRoomMemberFromPmcProfile(pmcProfile: IPmcData): ISearchFriendResponse;
|
||||
/**
|
||||
* Get a PMC profile by its session id
|
||||
* @param sessionID Profile id to return
|
||||
|
@ -11,23 +11,36 @@ export interface ILocationBase {
|
||||
Banners: IBanner[];
|
||||
BossLocationSpawn: IBossLocationSpawn[];
|
||||
BotAssault: number;
|
||||
/** Weighting on how likely a bot will be Easy difficulty */
|
||||
BotEasy: number;
|
||||
/** Weighting on how likely a bot will be Hard difficulty */
|
||||
BotHard: number;
|
||||
/** Weighting on how likely a bot will be Impossible difficulty */
|
||||
BotImpossible: number;
|
||||
BotLocationModifier: IBotLocationModifier;
|
||||
BotMarksman: number;
|
||||
/** Maximum Number of bots that are currently alive/loading/delayed */
|
||||
BotMax: number;
|
||||
/** Is not used in 33420 */
|
||||
BotMaxPlayer: number;
|
||||
/** Is not used in 33420 */
|
||||
BotMaxTimePlayer: number;
|
||||
/** Does not even exist in the client in 33420 */
|
||||
BotMaxPvE: number;
|
||||
/** Weighting on how likely a bot will be Normal difficulty */
|
||||
BotNormal: number;
|
||||
/** How many bot slots that need to be open before trying to spawn new bots. */
|
||||
BotSpawnCountStep: number;
|
||||
/** How often to check if bots are spawn-able. In seconds */
|
||||
BotSpawnPeriodCheck: number;
|
||||
/** The bot spawn will toggle on and off in intervals of Off(Min/Max) and On(Min/Max) */
|
||||
BotSpawnTimeOffMax: number;
|
||||
BotSpawnTimeOffMin: number;
|
||||
BotSpawnTimeOnMax: number;
|
||||
BotSpawnTimeOnMin: number;
|
||||
/** How soon bots will be allowed to spawn */
|
||||
BotStart: number;
|
||||
/** After this long bots will no longer spawn */
|
||||
BotStop: number;
|
||||
Description: string;
|
||||
DisabledForScav: boolean;
|
||||
|
@ -33,6 +33,11 @@ export interface IQuest {
|
||||
changeQuestMessageText: string;
|
||||
/** "Pmc" or "Scav" */
|
||||
side: string;
|
||||
acceptanceAndFinishingSource: string;
|
||||
progressSource: string;
|
||||
rankingModes: string[];
|
||||
gameModes: string[];
|
||||
arenaLocations: string[];
|
||||
/** Status of quest to player */
|
||||
sptStatus?: QuestStatus;
|
||||
}
|
||||
@ -148,8 +153,10 @@ export interface IQuestReward {
|
||||
loyaltyLevel?: number;
|
||||
/** Hideout area id */
|
||||
traderId?: string;
|
||||
isEncoded?: boolean;
|
||||
unknown?: boolean;
|
||||
findInRaid?: boolean;
|
||||
gameMode?: string[];
|
||||
/** Game editions whitelisted to get reward */
|
||||
availableInGameEditions?: string[];
|
||||
/** Game editions blacklisted from getting reward */
|
||||
|
@ -3,6 +3,12 @@ export interface IRepeatableQuest extends IQuest {
|
||||
changeCost: IChangeCost[];
|
||||
changeStandingCost: number;
|
||||
sptRepatableGroupName: string;
|
||||
acceptanceAndFinishingSource: string;
|
||||
progressSource: string;
|
||||
rankingModes: string[];
|
||||
gameModes: string[];
|
||||
arenaLocations: string[];
|
||||
questStatus: IRepeatableQuestStatus;
|
||||
}
|
||||
export interface IRepeatableQuestDatabase {
|
||||
templates: IRepeatableTemplates;
|
||||
@ -10,6 +16,14 @@ export interface IRepeatableQuestDatabase {
|
||||
data: IOptions;
|
||||
samples: ISampleQuests[];
|
||||
}
|
||||
export interface IRepeatableQuestStatus {
|
||||
id: string;
|
||||
uid: string;
|
||||
qid: string;
|
||||
startTime: number;
|
||||
status: number;
|
||||
statusTimers: any;
|
||||
}
|
||||
export interface IRepeatableTemplates {
|
||||
Elimination: IQuest;
|
||||
Completion: IQuest;
|
||||
|
@ -8,4 +8,5 @@ export interface Info {
|
||||
Side: string;
|
||||
Level: number;
|
||||
MemberCategory: number;
|
||||
SelectedMemberCategory: number;
|
||||
}
|
||||
|
@ -19,6 +19,8 @@ export interface ISptProfile {
|
||||
traderPurchases?: Record<string, Record<string, ITraderPurchaseData>>;
|
||||
/** Achievements earned by player */
|
||||
achievements: Record<string, number>;
|
||||
/** List of friend profile IDs */
|
||||
friends: string[];
|
||||
}
|
||||
export declare class ITraderPurchaseData {
|
||||
count: number;
|
||||
|
5
TypeScript/12ClassExtensionOverride/types/models/eft/ws/IWsFriendsListAccept.d.ts
vendored
Normal file
5
TypeScript/12ClassExtensionOverride/types/models/eft/ws/IWsFriendsListAccept.d.ts
vendored
Normal file
@ -0,0 +1,5 @@
|
||||
import { IWsNotificationEvent } from "@spt/models/eft/ws/IWsNotificationEvent";
|
||||
import { ISearchFriendResponse } from "../profile/ISearchFriendResponse";
|
||||
export interface IWsFriendsListAccept extends IWsNotificationEvent {
|
||||
profile: ISearchFriendResponse;
|
||||
}
|
@ -1,4 +1,4 @@
|
||||
export interface IWsNotificationEvent {
|
||||
type: string;
|
||||
eventId: string;
|
||||
eventId?: string;
|
||||
}
|
||||
|
@ -1,5 +1,6 @@
|
||||
export declare enum ConfigTypes {
|
||||
AIRDROP = "spt-airdrop",
|
||||
BACKUP = "spt-backup",
|
||||
BOT = "spt-bot",
|
||||
PMC = "spt-pmc",
|
||||
CORE = "spt-core",
|
||||
|
12
TypeScript/12ClassExtensionOverride/types/models/spt/config/IBackupConfig.d.ts
vendored
Normal file
12
TypeScript/12ClassExtensionOverride/types/models/spt/config/IBackupConfig.d.ts
vendored
Normal file
@ -0,0 +1,12 @@
|
||||
import { IBaseConfig } from "@spt/models/spt/config/IBaseConfig";
|
||||
export interface IBackupConfig extends IBaseConfig {
|
||||
kind: "spt-backup";
|
||||
enabled: boolean;
|
||||
maxBackups: number;
|
||||
directory: string;
|
||||
backupInterval: IBackupConfigInterval;
|
||||
}
|
||||
export interface IBackupConfigInterval {
|
||||
enabled: boolean;
|
||||
intervalMinutes: number;
|
||||
}
|
@ -7,6 +7,8 @@ export interface IItemConfig extends IBaseConfig {
|
||||
lootableItemBlacklist: string[];
|
||||
/** items that should not be given as rewards */
|
||||
rewardItemBlacklist: string[];
|
||||
/** Item base types that should not be given as rewards */
|
||||
rewardItemTypeBlacklist: string[];
|
||||
/** Items that can only be found on bosses */
|
||||
bossItems: string[];
|
||||
handbookPriceOverride: Record<string, IHandbookPriceOverride>;
|
||||
|
98
TypeScript/12ClassExtensionOverride/types/services/BackupService.d.ts
vendored
Normal file
98
TypeScript/12ClassExtensionOverride/types/services/BackupService.d.ts
vendored
Normal file
@ -0,0 +1,98 @@
|
||||
import { PreSptModLoader } from "@spt/loaders/PreSptModLoader";
|
||||
import { IBackupConfig } from "@spt/models/spt/config/IBackupConfig";
|
||||
import { ILogger } from "@spt/models/spt/utils/ILogger";
|
||||
import { ConfigServer } from "@spt/servers/ConfigServer";
|
||||
export declare class BackupService {
|
||||
protected logger: ILogger;
|
||||
protected preSptModLoader: PreSptModLoader;
|
||||
protected configServer: ConfigServer;
|
||||
protected backupConfig: IBackupConfig;
|
||||
protected readonly activeServerMods: string[];
|
||||
protected readonly profileDir = "./user/profiles";
|
||||
constructor(logger: ILogger, preSptModLoader: PreSptModLoader, configServer: ConfigServer);
|
||||
/**
|
||||
* Initializes the backup process.
|
||||
*
|
||||
* This method orchestrates the profile backup service. Handles copying profiles to a backup directory and cleaning
|
||||
* up old backups if the number exceeds the configured maximum.
|
||||
*
|
||||
* @returns A promise that resolves when the backup process is complete.
|
||||
*/
|
||||
init(): Promise<void>;
|
||||
/**
|
||||
* Fetches the names of all JSON files in the profile directory.
|
||||
*
|
||||
* This method normalizes the profile directory path and reads all files within it. It then filters the files to
|
||||
* include only those with a `.json` extension and returns their names.
|
||||
*
|
||||
* @returns A promise that resolves to an array of JSON file names.
|
||||
*/
|
||||
protected fetchProfileFiles(): Promise<string[]>;
|
||||
/**
|
||||
* Check to see if the backup service is enabled via the config.
|
||||
*
|
||||
* @returns True if enabled, false otherwise.
|
||||
*/
|
||||
protected isEnabled(): boolean;
|
||||
/**
|
||||
* Generates the target directory path for the backup. The directory path is constructed using the `directory` from
|
||||
* the configuration and the current backup date.
|
||||
*
|
||||
* @returns The target directory path for the backup.
|
||||
*/
|
||||
protected generateBackupTargetDir(): string;
|
||||
/**
|
||||
* Generates a formatted backup date string in the format `YYYY-MM-DD_hh-mm-ss`.
|
||||
*
|
||||
* @returns The formatted backup date string.
|
||||
*/
|
||||
protected generateBackupDate(): string;
|
||||
/**
|
||||
* Cleans up old backups in the backup directory.
|
||||
*
|
||||
* This method reads the backup directory, and sorts backups by modification time. If the number of backups exceeds
|
||||
* the configured maximum, it deletes the oldest backups.
|
||||
*
|
||||
* @returns A promise that resolves when the cleanup is complete.
|
||||
*/
|
||||
protected cleanBackups(): Promise<void>;
|
||||
/**
|
||||
* Retrieves and sorts the backup file paths from the specified directory.
|
||||
*
|
||||
* @param dir - The directory to search for backup files.
|
||||
* @returns A promise that resolves to an array of sorted backup file paths.
|
||||
*/
|
||||
private getBackupPaths;
|
||||
/**
|
||||
* Compares two backup folder names based on their extracted dates.
|
||||
*
|
||||
* @param a - The name of the first backup folder.
|
||||
* @param b - The name of the second backup folder.
|
||||
* @returns The difference in time between the two dates in milliseconds, or `null` if either date is invalid.
|
||||
*/
|
||||
private compareBackupDates;
|
||||
/**
|
||||
* Extracts a date from a folder name string formatted as `YYYY-MM-DD_hh-mm-ss`.
|
||||
*
|
||||
* @param folderName - The name of the folder from which to extract the date.
|
||||
* @returns A Date object if the folder name is in the correct format, otherwise null.
|
||||
*/
|
||||
private extractDateFromFolderName;
|
||||
/**
|
||||
* Removes excess backups from the backup directory.
|
||||
*
|
||||
* @param backups - An array of backup file names to be removed.
|
||||
* @returns A promise that resolves when all specified backups have been removed.
|
||||
*/
|
||||
private removeExcessBackups;
|
||||
/**
|
||||
* Start the backup interval if enabled in the configuration.
|
||||
*/
|
||||
protected startBackupInterval(): void;
|
||||
/**
|
||||
* Get an array of active server mod details.
|
||||
*
|
||||
* @returns An array of mod names.
|
||||
*/
|
||||
protected getActiveServerMods(): string[];
|
||||
}
|
@ -54,6 +54,16 @@ export declare class CircleOfCultistService {
|
||||
* @returns IItemEventRouterResponse
|
||||
*/
|
||||
startSacrifice(sessionId: string, pmcData: IPmcData, request: IHideoutCircleOfCultistProductionStartRequestData): IItemEventRouterResponse;
|
||||
/**
|
||||
* Attempt to add all rewards to cultist circle, if they dont fit remove one and try again until they fit
|
||||
* @param sessionId Session id
|
||||
* @param pmcData Player profile
|
||||
* @param rewards Rewards to send to player
|
||||
* @param containerGrid Cultist grid to add rewards to
|
||||
* @param cultistCircleStashId Stash id
|
||||
* @param output Client output
|
||||
*/
|
||||
protected addRewardsToCircleContainer(sessionId: string, pmcData: IPmcData, rewards: IItem[][], containerGrid: number[][], cultistCircleStashId: string, output: IItemEventRouterResponse): void;
|
||||
/**
|
||||
* Create a map of the possible direct rewards, keyed by the items needed to be sacrificed
|
||||
* @param directRewards Direct rewards array from hideout config
|
||||
@ -156,7 +166,7 @@ export declare class CircleOfCultistService {
|
||||
* @param itemRewardBlacklist Items not to add to pool
|
||||
* @param rewardPool Pool to add items to
|
||||
*/
|
||||
protected addTaskItemRequirementsToRewardPool(pmcData: IPmcData, itemRewardBlacklist: string[], rewardPool: Set<string>): void;
|
||||
protected addTaskItemRequirementsToRewardPool(pmcData: IPmcData, itemRewardBlacklist: Set<string>, rewardPool: Set<string>): void;
|
||||
/**
|
||||
* Adds items the player needs to complete hideout crafts/upgrades to the reward pool
|
||||
* @param hideoutDbData Hideout area data
|
||||
@ -164,7 +174,7 @@ export declare class CircleOfCultistService {
|
||||
* @param itemRewardBlacklist Items not to add to pool
|
||||
* @param rewardPool Pool to add items to
|
||||
*/
|
||||
protected addHideoutUpgradeRequirementsToRewardPool(hideoutDbData: IHideout, pmcData: IPmcData, itemRewardBlacklist: string[], rewardPool: Set<string>): void;
|
||||
protected addHideoutUpgradeRequirementsToRewardPool(hideoutDbData: IHideout, pmcData: IPmcData, itemRewardBlacklist: Set<string>, rewardPool: Set<string>): void;
|
||||
/**
|
||||
* Get all active hideout areas
|
||||
* @param areas Hideout areas to iterate over
|
||||
@ -174,11 +184,11 @@ export declare class CircleOfCultistService {
|
||||
/**
|
||||
* Get array of random reward items
|
||||
* @param rewardPool Reward pool to add to
|
||||
* @param itemRewardBlacklist Reward Blacklist
|
||||
* @param itemRewardBlacklist Item tpls to ignore
|
||||
* @param itemsShouldBeHighValue Should these items meet the valuable threshold
|
||||
* @returns rewardPool
|
||||
* @returns Set of item tpls
|
||||
*/
|
||||
protected generateRandomisedItemsAndAddToRewardPool(rewardPool: Set<string>, itemRewardBlacklist: string[], itemsShouldBeHighValue: boolean): Set<string>;
|
||||
protected generateRandomisedItemsAndAddToRewardPool(rewardPool: Set<string>, itemRewardBlacklist: Set<string>, itemsShouldBeHighValue: boolean): Set<string>;
|
||||
/**
|
||||
* Iterate over passed in hideout requirements and return the Item
|
||||
* @param requirements Requirements to iterate over
|
||||
|
@ -36,6 +36,11 @@ export declare class ItemFilterService {
|
||||
* @returns string array of item tpls
|
||||
*/
|
||||
getItemRewardBlacklist(): string[];
|
||||
/**
|
||||
* Get an array of item types that should never be given as a reward to player
|
||||
* @returns string array of item base ids
|
||||
*/
|
||||
getItemRewardBaseTypeBlacklist(): string[];
|
||||
/**
|
||||
* Return every template id blacklisted in config/item.json
|
||||
* @returns string array of blacklisted tempalte ids
|
||||
|
@ -4,10 +4,10 @@ import { ICoreConfig } from "@spt/models/spt/config/ICoreConfig";
|
||||
import { ILogger } from "@spt/models/spt/utils/ILogger";
|
||||
import { ConfigServer } from "@spt/servers/ConfigServer";
|
||||
import { HttpServer } from "@spt/servers/HttpServer";
|
||||
import { DatabaseService } from "@spt/services/DatabaseService";
|
||||
import { LocalisationService } from "@spt/services/LocalisationService";
|
||||
import { EncodingUtil } from "@spt/utils/EncodingUtil";
|
||||
import { TimeUtil } from "@spt/utils/TimeUtil";
|
||||
import { DatabaseService } from "@spt/services/DatabaseService";
|
||||
export declare class App {
|
||||
protected logger: ILogger;
|
||||
protected timeUtil: TimeUtil;
|
||||
|
@ -106,6 +106,11 @@ export declare class RandomUtil {
|
||||
protected cloner: ICloner;
|
||||
protected logger: ILogger;
|
||||
constructor(cloner: ICloner, logger: ILogger);
|
||||
/**
|
||||
* The IEEE-754 standard for double-precision floating-point numbers limits the number of digits (including both
|
||||
* integer + fractional parts) to about 15–17 significant digits. 15 is a safe upper bound, so we'll use that.
|
||||
*/
|
||||
private static readonly MAX_SIGNIFICANT_DIGITS;
|
||||
/**
|
||||
* Generates a secure random number between 0 (inclusive) and 1 (exclusive).
|
||||
*
|
||||
@ -116,6 +121,16 @@ export declare class RandomUtil {
|
||||
* @returns A secure random number between 0 (inclusive) and 1 (exclusive).
|
||||
*/
|
||||
private getSecureRandomNumber;
|
||||
/**
|
||||
* Determines the number of decimal places in a number.
|
||||
*
|
||||
* @param num - The number to analyze.
|
||||
* @returns The number of decimal places, or 0 if none exist.
|
||||
* @remarks There is a mathematical way to determine this, but it's not as simple as it seams due to floating point
|
||||
* precision issues. This method is a simple workaround that converts the number to a string and splits it.
|
||||
* It's not the most efficient but it *is* the most reliable and easy to understand. Come at me.
|
||||
*/
|
||||
private getNumberPrecision;
|
||||
/**
|
||||
* Generates a random integer between the specified minimum and maximum values, inclusive.
|
||||
*
|
||||
@ -173,7 +188,7 @@ export declare class RandomUtil {
|
||||
/**
|
||||
* Returns a random string from the provided array of strings.
|
||||
*
|
||||
* This method is separate from getArrayValue so we can use a generic inferance with getArrayValue.
|
||||
* This method is separate from getArrayValue so we can use a generic inference with getArrayValue.
|
||||
*
|
||||
* @param arr - The array of strings to select a random value from.
|
||||
* @returns A randomly selected string from the array.
|
||||
@ -225,12 +240,27 @@ export declare class RandomUtil {
|
||||
getNormallyDistributedRandomNumber(mean: number, sigma: number, attempt?: number): number;
|
||||
/**
|
||||
* Generates a random integer between the specified range.
|
||||
* Low and high parameters are floored to integers.
|
||||
*
|
||||
* TODO: v3.11 - This method should not accept non-integer numbers.
|
||||
*
|
||||
* @param low - The lower bound of the range (inclusive).
|
||||
* @param high - The upper bound of the range (exclusive). If not provided, the range will be from 0 to `low`.
|
||||
* @returns A random integer within the specified range.
|
||||
*/
|
||||
randInt(low: number, high?: number): number;
|
||||
/**
|
||||
* Generates a random number between two given values with optional precision.
|
||||
*
|
||||
* @param value1 - The first value to determine the range.
|
||||
* @param value2 - The second value to determine the range. If not provided, 0 is used.
|
||||
* @param precision - The number of decimal places to round the result to. Must be a positive integer between 0
|
||||
* and MAX_PRECISION, inclusive. If not provided, precision is determined by the input values.
|
||||
* @returns A random floating-point number between `value1` and `value2` (inclusive) with the specified precision.
|
||||
* @throws Will throw an error if `precision` is not a positive integer, if `value1` or `value2` are not finite
|
||||
* numbers, or if the precision exceeds the maximum allowed for the given values.
|
||||
*/
|
||||
randNum(value1: number, value2?: number, precision?: number | null): number;
|
||||
/**
|
||||
* Draws a specified number of random elements from a given list.
|
||||
*
|
||||
|
@ -3,11 +3,13 @@ import { OnUpdate } from "@spt/di/OnUpdate";
|
||||
import { ICoreConfig } from "@spt/models/spt/config/ICoreConfig";
|
||||
import { ConfigServer } from "@spt/servers/ConfigServer";
|
||||
import { SaveServer } from "@spt/servers/SaveServer";
|
||||
import { BackupService } from "@spt/services/BackupService";
|
||||
export declare class SaveCallbacks implements OnLoad, OnUpdate {
|
||||
protected saveServer: SaveServer;
|
||||
protected configServer: ConfigServer;
|
||||
protected backupService: BackupService;
|
||||
protected coreConfig: ICoreConfig;
|
||||
constructor(saveServer: SaveServer, configServer: ConfigServer);
|
||||
constructor(saveServer: SaveServer, configServer: ConfigServer, backupService: BackupService);
|
||||
onLoad(): Promise<void>;
|
||||
getRoute(): string;
|
||||
onUpdate(secondsSinceLastRun: number): Promise<boolean>;
|
||||
|
@ -1,5 +1,8 @@
|
||||
import { IDialogueChatBot } from "@spt/helpers/Dialogue/IDialogueChatBot";
|
||||
import { DialogueHelper } from "@spt/helpers/DialogueHelper";
|
||||
import { NotificationSendHelper } from "@spt/helpers/NotificationSendHelper";
|
||||
import { ProfileHelper } from "@spt/helpers/ProfileHelper";
|
||||
import { IDeleteFriendRequest } from "@spt/models/eft/dialog/IDeleteFriendRequest";
|
||||
import { IFriendRequestData } from "@spt/models/eft/dialog/IFriendRequestData";
|
||||
import { IFriendRequestSendResponse } from "@spt/models/eft/dialog/IFriendRequestSendResponse";
|
||||
import { IGetAllAttachmentsResponse } from "@spt/models/eft/dialog/IGetAllAttachmentsResponse";
|
||||
@ -20,11 +23,13 @@ export declare class DialogueController {
|
||||
protected saveServer: SaveServer;
|
||||
protected timeUtil: TimeUtil;
|
||||
protected dialogueHelper: DialogueHelper;
|
||||
protected notificationSendHelper: NotificationSendHelper;
|
||||
protected profileHelper: ProfileHelper;
|
||||
protected mailSendService: MailSendService;
|
||||
protected localisationService: LocalisationService;
|
||||
protected configServer: ConfigServer;
|
||||
protected dialogueChatBots: IDialogueChatBot[];
|
||||
constructor(logger: ILogger, saveServer: SaveServer, timeUtil: TimeUtil, dialogueHelper: DialogueHelper, mailSendService: MailSendService, localisationService: LocalisationService, configServer: ConfigServer, dialogueChatBots: IDialogueChatBot[]);
|
||||
constructor(logger: ILogger, saveServer: SaveServer, timeUtil: TimeUtil, dialogueHelper: DialogueHelper, notificationSendHelper: NotificationSendHelper, profileHelper: ProfileHelper, mailSendService: MailSendService, localisationService: LocalisationService, configServer: ConfigServer, dialogueChatBots: IDialogueChatBot[]);
|
||||
registerChatBot(chatBot: IDialogueChatBot): void;
|
||||
/** Handle onUpdate spt event */
|
||||
update(): void;
|
||||
@ -151,4 +156,6 @@ export declare class DialogueController {
|
||||
protected messageHasExpired(message: IMessage): boolean;
|
||||
/** Handle client/friend/request/send */
|
||||
sendFriendRequest(sessionID: string, request: IFriendRequestData): IFriendRequestSendResponse;
|
||||
/** Handle client/friend/delete */
|
||||
deleteFriend(sessionID: string, request: IDeleteFriendRequest): void;
|
||||
}
|
||||
|
@ -72,6 +72,7 @@ export declare class QuestController {
|
||||
*/
|
||||
protected addTaskConditionCountersToProfile(questConditions: IQuestCondition[], pmcData: IPmcData, questId: string): void;
|
||||
/**
|
||||
* TODO - Move this code into RepeatableQuestController
|
||||
* Handle the client accepting a repeatable quest and starting it
|
||||
* Send starting rewards if any to player and
|
||||
* Send start notification if any to player
|
||||
@ -81,7 +82,6 @@ export declare class QuestController {
|
||||
* @returns IItemEventRouterResponse
|
||||
*/
|
||||
acceptRepeatableQuest(pmcData: IPmcData, acceptedQuest: IAcceptQuestRequestData, sessionID: string): IItemEventRouterResponse;
|
||||
protected createAcceptedQuestClientResponse(sessionID: string, pmcData: IPmcData, repeatableQuestProfile: IRepeatableQuest): IItemEventRouterResponse;
|
||||
/**
|
||||
* Look for an accepted quest inside player profile, return matching
|
||||
* @param pmcData Profile to search through
|
||||
|
@ -147,6 +147,18 @@ export declare class RepeatableQuestController {
|
||||
* @returns IItemEventRouterResponse
|
||||
*/
|
||||
changeRepeatableQuest(pmcData: IPmcData, changeRequest: IRepeatableQuestChangeRequest, sessionID: string): IItemEventRouterResponse;
|
||||
/**
|
||||
* Remove the provided quest from pmc and scav character profiles
|
||||
* @param fullProfile Profile to remove quest from
|
||||
* @param questToReplaceId Quest id to remove from profile
|
||||
*/
|
||||
protected removeQuestFromProfile(fullProfile: ISptProfile, questToReplaceId: string): void;
|
||||
/**
|
||||
* Clean up the repeatables `changeRequirement` dictionary of expired data
|
||||
* @param repeatablesOfTypeInProfile The repeatables that have the replaced and new quest
|
||||
* @param replacedQuestId Id of the replaced quest
|
||||
*/
|
||||
protected cleanUpRepeatableChangeRequirements(repeatablesOfTypeInProfile: IPmcDataRepeatableQuest, replacedQuestId: string): void;
|
||||
/**
|
||||
* Find a repeatable (daily/weekly/scav) from a players profile by its id
|
||||
* @param questId Id of quest to find
|
||||
@ -154,7 +166,7 @@ export declare class RepeatableQuestController {
|
||||
* @returns IGetRepeatableByIdResult
|
||||
*/
|
||||
protected getRepeatableById(questId: string, pmcData: IPmcData): IGetRepeatableByIdResult;
|
||||
protected attemptToGenerateRepeatableQuest(pmcData: IPmcData, questTypePool: IQuestTypePool, repeatableConfig: IRepeatableQuestConfig): IRepeatableQuest;
|
||||
protected attemptToGenerateRepeatableQuest(sessionId: string, pmcData: IPmcData, questTypePool: IQuestTypePool, repeatableConfig: IRepeatableQuestConfig): IRepeatableQuest;
|
||||
/**
|
||||
* Some accounts have access to free repeatable quest refreshes
|
||||
* Track the usage of them inside players profile
|
||||
|
@ -33,13 +33,14 @@ export declare class RepeatableQuestGenerator {
|
||||
/**
|
||||
* This method is called by /GetClientRepeatableQuests/ and creates one element of quest type format (see assets/database/templates/repeatableQuests.json).
|
||||
* It randomly draws a quest type (currently Elimination, Completion or Exploration) as well as a trader who is providing the quest
|
||||
* @param sessionId Session id
|
||||
* @param pmcLevel Player's level for requested items and reward generation
|
||||
* @param pmcTraderInfo Players traper standing/rep levels
|
||||
* @param questTypePool Possible quest types pool
|
||||
* @param repeatableConfig Repeatable quest config
|
||||
* @returns IRepeatableQuest
|
||||
*/
|
||||
generateRepeatableQuest(pmcLevel: number, pmcTraderInfo: Record<string, ITraderInfo>, questTypePool: IQuestTypePool, repeatableConfig: IRepeatableQuestConfig): IRepeatableQuest;
|
||||
generateRepeatableQuest(sessionId: string, pmcLevel: number, pmcTraderInfo: Record<string, ITraderInfo>, questTypePool: IQuestTypePool, repeatableConfig: IRepeatableQuestConfig): IRepeatableQuest;
|
||||
/**
|
||||
* Generate a randomised Elimination quest
|
||||
* @param pmcLevel Player's level for requested items and reward generation
|
||||
@ -48,7 +49,7 @@ export declare class RepeatableQuestGenerator {
|
||||
* @param repeatableConfig The configuration for the repeatably kind (daily, weekly) as configured in QuestConfig for the requestd quest
|
||||
* @returns Object of quest type format for "Elimination" (see assets/database/templates/repeatableQuests.json)
|
||||
*/
|
||||
protected generateEliminationQuest(pmcLevel: number, traderId: string, questTypePool: IQuestTypePool, repeatableConfig: IRepeatableQuestConfig): IRepeatableQuest;
|
||||
protected generateEliminationQuest(sessionid: string, pmcLevel: number, traderId: string, questTypePool: IQuestTypePool, repeatableConfig: IRepeatableQuestConfig): IRepeatableQuest;
|
||||
/**
|
||||
* Get a number of kills neded to complete elimination quest
|
||||
* @param targetKey Target type desired e.g. anyPmc/bossBully/Savage
|
||||
@ -83,7 +84,7 @@ export declare class RepeatableQuestGenerator {
|
||||
* @param {object} repeatableConfig The configuration for the repeatably kind (daily, weekly) as configured in QuestConfig for the requestd quest
|
||||
* @returns {object} object of quest type format for "Completion" (see assets/database/templates/repeatableQuests.json)
|
||||
*/
|
||||
protected generateCompletionQuest(pmcLevel: number, traderId: string, repeatableConfig: IRepeatableQuestConfig): IRepeatableQuest;
|
||||
protected generateCompletionQuest(sessionId: string, pmcLevel: number, traderId: string, repeatableConfig: IRepeatableQuestConfig): IRepeatableQuest;
|
||||
/**
|
||||
* A repeatable quest, besides some more or less static components, exists of reward and condition (see assets/database/templates/repeatableQuests.json)
|
||||
* This is a helper method for GenerateCompletionQuest to create a completion condition (of which a completion quest theoretically can have many)
|
||||
@ -102,7 +103,7 @@ export declare class RepeatableQuestGenerator {
|
||||
* @param {object} repeatableConfig The configuration for the repeatably kind (daily, weekly) as configured in QuestConfig for the requestd quest
|
||||
* @returns {object} object of quest type format for "Exploration" (see assets/database/templates/repeatableQuests.json)
|
||||
*/
|
||||
protected generateExplorationQuest(pmcLevel: number, traderId: string, questTypePool: IQuestTypePool, repeatableConfig: IRepeatableQuestConfig): IRepeatableQuest;
|
||||
protected generateExplorationQuest(sessionId: string, pmcLevel: number, traderId: string, questTypePool: IQuestTypePool, repeatableConfig: IRepeatableQuestConfig): IRepeatableQuest;
|
||||
/**
|
||||
* Filter a maps exits to just those for the desired side
|
||||
* @param locationKey Map id (e.g. factory4_day)
|
||||
@ -110,7 +111,7 @@ export declare class RepeatableQuestGenerator {
|
||||
* @returns Array of Exit objects
|
||||
*/
|
||||
protected getLocationExitsForSide(locationKey: string, playerSide: string): IExit[];
|
||||
protected generatePickupQuest(pmcLevel: number, traderId: string, questTypePool: IQuestTypePool, repeatableConfig: IRepeatableQuestConfig): IRepeatableQuest;
|
||||
protected generatePickupQuest(sessionId: string, pmcLevel: number, traderId: string, questTypePool: IQuestTypePool, repeatableConfig: IRepeatableQuestConfig): IRepeatableQuest;
|
||||
/**
|
||||
* Convert a location into an quest code can read (e.g. factory4_day into 55f2d3fd4bdc2d5f408b4567)
|
||||
* @param locationKey e.g factory4_day
|
||||
@ -135,5 +136,5 @@ export declare class RepeatableQuestGenerator {
|
||||
* @returns {object} Object which contains the base elements for repeatable quests of the requests type
|
||||
* (needs to be filled with reward and conditions by called to make a valid quest)
|
||||
*/
|
||||
protected generateRepeatableTemplate(type: string, traderId: string, side: string): IRepeatableQuest;
|
||||
protected generateRepeatableTemplate(type: string, traderId: string, side: string, sessionId: string): IRepeatableQuest;
|
||||
}
|
||||
|
@ -12,6 +12,7 @@ import { DatabaseService } from "@spt/services/DatabaseService";
|
||||
import { ItemFilterService } from "@spt/services/ItemFilterService";
|
||||
import { LocalisationService } from "@spt/services/LocalisationService";
|
||||
import { SeasonalEventService } from "@spt/services/SeasonalEventService";
|
||||
import { HashUtil } from "@spt/utils/HashUtil";
|
||||
import { MathUtil } from "@spt/utils/MathUtil";
|
||||
import { ObjectId } from "@spt/utils/ObjectId";
|
||||
import { RandomUtil } from "@spt/utils/RandomUtil";
|
||||
@ -19,6 +20,7 @@ import { ICloner } from "@spt/utils/cloners/ICloner";
|
||||
export declare class RepeatableQuestRewardGenerator {
|
||||
protected logger: ILogger;
|
||||
protected randomUtil: RandomUtil;
|
||||
protected hashUtil: HashUtil;
|
||||
protected mathUtil: MathUtil;
|
||||
protected databaseService: DatabaseService;
|
||||
protected itemHelper: ItemHelper;
|
||||
@ -31,7 +33,7 @@ export declare class RepeatableQuestRewardGenerator {
|
||||
protected configServer: ConfigServer;
|
||||
protected cloner: ICloner;
|
||||
protected questConfig: IQuestConfig;
|
||||
constructor(logger: ILogger, randomUtil: RandomUtil, mathUtil: MathUtil, databaseService: DatabaseService, itemHelper: ItemHelper, presetHelper: PresetHelper, handbookHelper: HandbookHelper, localisationService: LocalisationService, objectId: ObjectId, itemFilterService: ItemFilterService, seasonalEventService: SeasonalEventService, configServer: ConfigServer, cloner: ICloner);
|
||||
constructor(logger: ILogger, randomUtil: RandomUtil, hashUtil: HashUtil, mathUtil: MathUtil, databaseService: DatabaseService, itemHelper: ItemHelper, presetHelper: PresetHelper, handbookHelper: HandbookHelper, localisationService: LocalisationService, objectId: ObjectId, itemFilterService: ItemFilterService, seasonalEventService: SeasonalEventService, configServer: ConfigServer, cloner: ICloner);
|
||||
/**
|
||||
* Generate the reward for a mission. A reward can consist of:
|
||||
* - Experience
|
||||
@ -127,7 +129,7 @@ export declare class RepeatableQuestRewardGenerator {
|
||||
* @param preset Optional array of preset items
|
||||
* @returns {object} Object of "Reward"-item-type
|
||||
*/
|
||||
protected generateItemReward(tpl: string, count: number, index: number): IQuestReward;
|
||||
protected generateItemReward(tpl: string, count: number, index: number, foundInRaid?: boolean): IQuestReward;
|
||||
/**
|
||||
* Helper to create a reward item structured as required by the client
|
||||
*
|
||||
@ -137,7 +139,7 @@ export declare class RepeatableQuestRewardGenerator {
|
||||
* @param preset Optional array of preset items
|
||||
* @returns {object} Object of "Reward"-item-type
|
||||
*/
|
||||
protected generatePresetReward(tpl: string, count: number, index: number, preset?: IItem[]): IQuestReward;
|
||||
protected generatePresetReward(tpl: string, count: number, index: number, preset?: IItem[], foundInRaid?: boolean): IQuestReward;
|
||||
/**
|
||||
* Picks rewardable items from items.json
|
||||
* This means they must:
|
||||
|
@ -2,6 +2,7 @@ import { ItemHelper } from "@spt/helpers/ItemHelper";
|
||||
import { IPmcData } from "@spt/models/eft/common/IPmcData";
|
||||
import { Common, ICounterKeyValue, IStats } from "@spt/models/eft/common/tables/IBotBase";
|
||||
import { IItem } from "@spt/models/eft/common/tables/IItem";
|
||||
import { ISearchFriendResponse } from "@spt/models/eft/profile/ISearchFriendResponse";
|
||||
import { ISptProfile } from "@spt/models/eft/profile/ISptProfile";
|
||||
import { IValidateNicknameRequestData } from "@spt/models/eft/profile/IValidateNicknameRequestData";
|
||||
import { BonusType } from "@spt/models/enums/BonusType";
|
||||
@ -90,6 +91,24 @@ export declare class ProfileHelper {
|
||||
* @returns ISptProfile object
|
||||
*/
|
||||
getFullProfile(sessionID: string): ISptProfile | undefined;
|
||||
/**
|
||||
* Get full representation of a players profile JSON by the account ID, or undefined if not found
|
||||
* @param accountId Account ID to find
|
||||
* @returns
|
||||
*/
|
||||
getFullProfileByAccountId(accountID: string): ISptProfile | undefined;
|
||||
/**
|
||||
* Retrieve a ChatRoomMember formatted profile for the given session ID
|
||||
* @param sessionID The session ID to return the profile for
|
||||
* @returns
|
||||
*/
|
||||
getChatRoomMemberFromSessionId(sessionID: string): ISearchFriendResponse | undefined;
|
||||
/**
|
||||
* Retrieve a ChatRoomMember formatted profile for the given PMC profile data
|
||||
* @param pmcProfile The PMC profile data to format into a ChatRoomMember structure
|
||||
* @returns
|
||||
*/
|
||||
getChatRoomMemberFromPmcProfile(pmcProfile: IPmcData): ISearchFriendResponse;
|
||||
/**
|
||||
* Get a PMC profile by its session id
|
||||
* @param sessionID Profile id to return
|
||||
|
@ -11,23 +11,36 @@ export interface ILocationBase {
|
||||
Banners: IBanner[];
|
||||
BossLocationSpawn: IBossLocationSpawn[];
|
||||
BotAssault: number;
|
||||
/** Weighting on how likely a bot will be Easy difficulty */
|
||||
BotEasy: number;
|
||||
/** Weighting on how likely a bot will be Hard difficulty */
|
||||
BotHard: number;
|
||||
/** Weighting on how likely a bot will be Impossible difficulty */
|
||||
BotImpossible: number;
|
||||
BotLocationModifier: IBotLocationModifier;
|
||||
BotMarksman: number;
|
||||
/** Maximum Number of bots that are currently alive/loading/delayed */
|
||||
BotMax: number;
|
||||
/** Is not used in 33420 */
|
||||
BotMaxPlayer: number;
|
||||
/** Is not used in 33420 */
|
||||
BotMaxTimePlayer: number;
|
||||
/** Does not even exist in the client in 33420 */
|
||||
BotMaxPvE: number;
|
||||
/** Weighting on how likely a bot will be Normal difficulty */
|
||||
BotNormal: number;
|
||||
/** How many bot slots that need to be open before trying to spawn new bots. */
|
||||
BotSpawnCountStep: number;
|
||||
/** How often to check if bots are spawn-able. In seconds */
|
||||
BotSpawnPeriodCheck: number;
|
||||
/** The bot spawn will toggle on and off in intervals of Off(Min/Max) and On(Min/Max) */
|
||||
BotSpawnTimeOffMax: number;
|
||||
BotSpawnTimeOffMin: number;
|
||||
BotSpawnTimeOnMax: number;
|
||||
BotSpawnTimeOnMin: number;
|
||||
/** How soon bots will be allowed to spawn */
|
||||
BotStart: number;
|
||||
/** After this long bots will no longer spawn */
|
||||
BotStop: number;
|
||||
Description: string;
|
||||
DisabledForScav: boolean;
|
||||
|
@ -33,6 +33,11 @@ export interface IQuest {
|
||||
changeQuestMessageText: string;
|
||||
/** "Pmc" or "Scav" */
|
||||
side: string;
|
||||
acceptanceAndFinishingSource: string;
|
||||
progressSource: string;
|
||||
rankingModes: string[];
|
||||
gameModes: string[];
|
||||
arenaLocations: string[];
|
||||
/** Status of quest to player */
|
||||
sptStatus?: QuestStatus;
|
||||
}
|
||||
@ -148,8 +153,10 @@ export interface IQuestReward {
|
||||
loyaltyLevel?: number;
|
||||
/** Hideout area id */
|
||||
traderId?: string;
|
||||
isEncoded?: boolean;
|
||||
unknown?: boolean;
|
||||
findInRaid?: boolean;
|
||||
gameMode?: string[];
|
||||
/** Game editions whitelisted to get reward */
|
||||
availableInGameEditions?: string[];
|
||||
/** Game editions blacklisted from getting reward */
|
||||
|
@ -3,6 +3,12 @@ export interface IRepeatableQuest extends IQuest {
|
||||
changeCost: IChangeCost[];
|
||||
changeStandingCost: number;
|
||||
sptRepatableGroupName: string;
|
||||
acceptanceAndFinishingSource: string;
|
||||
progressSource: string;
|
||||
rankingModes: string[];
|
||||
gameModes: string[];
|
||||
arenaLocations: string[];
|
||||
questStatus: IRepeatableQuestStatus;
|
||||
}
|
||||
export interface IRepeatableQuestDatabase {
|
||||
templates: IRepeatableTemplates;
|
||||
@ -10,6 +16,14 @@ export interface IRepeatableQuestDatabase {
|
||||
data: IOptions;
|
||||
samples: ISampleQuests[];
|
||||
}
|
||||
export interface IRepeatableQuestStatus {
|
||||
id: string;
|
||||
uid: string;
|
||||
qid: string;
|
||||
startTime: number;
|
||||
status: number;
|
||||
statusTimers: any;
|
||||
}
|
||||
export interface IRepeatableTemplates {
|
||||
Elimination: IQuest;
|
||||
Completion: IQuest;
|
||||
|
@ -8,4 +8,5 @@ export interface Info {
|
||||
Side: string;
|
||||
Level: number;
|
||||
MemberCategory: number;
|
||||
SelectedMemberCategory: number;
|
||||
}
|
||||
|
@ -19,6 +19,8 @@ export interface ISptProfile {
|
||||
traderPurchases?: Record<string, Record<string, ITraderPurchaseData>>;
|
||||
/** Achievements earned by player */
|
||||
achievements: Record<string, number>;
|
||||
/** List of friend profile IDs */
|
||||
friends: string[];
|
||||
}
|
||||
export declare class ITraderPurchaseData {
|
||||
count: number;
|
||||
|
5
TypeScript/13.1AddTraderWithAssortJSON/types/models/eft/ws/IWsFriendsListAccept.d.ts
vendored
Normal file
5
TypeScript/13.1AddTraderWithAssortJSON/types/models/eft/ws/IWsFriendsListAccept.d.ts
vendored
Normal file
@ -0,0 +1,5 @@
|
||||
import { IWsNotificationEvent } from "@spt/models/eft/ws/IWsNotificationEvent";
|
||||
import { ISearchFriendResponse } from "../profile/ISearchFriendResponse";
|
||||
export interface IWsFriendsListAccept extends IWsNotificationEvent {
|
||||
profile: ISearchFriendResponse;
|
||||
}
|
@ -1,4 +1,4 @@
|
||||
export interface IWsNotificationEvent {
|
||||
type: string;
|
||||
eventId: string;
|
||||
eventId?: string;
|
||||
}
|
||||
|
@ -1,5 +1,6 @@
|
||||
export declare enum ConfigTypes {
|
||||
AIRDROP = "spt-airdrop",
|
||||
BACKUP = "spt-backup",
|
||||
BOT = "spt-bot",
|
||||
PMC = "spt-pmc",
|
||||
CORE = "spt-core",
|
||||
|
12
TypeScript/13.1AddTraderWithAssortJSON/types/models/spt/config/IBackupConfig.d.ts
vendored
Normal file
12
TypeScript/13.1AddTraderWithAssortJSON/types/models/spt/config/IBackupConfig.d.ts
vendored
Normal file
@ -0,0 +1,12 @@
|
||||
import { IBaseConfig } from "@spt/models/spt/config/IBaseConfig";
|
||||
export interface IBackupConfig extends IBaseConfig {
|
||||
kind: "spt-backup";
|
||||
enabled: boolean;
|
||||
maxBackups: number;
|
||||
directory: string;
|
||||
backupInterval: IBackupConfigInterval;
|
||||
}
|
||||
export interface IBackupConfigInterval {
|
||||
enabled: boolean;
|
||||
intervalMinutes: number;
|
||||
}
|
@ -7,6 +7,8 @@ export interface IItemConfig extends IBaseConfig {
|
||||
lootableItemBlacklist: string[];
|
||||
/** items that should not be given as rewards */
|
||||
rewardItemBlacklist: string[];
|
||||
/** Item base types that should not be given as rewards */
|
||||
rewardItemTypeBlacklist: string[];
|
||||
/** Items that can only be found on bosses */
|
||||
bossItems: string[];
|
||||
handbookPriceOverride: Record<string, IHandbookPriceOverride>;
|
||||
|
98
TypeScript/13.1AddTraderWithAssortJSON/types/services/BackupService.d.ts
vendored
Normal file
98
TypeScript/13.1AddTraderWithAssortJSON/types/services/BackupService.d.ts
vendored
Normal file
@ -0,0 +1,98 @@
|
||||
import { PreSptModLoader } from "@spt/loaders/PreSptModLoader";
|
||||
import { IBackupConfig } from "@spt/models/spt/config/IBackupConfig";
|
||||
import { ILogger } from "@spt/models/spt/utils/ILogger";
|
||||
import { ConfigServer } from "@spt/servers/ConfigServer";
|
||||
export declare class BackupService {
|
||||
protected logger: ILogger;
|
||||
protected preSptModLoader: PreSptModLoader;
|
||||
protected configServer: ConfigServer;
|
||||
protected backupConfig: IBackupConfig;
|
||||
protected readonly activeServerMods: string[];
|
||||
protected readonly profileDir = "./user/profiles";
|
||||
constructor(logger: ILogger, preSptModLoader: PreSptModLoader, configServer: ConfigServer);
|
||||
/**
|
||||
* Initializes the backup process.
|
||||
*
|
||||
* This method orchestrates the profile backup service. Handles copying profiles to a backup directory and cleaning
|
||||
* up old backups if the number exceeds the configured maximum.
|
||||
*
|
||||
* @returns A promise that resolves when the backup process is complete.
|
||||
*/
|
||||
init(): Promise<void>;
|
||||
/**
|
||||
* Fetches the names of all JSON files in the profile directory.
|
||||
*
|
||||
* This method normalizes the profile directory path and reads all files within it. It then filters the files to
|
||||
* include only those with a `.json` extension and returns their names.
|
||||
*
|
||||
* @returns A promise that resolves to an array of JSON file names.
|
||||
*/
|
||||
protected fetchProfileFiles(): Promise<string[]>;
|
||||
/**
|
||||
* Check to see if the backup service is enabled via the config.
|
||||
*
|
||||
* @returns True if enabled, false otherwise.
|
||||
*/
|
||||
protected isEnabled(): boolean;
|
||||
/**
|
||||
* Generates the target directory path for the backup. The directory path is constructed using the `directory` from
|
||||
* the configuration and the current backup date.
|
||||
*
|
||||
* @returns The target directory path for the backup.
|
||||
*/
|
||||
protected generateBackupTargetDir(): string;
|
||||
/**
|
||||
* Generates a formatted backup date string in the format `YYYY-MM-DD_hh-mm-ss`.
|
||||
*
|
||||
* @returns The formatted backup date string.
|
||||
*/
|
||||
protected generateBackupDate(): string;
|
||||
/**
|
||||
* Cleans up old backups in the backup directory.
|
||||
*
|
||||
* This method reads the backup directory, and sorts backups by modification time. If the number of backups exceeds
|
||||
* the configured maximum, it deletes the oldest backups.
|
||||
*
|
||||
* @returns A promise that resolves when the cleanup is complete.
|
||||
*/
|
||||
protected cleanBackups(): Promise<void>;
|
||||
/**
|
||||
* Retrieves and sorts the backup file paths from the specified directory.
|
||||
*
|
||||
* @param dir - The directory to search for backup files.
|
||||
* @returns A promise that resolves to an array of sorted backup file paths.
|
||||
*/
|
||||
private getBackupPaths;
|
||||
/**
|
||||
* Compares two backup folder names based on their extracted dates.
|
||||
*
|
||||
* @param a - The name of the first backup folder.
|
||||
* @param b - The name of the second backup folder.
|
||||
* @returns The difference in time between the two dates in milliseconds, or `null` if either date is invalid.
|
||||
*/
|
||||
private compareBackupDates;
|
||||
/**
|
||||
* Extracts a date from a folder name string formatted as `YYYY-MM-DD_hh-mm-ss`.
|
||||
*
|
||||
* @param folderName - The name of the folder from which to extract the date.
|
||||
* @returns A Date object if the folder name is in the correct format, otherwise null.
|
||||
*/
|
||||
private extractDateFromFolderName;
|
||||
/**
|
||||
* Removes excess backups from the backup directory.
|
||||
*
|
||||
* @param backups - An array of backup file names to be removed.
|
||||
* @returns A promise that resolves when all specified backups have been removed.
|
||||
*/
|
||||
private removeExcessBackups;
|
||||
/**
|
||||
* Start the backup interval if enabled in the configuration.
|
||||
*/
|
||||
protected startBackupInterval(): void;
|
||||
/**
|
||||
* Get an array of active server mod details.
|
||||
*
|
||||
* @returns An array of mod names.
|
||||
*/
|
||||
protected getActiveServerMods(): string[];
|
||||
}
|
@ -54,6 +54,16 @@ export declare class CircleOfCultistService {
|
||||
* @returns IItemEventRouterResponse
|
||||
*/
|
||||
startSacrifice(sessionId: string, pmcData: IPmcData, request: IHideoutCircleOfCultistProductionStartRequestData): IItemEventRouterResponse;
|
||||
/**
|
||||
* Attempt to add all rewards to cultist circle, if they dont fit remove one and try again until they fit
|
||||
* @param sessionId Session id
|
||||
* @param pmcData Player profile
|
||||
* @param rewards Rewards to send to player
|
||||
* @param containerGrid Cultist grid to add rewards to
|
||||
* @param cultistCircleStashId Stash id
|
||||
* @param output Client output
|
||||
*/
|
||||
protected addRewardsToCircleContainer(sessionId: string, pmcData: IPmcData, rewards: IItem[][], containerGrid: number[][], cultistCircleStashId: string, output: IItemEventRouterResponse): void;
|
||||
/**
|
||||
* Create a map of the possible direct rewards, keyed by the items needed to be sacrificed
|
||||
* @param directRewards Direct rewards array from hideout config
|
||||
@ -156,7 +166,7 @@ export declare class CircleOfCultistService {
|
||||
* @param itemRewardBlacklist Items not to add to pool
|
||||
* @param rewardPool Pool to add items to
|
||||
*/
|
||||
protected addTaskItemRequirementsToRewardPool(pmcData: IPmcData, itemRewardBlacklist: string[], rewardPool: Set<string>): void;
|
||||
protected addTaskItemRequirementsToRewardPool(pmcData: IPmcData, itemRewardBlacklist: Set<string>, rewardPool: Set<string>): void;
|
||||
/**
|
||||
* Adds items the player needs to complete hideout crafts/upgrades to the reward pool
|
||||
* @param hideoutDbData Hideout area data
|
||||
@ -164,7 +174,7 @@ export declare class CircleOfCultistService {
|
||||
* @param itemRewardBlacklist Items not to add to pool
|
||||
* @param rewardPool Pool to add items to
|
||||
*/
|
||||
protected addHideoutUpgradeRequirementsToRewardPool(hideoutDbData: IHideout, pmcData: IPmcData, itemRewardBlacklist: string[], rewardPool: Set<string>): void;
|
||||
protected addHideoutUpgradeRequirementsToRewardPool(hideoutDbData: IHideout, pmcData: IPmcData, itemRewardBlacklist: Set<string>, rewardPool: Set<string>): void;
|
||||
/**
|
||||
* Get all active hideout areas
|
||||
* @param areas Hideout areas to iterate over
|
||||
@ -174,11 +184,11 @@ export declare class CircleOfCultistService {
|
||||
/**
|
||||
* Get array of random reward items
|
||||
* @param rewardPool Reward pool to add to
|
||||
* @param itemRewardBlacklist Reward Blacklist
|
||||
* @param itemRewardBlacklist Item tpls to ignore
|
||||
* @param itemsShouldBeHighValue Should these items meet the valuable threshold
|
||||
* @returns rewardPool
|
||||
* @returns Set of item tpls
|
||||
*/
|
||||
protected generateRandomisedItemsAndAddToRewardPool(rewardPool: Set<string>, itemRewardBlacklist: string[], itemsShouldBeHighValue: boolean): Set<string>;
|
||||
protected generateRandomisedItemsAndAddToRewardPool(rewardPool: Set<string>, itemRewardBlacklist: Set<string>, itemsShouldBeHighValue: boolean): Set<string>;
|
||||
/**
|
||||
* Iterate over passed in hideout requirements and return the Item
|
||||
* @param requirements Requirements to iterate over
|
||||
|
@ -36,6 +36,11 @@ export declare class ItemFilterService {
|
||||
* @returns string array of item tpls
|
||||
*/
|
||||
getItemRewardBlacklist(): string[];
|
||||
/**
|
||||
* Get an array of item types that should never be given as a reward to player
|
||||
* @returns string array of item base ids
|
||||
*/
|
||||
getItemRewardBaseTypeBlacklist(): string[];
|
||||
/**
|
||||
* Return every template id blacklisted in config/item.json
|
||||
* @returns string array of blacklisted tempalte ids
|
||||
|
@ -4,10 +4,10 @@ import { ICoreConfig } from "@spt/models/spt/config/ICoreConfig";
|
||||
import { ILogger } from "@spt/models/spt/utils/ILogger";
|
||||
import { ConfigServer } from "@spt/servers/ConfigServer";
|
||||
import { HttpServer } from "@spt/servers/HttpServer";
|
||||
import { DatabaseService } from "@spt/services/DatabaseService";
|
||||
import { LocalisationService } from "@spt/services/LocalisationService";
|
||||
import { EncodingUtil } from "@spt/utils/EncodingUtil";
|
||||
import { TimeUtil } from "@spt/utils/TimeUtil";
|
||||
import { DatabaseService } from "@spt/services/DatabaseService";
|
||||
export declare class App {
|
||||
protected logger: ILogger;
|
||||
protected timeUtil: TimeUtil;
|
||||
|
@ -106,6 +106,11 @@ export declare class RandomUtil {
|
||||
protected cloner: ICloner;
|
||||
protected logger: ILogger;
|
||||
constructor(cloner: ICloner, logger: ILogger);
|
||||
/**
|
||||
* The IEEE-754 standard for double-precision floating-point numbers limits the number of digits (including both
|
||||
* integer + fractional parts) to about 15–17 significant digits. 15 is a safe upper bound, so we'll use that.
|
||||
*/
|
||||
private static readonly MAX_SIGNIFICANT_DIGITS;
|
||||
/**
|
||||
* Generates a secure random number between 0 (inclusive) and 1 (exclusive).
|
||||
*
|
||||
@ -116,6 +121,16 @@ export declare class RandomUtil {
|
||||
* @returns A secure random number between 0 (inclusive) and 1 (exclusive).
|
||||
*/
|
||||
private getSecureRandomNumber;
|
||||
/**
|
||||
* Determines the number of decimal places in a number.
|
||||
*
|
||||
* @param num - The number to analyze.
|
||||
* @returns The number of decimal places, or 0 if none exist.
|
||||
* @remarks There is a mathematical way to determine this, but it's not as simple as it seams due to floating point
|
||||
* precision issues. This method is a simple workaround that converts the number to a string and splits it.
|
||||
* It's not the most efficient but it *is* the most reliable and easy to understand. Come at me.
|
||||
*/
|
||||
private getNumberPrecision;
|
||||
/**
|
||||
* Generates a random integer between the specified minimum and maximum values, inclusive.
|
||||
*
|
||||
@ -173,7 +188,7 @@ export declare class RandomUtil {
|
||||
/**
|
||||
* Returns a random string from the provided array of strings.
|
||||
*
|
||||
* This method is separate from getArrayValue so we can use a generic inferance with getArrayValue.
|
||||
* This method is separate from getArrayValue so we can use a generic inference with getArrayValue.
|
||||
*
|
||||
* @param arr - The array of strings to select a random value from.
|
||||
* @returns A randomly selected string from the array.
|
||||
@ -225,12 +240,27 @@ export declare class RandomUtil {
|
||||
getNormallyDistributedRandomNumber(mean: number, sigma: number, attempt?: number): number;
|
||||
/**
|
||||
* Generates a random integer between the specified range.
|
||||
* Low and high parameters are floored to integers.
|
||||
*
|
||||
* TODO: v3.11 - This method should not accept non-integer numbers.
|
||||
*
|
||||
* @param low - The lower bound of the range (inclusive).
|
||||
* @param high - The upper bound of the range (exclusive). If not provided, the range will be from 0 to `low`.
|
||||
* @returns A random integer within the specified range.
|
||||
*/
|
||||
randInt(low: number, high?: number): number;
|
||||
/**
|
||||
* Generates a random number between two given values with optional precision.
|
||||
*
|
||||
* @param value1 - The first value to determine the range.
|
||||
* @param value2 - The second value to determine the range. If not provided, 0 is used.
|
||||
* @param precision - The number of decimal places to round the result to. Must be a positive integer between 0
|
||||
* and MAX_PRECISION, inclusive. If not provided, precision is determined by the input values.
|
||||
* @returns A random floating-point number between `value1` and `value2` (inclusive) with the specified precision.
|
||||
* @throws Will throw an error if `precision` is not a positive integer, if `value1` or `value2` are not finite
|
||||
* numbers, or if the precision exceeds the maximum allowed for the given values.
|
||||
*/
|
||||
randNum(value1: number, value2?: number, precision?: number | null): number;
|
||||
/**
|
||||
* Draws a specified number of random elements from a given list.
|
||||
*
|
||||
|
@ -3,11 +3,13 @@ import { OnUpdate } from "@spt/di/OnUpdate";
|
||||
import { ICoreConfig } from "@spt/models/spt/config/ICoreConfig";
|
||||
import { ConfigServer } from "@spt/servers/ConfigServer";
|
||||
import { SaveServer } from "@spt/servers/SaveServer";
|
||||
import { BackupService } from "@spt/services/BackupService";
|
||||
export declare class SaveCallbacks implements OnLoad, OnUpdate {
|
||||
protected saveServer: SaveServer;
|
||||
protected configServer: ConfigServer;
|
||||
protected backupService: BackupService;
|
||||
protected coreConfig: ICoreConfig;
|
||||
constructor(saveServer: SaveServer, configServer: ConfigServer);
|
||||
constructor(saveServer: SaveServer, configServer: ConfigServer, backupService: BackupService);
|
||||
onLoad(): Promise<void>;
|
||||
getRoute(): string;
|
||||
onUpdate(secondsSinceLastRun: number): Promise<boolean>;
|
||||
|
@ -1,5 +1,8 @@
|
||||
import { IDialogueChatBot } from "@spt/helpers/Dialogue/IDialogueChatBot";
|
||||
import { DialogueHelper } from "@spt/helpers/DialogueHelper";
|
||||
import { NotificationSendHelper } from "@spt/helpers/NotificationSendHelper";
|
||||
import { ProfileHelper } from "@spt/helpers/ProfileHelper";
|
||||
import { IDeleteFriendRequest } from "@spt/models/eft/dialog/IDeleteFriendRequest";
|
||||
import { IFriendRequestData } from "@spt/models/eft/dialog/IFriendRequestData";
|
||||
import { IFriendRequestSendResponse } from "@spt/models/eft/dialog/IFriendRequestSendResponse";
|
||||
import { IGetAllAttachmentsResponse } from "@spt/models/eft/dialog/IGetAllAttachmentsResponse";
|
||||
@ -20,11 +23,13 @@ export declare class DialogueController {
|
||||
protected saveServer: SaveServer;
|
||||
protected timeUtil: TimeUtil;
|
||||
protected dialogueHelper: DialogueHelper;
|
||||
protected notificationSendHelper: NotificationSendHelper;
|
||||
protected profileHelper: ProfileHelper;
|
||||
protected mailSendService: MailSendService;
|
||||
protected localisationService: LocalisationService;
|
||||
protected configServer: ConfigServer;
|
||||
protected dialogueChatBots: IDialogueChatBot[];
|
||||
constructor(logger: ILogger, saveServer: SaveServer, timeUtil: TimeUtil, dialogueHelper: DialogueHelper, mailSendService: MailSendService, localisationService: LocalisationService, configServer: ConfigServer, dialogueChatBots: IDialogueChatBot[]);
|
||||
constructor(logger: ILogger, saveServer: SaveServer, timeUtil: TimeUtil, dialogueHelper: DialogueHelper, notificationSendHelper: NotificationSendHelper, profileHelper: ProfileHelper, mailSendService: MailSendService, localisationService: LocalisationService, configServer: ConfigServer, dialogueChatBots: IDialogueChatBot[]);
|
||||
registerChatBot(chatBot: IDialogueChatBot): void;
|
||||
/** Handle onUpdate spt event */
|
||||
update(): void;
|
||||
@ -151,4 +156,6 @@ export declare class DialogueController {
|
||||
protected messageHasExpired(message: IMessage): boolean;
|
||||
/** Handle client/friend/request/send */
|
||||
sendFriendRequest(sessionID: string, request: IFriendRequestData): IFriendRequestSendResponse;
|
||||
/** Handle client/friend/delete */
|
||||
deleteFriend(sessionID: string, request: IDeleteFriendRequest): void;
|
||||
}
|
||||
|
@ -72,6 +72,7 @@ export declare class QuestController {
|
||||
*/
|
||||
protected addTaskConditionCountersToProfile(questConditions: IQuestCondition[], pmcData: IPmcData, questId: string): void;
|
||||
/**
|
||||
* TODO - Move this code into RepeatableQuestController
|
||||
* Handle the client accepting a repeatable quest and starting it
|
||||
* Send starting rewards if any to player and
|
||||
* Send start notification if any to player
|
||||
@ -81,7 +82,6 @@ export declare class QuestController {
|
||||
* @returns IItemEventRouterResponse
|
||||
*/
|
||||
acceptRepeatableQuest(pmcData: IPmcData, acceptedQuest: IAcceptQuestRequestData, sessionID: string): IItemEventRouterResponse;
|
||||
protected createAcceptedQuestClientResponse(sessionID: string, pmcData: IPmcData, repeatableQuestProfile: IRepeatableQuest): IItemEventRouterResponse;
|
||||
/**
|
||||
* Look for an accepted quest inside player profile, return matching
|
||||
* @param pmcData Profile to search through
|
||||
|
@ -147,6 +147,18 @@ export declare class RepeatableQuestController {
|
||||
* @returns IItemEventRouterResponse
|
||||
*/
|
||||
changeRepeatableQuest(pmcData: IPmcData, changeRequest: IRepeatableQuestChangeRequest, sessionID: string): IItemEventRouterResponse;
|
||||
/**
|
||||
* Remove the provided quest from pmc and scav character profiles
|
||||
* @param fullProfile Profile to remove quest from
|
||||
* @param questToReplaceId Quest id to remove from profile
|
||||
*/
|
||||
protected removeQuestFromProfile(fullProfile: ISptProfile, questToReplaceId: string): void;
|
||||
/**
|
||||
* Clean up the repeatables `changeRequirement` dictionary of expired data
|
||||
* @param repeatablesOfTypeInProfile The repeatables that have the replaced and new quest
|
||||
* @param replacedQuestId Id of the replaced quest
|
||||
*/
|
||||
protected cleanUpRepeatableChangeRequirements(repeatablesOfTypeInProfile: IPmcDataRepeatableQuest, replacedQuestId: string): void;
|
||||
/**
|
||||
* Find a repeatable (daily/weekly/scav) from a players profile by its id
|
||||
* @param questId Id of quest to find
|
||||
@ -154,7 +166,7 @@ export declare class RepeatableQuestController {
|
||||
* @returns IGetRepeatableByIdResult
|
||||
*/
|
||||
protected getRepeatableById(questId: string, pmcData: IPmcData): IGetRepeatableByIdResult;
|
||||
protected attemptToGenerateRepeatableQuest(pmcData: IPmcData, questTypePool: IQuestTypePool, repeatableConfig: IRepeatableQuestConfig): IRepeatableQuest;
|
||||
protected attemptToGenerateRepeatableQuest(sessionId: string, pmcData: IPmcData, questTypePool: IQuestTypePool, repeatableConfig: IRepeatableQuestConfig): IRepeatableQuest;
|
||||
/**
|
||||
* Some accounts have access to free repeatable quest refreshes
|
||||
* Track the usage of them inside players profile
|
||||
|
@ -33,13 +33,14 @@ export declare class RepeatableQuestGenerator {
|
||||
/**
|
||||
* This method is called by /GetClientRepeatableQuests/ and creates one element of quest type format (see assets/database/templates/repeatableQuests.json).
|
||||
* It randomly draws a quest type (currently Elimination, Completion or Exploration) as well as a trader who is providing the quest
|
||||
* @param sessionId Session id
|
||||
* @param pmcLevel Player's level for requested items and reward generation
|
||||
* @param pmcTraderInfo Players traper standing/rep levels
|
||||
* @param questTypePool Possible quest types pool
|
||||
* @param repeatableConfig Repeatable quest config
|
||||
* @returns IRepeatableQuest
|
||||
*/
|
||||
generateRepeatableQuest(pmcLevel: number, pmcTraderInfo: Record<string, ITraderInfo>, questTypePool: IQuestTypePool, repeatableConfig: IRepeatableQuestConfig): IRepeatableQuest;
|
||||
generateRepeatableQuest(sessionId: string, pmcLevel: number, pmcTraderInfo: Record<string, ITraderInfo>, questTypePool: IQuestTypePool, repeatableConfig: IRepeatableQuestConfig): IRepeatableQuest;
|
||||
/**
|
||||
* Generate a randomised Elimination quest
|
||||
* @param pmcLevel Player's level for requested items and reward generation
|
||||
@ -48,7 +49,7 @@ export declare class RepeatableQuestGenerator {
|
||||
* @param repeatableConfig The configuration for the repeatably kind (daily, weekly) as configured in QuestConfig for the requestd quest
|
||||
* @returns Object of quest type format for "Elimination" (see assets/database/templates/repeatableQuests.json)
|
||||
*/
|
||||
protected generateEliminationQuest(pmcLevel: number, traderId: string, questTypePool: IQuestTypePool, repeatableConfig: IRepeatableQuestConfig): IRepeatableQuest;
|
||||
protected generateEliminationQuest(sessionid: string, pmcLevel: number, traderId: string, questTypePool: IQuestTypePool, repeatableConfig: IRepeatableQuestConfig): IRepeatableQuest;
|
||||
/**
|
||||
* Get a number of kills neded to complete elimination quest
|
||||
* @param targetKey Target type desired e.g. anyPmc/bossBully/Savage
|
||||
@ -83,7 +84,7 @@ export declare class RepeatableQuestGenerator {
|
||||
* @param {object} repeatableConfig The configuration for the repeatably kind (daily, weekly) as configured in QuestConfig for the requestd quest
|
||||
* @returns {object} object of quest type format for "Completion" (see assets/database/templates/repeatableQuests.json)
|
||||
*/
|
||||
protected generateCompletionQuest(pmcLevel: number, traderId: string, repeatableConfig: IRepeatableQuestConfig): IRepeatableQuest;
|
||||
protected generateCompletionQuest(sessionId: string, pmcLevel: number, traderId: string, repeatableConfig: IRepeatableQuestConfig): IRepeatableQuest;
|
||||
/**
|
||||
* A repeatable quest, besides some more or less static components, exists of reward and condition (see assets/database/templates/repeatableQuests.json)
|
||||
* This is a helper method for GenerateCompletionQuest to create a completion condition (of which a completion quest theoretically can have many)
|
||||
@ -102,7 +103,7 @@ export declare class RepeatableQuestGenerator {
|
||||
* @param {object} repeatableConfig The configuration for the repeatably kind (daily, weekly) as configured in QuestConfig for the requestd quest
|
||||
* @returns {object} object of quest type format for "Exploration" (see assets/database/templates/repeatableQuests.json)
|
||||
*/
|
||||
protected generateExplorationQuest(pmcLevel: number, traderId: string, questTypePool: IQuestTypePool, repeatableConfig: IRepeatableQuestConfig): IRepeatableQuest;
|
||||
protected generateExplorationQuest(sessionId: string, pmcLevel: number, traderId: string, questTypePool: IQuestTypePool, repeatableConfig: IRepeatableQuestConfig): IRepeatableQuest;
|
||||
/**
|
||||
* Filter a maps exits to just those for the desired side
|
||||
* @param locationKey Map id (e.g. factory4_day)
|
||||
@ -110,7 +111,7 @@ export declare class RepeatableQuestGenerator {
|
||||
* @returns Array of Exit objects
|
||||
*/
|
||||
protected getLocationExitsForSide(locationKey: string, playerSide: string): IExit[];
|
||||
protected generatePickupQuest(pmcLevel: number, traderId: string, questTypePool: IQuestTypePool, repeatableConfig: IRepeatableQuestConfig): IRepeatableQuest;
|
||||
protected generatePickupQuest(sessionId: string, pmcLevel: number, traderId: string, questTypePool: IQuestTypePool, repeatableConfig: IRepeatableQuestConfig): IRepeatableQuest;
|
||||
/**
|
||||
* Convert a location into an quest code can read (e.g. factory4_day into 55f2d3fd4bdc2d5f408b4567)
|
||||
* @param locationKey e.g factory4_day
|
||||
@ -135,5 +136,5 @@ export declare class RepeatableQuestGenerator {
|
||||
* @returns {object} Object which contains the base elements for repeatable quests of the requests type
|
||||
* (needs to be filled with reward and conditions by called to make a valid quest)
|
||||
*/
|
||||
protected generateRepeatableTemplate(type: string, traderId: string, side: string): IRepeatableQuest;
|
||||
protected generateRepeatableTemplate(type: string, traderId: string, side: string, sessionId: string): IRepeatableQuest;
|
||||
}
|
||||
|
@ -12,6 +12,7 @@ import { DatabaseService } from "@spt/services/DatabaseService";
|
||||
import { ItemFilterService } from "@spt/services/ItemFilterService";
|
||||
import { LocalisationService } from "@spt/services/LocalisationService";
|
||||
import { SeasonalEventService } from "@spt/services/SeasonalEventService";
|
||||
import { HashUtil } from "@spt/utils/HashUtil";
|
||||
import { MathUtil } from "@spt/utils/MathUtil";
|
||||
import { ObjectId } from "@spt/utils/ObjectId";
|
||||
import { RandomUtil } from "@spt/utils/RandomUtil";
|
||||
@ -19,6 +20,7 @@ import { ICloner } from "@spt/utils/cloners/ICloner";
|
||||
export declare class RepeatableQuestRewardGenerator {
|
||||
protected logger: ILogger;
|
||||
protected randomUtil: RandomUtil;
|
||||
protected hashUtil: HashUtil;
|
||||
protected mathUtil: MathUtil;
|
||||
protected databaseService: DatabaseService;
|
||||
protected itemHelper: ItemHelper;
|
||||
@ -31,7 +33,7 @@ export declare class RepeatableQuestRewardGenerator {
|
||||
protected configServer: ConfigServer;
|
||||
protected cloner: ICloner;
|
||||
protected questConfig: IQuestConfig;
|
||||
constructor(logger: ILogger, randomUtil: RandomUtil, mathUtil: MathUtil, databaseService: DatabaseService, itemHelper: ItemHelper, presetHelper: PresetHelper, handbookHelper: HandbookHelper, localisationService: LocalisationService, objectId: ObjectId, itemFilterService: ItemFilterService, seasonalEventService: SeasonalEventService, configServer: ConfigServer, cloner: ICloner);
|
||||
constructor(logger: ILogger, randomUtil: RandomUtil, hashUtil: HashUtil, mathUtil: MathUtil, databaseService: DatabaseService, itemHelper: ItemHelper, presetHelper: PresetHelper, handbookHelper: HandbookHelper, localisationService: LocalisationService, objectId: ObjectId, itemFilterService: ItemFilterService, seasonalEventService: SeasonalEventService, configServer: ConfigServer, cloner: ICloner);
|
||||
/**
|
||||
* Generate the reward for a mission. A reward can consist of:
|
||||
* - Experience
|
||||
@ -127,7 +129,7 @@ export declare class RepeatableQuestRewardGenerator {
|
||||
* @param preset Optional array of preset items
|
||||
* @returns {object} Object of "Reward"-item-type
|
||||
*/
|
||||
protected generateItemReward(tpl: string, count: number, index: number): IQuestReward;
|
||||
protected generateItemReward(tpl: string, count: number, index: number, foundInRaid?: boolean): IQuestReward;
|
||||
/**
|
||||
* Helper to create a reward item structured as required by the client
|
||||
*
|
||||
@ -137,7 +139,7 @@ export declare class RepeatableQuestRewardGenerator {
|
||||
* @param preset Optional array of preset items
|
||||
* @returns {object} Object of "Reward"-item-type
|
||||
*/
|
||||
protected generatePresetReward(tpl: string, count: number, index: number, preset?: IItem[]): IQuestReward;
|
||||
protected generatePresetReward(tpl: string, count: number, index: number, preset?: IItem[], foundInRaid?: boolean): IQuestReward;
|
||||
/**
|
||||
* Picks rewardable items from items.json
|
||||
* This means they must:
|
||||
|
@ -2,6 +2,7 @@ import { ItemHelper } from "@spt/helpers/ItemHelper";
|
||||
import { IPmcData } from "@spt/models/eft/common/IPmcData";
|
||||
import { Common, ICounterKeyValue, IStats } from "@spt/models/eft/common/tables/IBotBase";
|
||||
import { IItem } from "@spt/models/eft/common/tables/IItem";
|
||||
import { ISearchFriendResponse } from "@spt/models/eft/profile/ISearchFriendResponse";
|
||||
import { ISptProfile } from "@spt/models/eft/profile/ISptProfile";
|
||||
import { IValidateNicknameRequestData } from "@spt/models/eft/profile/IValidateNicknameRequestData";
|
||||
import { BonusType } from "@spt/models/enums/BonusType";
|
||||
@ -90,6 +91,24 @@ export declare class ProfileHelper {
|
||||
* @returns ISptProfile object
|
||||
*/
|
||||
getFullProfile(sessionID: string): ISptProfile | undefined;
|
||||
/**
|
||||
* Get full representation of a players profile JSON by the account ID, or undefined if not found
|
||||
* @param accountId Account ID to find
|
||||
* @returns
|
||||
*/
|
||||
getFullProfileByAccountId(accountID: string): ISptProfile | undefined;
|
||||
/**
|
||||
* Retrieve a ChatRoomMember formatted profile for the given session ID
|
||||
* @param sessionID The session ID to return the profile for
|
||||
* @returns
|
||||
*/
|
||||
getChatRoomMemberFromSessionId(sessionID: string): ISearchFriendResponse | undefined;
|
||||
/**
|
||||
* Retrieve a ChatRoomMember formatted profile for the given PMC profile data
|
||||
* @param pmcProfile The PMC profile data to format into a ChatRoomMember structure
|
||||
* @returns
|
||||
*/
|
||||
getChatRoomMemberFromPmcProfile(pmcProfile: IPmcData): ISearchFriendResponse;
|
||||
/**
|
||||
* Get a PMC profile by its session id
|
||||
* @param sessionID Profile id to return
|
||||
|
@ -11,23 +11,36 @@ export interface ILocationBase {
|
||||
Banners: IBanner[];
|
||||
BossLocationSpawn: IBossLocationSpawn[];
|
||||
BotAssault: number;
|
||||
/** Weighting on how likely a bot will be Easy difficulty */
|
||||
BotEasy: number;
|
||||
/** Weighting on how likely a bot will be Hard difficulty */
|
||||
BotHard: number;
|
||||
/** Weighting on how likely a bot will be Impossible difficulty */
|
||||
BotImpossible: number;
|
||||
BotLocationModifier: IBotLocationModifier;
|
||||
BotMarksman: number;
|
||||
/** Maximum Number of bots that are currently alive/loading/delayed */
|
||||
BotMax: number;
|
||||
/** Is not used in 33420 */
|
||||
BotMaxPlayer: number;
|
||||
/** Is not used in 33420 */
|
||||
BotMaxTimePlayer: number;
|
||||
/** Does not even exist in the client in 33420 */
|
||||
BotMaxPvE: number;
|
||||
/** Weighting on how likely a bot will be Normal difficulty */
|
||||
BotNormal: number;
|
||||
/** How many bot slots that need to be open before trying to spawn new bots. */
|
||||
BotSpawnCountStep: number;
|
||||
/** How often to check if bots are spawn-able. In seconds */
|
||||
BotSpawnPeriodCheck: number;
|
||||
/** The bot spawn will toggle on and off in intervals of Off(Min/Max) and On(Min/Max) */
|
||||
BotSpawnTimeOffMax: number;
|
||||
BotSpawnTimeOffMin: number;
|
||||
BotSpawnTimeOnMax: number;
|
||||
BotSpawnTimeOnMin: number;
|
||||
/** How soon bots will be allowed to spawn */
|
||||
BotStart: number;
|
||||
/** After this long bots will no longer spawn */
|
||||
BotStop: number;
|
||||
Description: string;
|
||||
DisabledForScav: boolean;
|
||||
|
@ -33,6 +33,11 @@ export interface IQuest {
|
||||
changeQuestMessageText: string;
|
||||
/** "Pmc" or "Scav" */
|
||||
side: string;
|
||||
acceptanceAndFinishingSource: string;
|
||||
progressSource: string;
|
||||
rankingModes: string[];
|
||||
gameModes: string[];
|
||||
arenaLocations: string[];
|
||||
/** Status of quest to player */
|
||||
sptStatus?: QuestStatus;
|
||||
}
|
||||
@ -148,8 +153,10 @@ export interface IQuestReward {
|
||||
loyaltyLevel?: number;
|
||||
/** Hideout area id */
|
||||
traderId?: string;
|
||||
isEncoded?: boolean;
|
||||
unknown?: boolean;
|
||||
findInRaid?: boolean;
|
||||
gameMode?: string[];
|
||||
/** Game editions whitelisted to get reward */
|
||||
availableInGameEditions?: string[];
|
||||
/** Game editions blacklisted from getting reward */
|
||||
|
@ -3,6 +3,12 @@ export interface IRepeatableQuest extends IQuest {
|
||||
changeCost: IChangeCost[];
|
||||
changeStandingCost: number;
|
||||
sptRepatableGroupName: string;
|
||||
acceptanceAndFinishingSource: string;
|
||||
progressSource: string;
|
||||
rankingModes: string[];
|
||||
gameModes: string[];
|
||||
arenaLocations: string[];
|
||||
questStatus: IRepeatableQuestStatus;
|
||||
}
|
||||
export interface IRepeatableQuestDatabase {
|
||||
templates: IRepeatableTemplates;
|
||||
@ -10,6 +16,14 @@ export interface IRepeatableQuestDatabase {
|
||||
data: IOptions;
|
||||
samples: ISampleQuests[];
|
||||
}
|
||||
export interface IRepeatableQuestStatus {
|
||||
id: string;
|
||||
uid: string;
|
||||
qid: string;
|
||||
startTime: number;
|
||||
status: number;
|
||||
statusTimers: any;
|
||||
}
|
||||
export interface IRepeatableTemplates {
|
||||
Elimination: IQuest;
|
||||
Completion: IQuest;
|
||||
|
@ -8,4 +8,5 @@ export interface Info {
|
||||
Side: string;
|
||||
Level: number;
|
||||
MemberCategory: number;
|
||||
SelectedMemberCategory: number;
|
||||
}
|
||||
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
x
Reference in New Issue
Block a user