2023-03-03 15:23:46 +00:00
import { inject , injectable } from "tsyringe" ;
2024-05-21 17:59:04 +00:00
import { ApplicationContext } from "@spt/context/ApplicationContext" ;
import { ContextVariableType } from "@spt/context/ContextVariableType" ;
import { HideoutHelper } from "@spt/helpers/HideoutHelper" ;
import { HttpServerHelper } from "@spt/helpers/HttpServerHelper" ;
import { ProfileHelper } from "@spt/helpers/ProfileHelper" ;
import { PreSptModLoader } from "@spt/loaders/PreSptModLoader" ;
import { IEmptyRequestData } from "@spt/models/eft/common/IEmptyRequestData" ;
import { ILocation } from "@spt/models/eft/common/ILocation" ;
import { ILooseLoot } from "@spt/models/eft/common/ILooseLoot" ;
import { IPmcData } from "@spt/models/eft/common/IPmcData" ;
import { BodyPartHealth } from "@spt/models/eft/common/tables/IBotBase" ;
import { ICheckVersionResponse } from "@spt/models/eft/game/ICheckVersionResponse" ;
import { ICurrentGroupResponse } from "@spt/models/eft/game/ICurrentGroupResponse" ;
import { IGameConfigResponse } from "@spt/models/eft/game/IGameConfigResponse" ;
import { IGameKeepAliveResponse } from "@spt/models/eft/game/IGameKeepAliveResponse" ;
import { IGameModeRequestData } from "@spt/models/eft/game/IGameModeRequestData" ;
import { ESessionMode } from "@spt/models/eft/game/IGameModeResponse" ;
import { IGetRaidTimeRequest } from "@spt/models/eft/game/IGetRaidTimeRequest" ;
import { IGetRaidTimeResponse } from "@spt/models/eft/game/IGetRaidTimeResponse" ;
import { IServerDetails } from "@spt/models/eft/game/IServerDetails" ;
import { ISptProfile } from "@spt/models/eft/profile/ISptProfile" ;
import { BonusType } from "@spt/models/enums/BonusType" ;
import { ConfigTypes } from "@spt/models/enums/ConfigTypes" ;
import { SkillTypes } from "@spt/models/enums/SkillTypes" ;
import { Traders } from "@spt/models/enums/Traders" ;
import { IBotConfig } from "@spt/models/spt/config/IBotConfig" ;
import { ICoreConfig } from "@spt/models/spt/config/ICoreConfig" ;
import { IHideoutConfig } from "@spt/models/spt/config/IHideoutConfig" ;
import { IHttpConfig } from "@spt/models/spt/config/IHttpConfig" ;
import { ILocationConfig } from "@spt/models/spt/config/ILocationConfig" ;
import { ILootConfig } from "@spt/models/spt/config/ILootConfig" ;
import { IPmcConfig } from "@spt/models/spt/config/IPmcConfig" ;
import { IRagfairConfig } from "@spt/models/spt/config/IRagfairConfig" ;
import { ILogger } from "@spt/models/spt/utils/ILogger" ;
import { ConfigServer } from "@spt/servers/ConfigServer" ;
import { DatabaseServer } from "@spt/servers/DatabaseServer" ;
import { CustomLocationWaveService } from "@spt/services/CustomLocationWaveService" ;
import { GiftService } from "@spt/services/GiftService" ;
import { ItemBaseClassService } from "@spt/services/ItemBaseClassService" ;
import { LocalisationService } from "@spt/services/LocalisationService" ;
import { OpenZoneService } from "@spt/services/OpenZoneService" ;
import { ProfileActivityService } from "@spt/services/ProfileActivityService" ;
import { ProfileFixerService } from "@spt/services/ProfileFixerService" ;
import { RaidTimeAdjustmentService } from "@spt/services/RaidTimeAdjustmentService" ;
import { SeasonalEventService } from "@spt/services/SeasonalEventService" ;
import { ICloner } from "@spt/utils/cloners/ICloner" ;
import { HashUtil } from "@spt/utils/HashUtil" ;
import { RandomUtil } from "@spt/utils/RandomUtil" ;
import { TimeUtil } from "@spt/utils/TimeUtil" ;
2023-03-03 15:23:46 +00:00
@injectable ( )
export class GameController
{
protected httpConfig : IHttpConfig ;
protected coreConfig : ICoreConfig ;
protected locationConfig : ILocationConfig ;
2023-07-31 15:41:10 +01:00
protected ragfairConfig : IRagfairConfig ;
2024-03-30 15:15:06 +00:00
protected hideoutConfig : IHideoutConfig ;
2023-10-10 11:03:20 +00:00
protected pmcConfig : IPmcConfig ;
protected lootConfig : ILootConfig ;
2024-01-24 19:49:42 +00:00
protected botConfig : IBotConfig ;
2023-03-03 15:23:46 +00:00
constructor (
@inject ( "WinstonLogger" ) protected logger : ILogger ,
@inject ( "DatabaseServer" ) protected databaseServer : DatabaseServer ,
@inject ( "TimeUtil" ) protected timeUtil : TimeUtil ,
2023-11-28 11:06:08 +00:00
@inject ( "HashUtil" ) protected hashUtil : HashUtil ,
2024-05-21 17:59:04 +00:00
@inject ( "PreSptModLoader" ) protected preSptModLoader : PreSptModLoader ,
2023-03-03 15:23:46 +00:00
@inject ( "HttpServerHelper" ) protected httpServerHelper : HttpServerHelper ,
2023-08-01 13:31:58 +01:00
@inject ( "RandomUtil" ) protected randomUtil : RandomUtil ,
2023-03-03 15:23:46 +00:00
@inject ( "HideoutHelper" ) protected hideoutHelper : HideoutHelper ,
@inject ( "ProfileHelper" ) protected profileHelper : ProfileHelper ,
@inject ( "ProfileFixerService" ) protected profileFixerService : ProfileFixerService ,
@inject ( "LocalisationService" ) protected localisationService : LocalisationService ,
@inject ( "CustomLocationWaveService" ) protected customLocationWaveService : CustomLocationWaveService ,
@inject ( "OpenZoneService" ) protected openZoneService : OpenZoneService ,
@inject ( "SeasonalEventService" ) protected seasonalEventService : SeasonalEventService ,
2023-08-09 12:04:31 +01:00
@inject ( "ItemBaseClassService" ) protected itemBaseClassService : ItemBaseClassService ,
2023-07-22 23:23:42 +01:00
@inject ( "GiftService" ) protected giftService : GiftService ,
2023-11-29 16:52:13 +00:00
@inject ( "RaidTimeAdjustmentService" ) protected raidTimeAdjustmentService : RaidTimeAdjustmentService ,
2024-04-13 12:46:43 +01:00
@inject ( "ProfileActivityService" ) protected profileActivityService : ProfileActivityService ,
2023-03-03 15:23:46 +00:00
@inject ( "ApplicationContext" ) protected applicationContext : ApplicationContext ,
2023-11-15 20:35:05 -05:00
@inject ( "ConfigServer" ) protected configServer : ConfigServer ,
2024-05-13 17:58:17 +00:00
@inject ( "RecursiveCloner" ) protected cloner : ICloner ,
2023-03-03 15:23:46 +00:00
)
{
this . httpConfig = this . configServer . getConfig ( ConfigTypes . HTTP ) ;
this . coreConfig = this . configServer . getConfig ( ConfigTypes . CORE ) ;
this . locationConfig = this . configServer . getConfig ( ConfigTypes . LOCATION ) ;
2023-07-31 15:41:10 +01:00
this . ragfairConfig = this . configServer . getConfig ( ConfigTypes . RAGFAIR ) ;
2024-03-30 15:15:06 +00:00
this . hideoutConfig = this . configServer . getConfig ( ConfigTypes . HIDEOUT ) ;
2023-10-10 11:03:20 +00:00
this . pmcConfig = this . configServer . getConfig ( ConfigTypes . PMC ) ;
this . lootConfig = this . configServer . getConfig ( ConfigTypes . LOOT ) ;
2024-01-24 19:49:42 +00:00
this . botConfig = this . configServer . getConfig ( ConfigTypes . BOT ) ;
2023-10-10 11:03:20 +00:00
}
public load ( ) : void
{
2023-11-10 16:49:29 -05:00
// Regenerate base cache now mods are loaded and game is starting
// Mods that add items and use the baseClass service generate the cache including their items, the next mod that
// add items gets left out,causing warnings
2023-10-10 11:03:20 +00:00
this . itemBaseClassService . hydrateItemBaseClassCache ( ) ;
this . addCustomLooseLootPositions ( ) ;
2023-03-03 15:23:46 +00:00
}
2023-07-14 12:55:32 +01:00
/ * *
* Handle client / game / start
* /
2023-03-03 15:23:46 +00:00
public gameStart ( _url : string , _info : IEmptyRequestData , sessionID : string , startTimeStampMS : number ) : void
{
2024-01-23 10:14:37 +00:00
// Store client start time in app context
this . applicationContext . addValue ( ContextVariableType . CLIENT_START_TIMESTAMP , startTimeStampMS ) ;
2024-04-13 12:46:43 +01:00
this . profileActivityService . setActivityTimestamp ( sessionID ) ;
2023-07-15 10:53:08 +01:00
if ( this . coreConfig . fixes . fixShotgunDispersion )
{
this . fixShotgunDispersions ( ) ;
}
if ( this . locationConfig . addOpenZonesToAllMaps )
{
this . openZoneService . applyZoneChangesToAllMaps ( ) ;
}
2023-04-08 22:17:04 +01:00
2023-07-15 10:53:08 +01:00
if ( this . locationConfig . addCustomBotWavesToMaps )
{
this . customLocationWaveService . applyWaveChangesToAllMaps ( ) ;
}
2023-03-03 15:23:46 +00:00
2023-07-17 14:40:54 +01:00
if ( this . locationConfig . enableBotTypeLimits )
{
this . adjustMapBotLimits ( ) ;
}
2023-10-10 11:03:20 +00:00
this . adjustLooseLootSpawnProbabilities ( ) ;
2023-11-07 20:00:02 +00:00
this . checkTraderRepairValuesExist ( ) ;
2024-02-02 13:54:07 -05:00
this . adjustLocationBotValues ( ) ;
2024-01-24 19:49:42 +00:00
2023-11-10 16:49:29 -05:00
// repeatableQuests are stored by in profile.Quests due to the responses of the client (e.g. Quests in
// offraidData). Since we don't want to clutter the Quests list, we need to remove all completed (failed or
// successful) repeatable quests. We also have to remove the Counters from the repeatableQuests
2023-03-03 15:23:46 +00:00
if ( sessionID )
{
const fullProfile = this . profileHelper . getFullProfile ( sessionID ) ;
2023-11-25 13:26:11 +00:00
if ( fullProfile . info . wipe )
{
// Don't bother doing any fixes, we're resetting profile
return ;
}
2023-03-03 15:23:46 +00:00
const pmcProfile = fullProfile . characters . pmc ;
2023-07-15 11:03:54 +01:00
this . logger . debug ( ` Started game with sessionId: ${ sessionID } ${ pmcProfile . Info ? . Nickname } ` ) ;
2023-05-30 13:58:02 +01:00
2024-05-21 19:47:01 +01:00
// Migrate aki object data into spt for 3.9.0 release
if ( ( fullProfile as any ) . aki )
{
fullProfile . spt = this . cloner . clone ( ( fullProfile as any ) . aki ) ;
delete ( fullProfile as any ) . aki ;
}
2023-11-28 11:06:08 +00:00
if ( this . coreConfig . fixes . fixProfileBreakingInventoryItemIssues )
{
2024-02-02 13:54:07 -05:00
this . profileFixerService . fixProfileBreakingInventoryItemIssues ( pmcProfile ) ;
2023-11-28 11:06:08 +00:00
}
2023-03-03 15:23:46 +00:00
if ( pmcProfile . Health )
{
this . updateProfileHealthValues ( pmcProfile ) ;
}
2024-02-03 19:42:49 +00:00
2023-03-03 15:23:46 +00:00
if ( this . locationConfig . fixEmptyBotWavesSettings . enabled )
{
this . fixBrokenOfflineMapWaves ( ) ;
}
if ( this . locationConfig . rogueLighthouseSpawnTimeSettings . enabled )
{
this . fixRoguesSpawningInstantlyOnLighthouse ( ) ;
}
if ( this . locationConfig . splitWaveIntoSingleSpawnsSettings . enabled )
{
this . splitBotWavesIntoSingleWaves ( ) ;
}
this . profileFixerService . removeLegacyScavCaseProductionCrafts ( pmcProfile ) ;
this . profileFixerService . addMissingHideoutAreasToProfile ( fullProfile ) ;
2023-10-10 11:03:20 +00:00
if ( pmcProfile . Inventory )
{
// MUST occur prior to `profileFixerService.checkForAndFixPmcProfileIssues()`
this . profileFixerService . fixIncorrectAidValue ( fullProfile ) ;
this . profileFixerService . migrateStatsToNewStructure ( fullProfile ) ;
2023-11-15 20:35:05 -05:00
2023-10-10 11:03:20 +00:00
this . sendPraporGiftsToNewProfiles ( pmcProfile ) ;
this . profileFixerService . checkForOrphanedModdedItems ( sessionID , fullProfile ) ;
}
2023-03-03 15:23:46 +00:00
this . profileFixerService . checkForAndFixPmcProfileIssues ( pmcProfile ) ;
2024-05-21 17:59:04 +00:00
this . profileFixerService . addMissingSptVersionTagToProfile ( fullProfile ) ;
2023-03-03 15:23:46 +00:00
if ( pmcProfile . Hideout )
{
this . profileFixerService . addMissingHideoutBonusesToProfile ( pmcProfile ) ;
this . profileFixerService . addMissingUpgradesPropertyToHideout ( pmcProfile ) ;
this . hideoutHelper . setHideoutImprovementsToCompleted ( pmcProfile ) ;
this . hideoutHelper . unlockHideoutWallInProfile ( pmcProfile ) ;
2023-10-10 11:03:20 +00:00
this . profileFixerService . addMissingIdsToBonuses ( pmcProfile ) ;
2024-04-09 07:48:18 +00:00
this . profileFixerService . fixBitcoinProductionTime ( pmcProfile ) ;
2023-03-03 15:23:46 +00:00
}
2023-11-15 20:35:05 -05:00
2023-03-03 15:23:46 +00:00
this . logProfileDetails ( fullProfile ) ;
this . adjustLabsRaiderSpawnRate ( ) ;
2024-04-06 20:25:57 +01:00
this . adjustHideoutCraftTimes ( ) ;
this . adjustHideoutBuildTimes ( ) ;
2023-03-03 15:23:46 +00:00
this . removePraporTestMessage ( ) ;
this . saveActiveModsToProfile ( fullProfile ) ;
2023-07-09 11:33:43 +01:00
this . validateQuestAssortUnlocksExist ( ) ;
2023-03-03 15:23:46 +00:00
if ( pmcProfile . Info )
{
this . addPlayerToPMCNames ( pmcProfile ) ;
2023-08-01 13:31:58 +01:00
2023-08-01 23:16:06 +01:00
this . checkForAndRemoveUndefinedDialogs ( fullProfile ) ;
2023-03-03 15:23:46 +00:00
}
if ( this . seasonalEventService . isAutomaticEventDetectionEnabled ( ) )
{
2023-10-14 16:52:48 +01:00
this . seasonalEventService . enableSeasonalEvents ( sessionID ) ;
2023-03-03 15:23:46 +00:00
}
2023-03-10 11:26:59 +00:00
if ( pmcProfile ? . Skills ? . Common )
{
this . warnOnActiveBotReloadSkill ( pmcProfile ) ;
}
2023-07-31 15:41:10 +01:00
// Flea bsg blacklist is off
if ( ! this . ragfairConfig . dynamic . blacklist . enableBsgList )
{
this . flagAllItemsInDbAsSellableOnFlea ( ) ;
}
2023-03-10 11:26:59 +00:00
}
}
2023-07-14 12:55:32 +01:00
2024-04-06 20:25:57 +01:00
protected adjustHideoutCraftTimes ( ) : void
{
const craftTimeOverrideSeconds = this . hideoutConfig . overrideCraftTimeSeconds ;
if ( craftTimeOverrideSeconds === - 1 )
{
return ;
}
for ( const craft of this . databaseServer . getTables ( ) . hideout . production )
{
// Only adjust crafts ABOVE the override
if ( craft . productionTime > craftTimeOverrideSeconds )
{
craft . productionTime = craftTimeOverrideSeconds ;
}
}
}
protected adjustHideoutBuildTimes ( ) : void
{
const craftTimeOverrideSeconds = this . hideoutConfig . overrideBuildTimeSeconds ;
if ( craftTimeOverrideSeconds === - 1 )
{
return ;
}
for ( const area of this . databaseServer . getTables ( ) . hideout . areas )
{
for ( const stageKey of Object . keys ( area . stages ) )
{
const stage = area . stages [ stageKey ] ;
// Only adjust crafts ABOVE the override
if ( stage . constructionTime > craftTimeOverrideSeconds )
{
stage . constructionTime = craftTimeOverrideSeconds ;
}
}
}
}
2024-01-24 19:49:42 +00:00
protected adjustLocationBotValues ( ) : void
{
const mapsDb = this . databaseServer . getTables ( ) . locations ;
for ( const locationKey in this . botConfig . maxBotCap )
{
2024-03-20 09:43:51 +00:00
const map : ILocation = mapsDb [ locationKey ] ;
2024-01-24 19:49:42 +00:00
if ( ! map )
{
continue ;
}
map . base . BotMax = this . botConfig . maxBotCap [ locationKey ] ;
// make values no larger than 30 secs
map . base . BotStart = Math . min ( map . base . BotStart , 30 ) ;
}
}
2023-11-07 20:00:02 +00:00
/ * *
* Out of date / incorrectly made trader mods forget this data
* /
protected checkTraderRepairValuesExist ( ) : void
{
for ( const traderKey in this . databaseServer . getTables ( ) . traders )
{
const trader = this . databaseServer . getTables ( ) . traders [ traderKey ] ;
if ( ! trader ? . base ? . repair )
{
2024-05-21 14:28:52 +01:00
this . logger . warning ( this . localisationService . getText ( "trader-missing_repair_property_using_default" ,
{ traderId : trader.base._id , nickname : trader.base.nickname } ) ) ;
2024-05-13 17:58:17 +00:00
trader . base . repair = this . cloner . clone ( this . databaseServer . getTables ( ) . traders . ragfair . base . repair ) ;
2023-11-07 20:00:02 +00:00
return ;
}
2023-11-10 19:00:04 +00:00
if ( trader . base . repair ? . quality === undefined )
2023-11-07 20:00:02 +00:00
{
2024-05-21 14:28:52 +01:00
this . logger . warning ( this . localisationService . getText ( "trader-missing_repair_quality_property_using_default" ,
{ traderId : trader.base._id , nickname : trader.base.nickname } ) ) ;
2024-05-13 17:58:17 +00:00
trader . base . repair . quality = this . cloner . clone (
2023-11-10 16:49:29 -05:00
this . databaseServer . getTables ( ) . traders . ragfair . base . repair . quality ,
) ;
2023-11-10 10:31:22 +00:00
trader . base . repair . quality = this . databaseServer . getTables ( ) . traders . ragfair . base . repair . quality ;
2023-11-07 20:00:02 +00:00
}
}
}
2023-10-10 11:03:20 +00:00
protected addCustomLooseLootPositions ( ) : void
{
const looseLootPositionsToAdd = this . lootConfig . looseLoot ;
for ( const mapId in looseLootPositionsToAdd )
{
if ( ! mapId )
{
2024-05-21 14:28:52 +01:00
this . logger . warning ( this . localisationService . getText ( "location-unable_to_add_custom_loot_position" , mapId ) ) ;
2023-10-10 11:03:20 +00:00
continue ;
}
2024-05-21 14:28:52 +01:00
2023-10-10 11:03:20 +00:00
const mapLooseLoot : ILooseLoot = this . databaseServer . getTables ( ) . locations [ mapId ] ? . looseLoot ;
if ( ! mapLooseLoot )
{
2024-05-21 14:28:52 +01:00
this . logger . warning ( this . localisationService . getText ( "location-map_has_no_loose_loot_data" , mapId ) ) ;
2023-10-10 11:03:20 +00:00
continue ;
}
2024-05-21 14:28:52 +01:00
2023-10-10 11:03:20 +00:00
const positionsToAdd = looseLootPositionsToAdd [ mapId ] ;
for ( const positionToAdd of positionsToAdd )
{
// Exists already, add new items to existing positions pool
2024-05-17 15:32:41 -04:00
const existingLootPosition = mapLooseLoot . spawnpoints . find (
( x ) = > x . template . Id === positionToAdd . template . Id ,
2023-11-15 20:35:05 -05:00
) ;
2024-05-21 14:28:52 +01:00
2023-10-10 11:03:20 +00:00
if ( existingLootPosition )
{
existingLootPosition . template . Items . push ( . . . positionToAdd . template . Items ) ;
existingLootPosition . itemDistribution . push ( . . . positionToAdd . itemDistribution ) ;
continue ;
}
2023-11-10 16:49:29 -05:00
// New position, add entire object
2023-10-10 11:03:20 +00:00
mapLooseLoot . spawnpoints . push ( positionToAdd ) ;
}
}
}
protected adjustLooseLootSpawnProbabilities ( ) : void
{
const adjustments = this . lootConfig . looseLootSpawnPointAdjustments ;
for ( const mapId in adjustments )
{
const mapLooseLootData : ILooseLoot = this . databaseServer . getTables ( ) . locations [ mapId ] ? . looseLoot ;
if ( ! mapLooseLootData )
{
2024-05-21 14:28:52 +01:00
this . logger . warning ( this . localisationService . getText ( "location-map_has_no_loose_loot_data" , mapId ) ) ;
2023-10-10 11:03:20 +00:00
continue ;
}
const mapLootAdjustmentsDict = adjustments [ mapId ] ;
for ( const lootKey in mapLootAdjustmentsDict )
{
2024-05-21 14:28:52 +01:00
const lootPostionToAdjust = mapLooseLootData . spawnpoints
. find ( ( spawnPoint ) = > spawnPoint . template . Id === lootKey ) ;
2023-10-10 11:03:20 +00:00
if ( ! lootPostionToAdjust )
{
2024-05-21 14:28:52 +01:00
this . logger . warning ( this . localisationService . getText ( "location-unable_to_adjust_loot_position_on_map" , { lootKey : lootKey , mapId : mapId } ) ) ;
2023-10-10 11:03:20 +00:00
continue ;
}
lootPostionToAdjust . probability = mapLootAdjustmentsDict [ lootKey ] ;
}
}
}
2023-11-15 20:35:05 -05:00
2023-07-18 17:16:23 +01:00
/** Apply custom limits on bot types as defined in configs/location.json/botTypeLimits */
2023-07-17 14:40:54 +01:00
protected adjustMapBotLimits ( ) : void
{
const mapsDb = this . databaseServer . getTables ( ) . locations ;
if ( ! this . locationConfig . botTypeLimits )
{
return ;
}
for ( const mapId in this . locationConfig . botTypeLimits )
{
2024-03-20 09:43:51 +00:00
const map : ILocation = mapsDb [ mapId ] ;
2023-07-17 14:40:54 +01:00
if ( ! map )
{
2023-11-15 20:35:05 -05:00
this . logger . warning (
this . localisationService . getText ( "bot-unable_to_edit_limits_of_unknown_map" , mapId ) ,
) ;
2023-07-17 14:40:54 +01:00
}
for ( const botToLimit of this . locationConfig . botTypeLimits [ mapId ] )
{
2024-05-17 15:32:41 -04:00
const index = map . base . MinMaxBots . findIndex ( ( x ) = > x . WildSpawnType === botToLimit . type ) ;
2023-07-17 14:40:54 +01:00
if ( index !== - 1 )
{
// Existing bot type found in MinMaxBots array, edit
const limitObjectToUpdate = map . base . MinMaxBots [ index ] ;
limitObjectToUpdate . min = botToLimit . min ;
limitObjectToUpdate . max = botToLimit . max ;
}
else
{
2023-11-10 16:49:29 -05:00
// Bot type not found, add new object
2023-11-15 20:35:05 -05:00
map . base . MinMaxBots . push ( {
// Bot type not found, add new object
WildSpawnType : botToLimit.type ,
min : botToLimit.min ,
max : botToLimit.max ,
} ) ;
2023-07-17 14:40:54 +01:00
}
}
}
}
2023-07-14 12:55:32 +01:00
/ * *
* Handle client / game / config
* /
public getGameConfig ( sessionID : string ) : IGameConfigResponse
2023-07-09 11:33:43 +01:00
{
2023-07-24 16:38:28 +01:00
const profile = this . profileHelper . getPmcProfile ( sessionID ) ;
2024-05-07 23:57:08 -04:00
const gameTime
2024-05-17 15:32:41 -04:00
= profile . Stats ? . Eft . OverallCounters . Items ? . find (
( counter ) = > counter . Key . includes ( "LifeTime" ) && counter . Key . includes ( "Pmc" ) ,
2024-02-02 13:54:07 -05:00
) ? . Value ? ? 0 ;
2023-07-24 16:38:28 +01:00
2023-07-14 12:55:32 +01:00
const config : IGameConfigResponse = {
languages : this.databaseServer.getTables ( ) . locales . languages ,
ndaFree : false ,
reportAvailable : false ,
twitchEventMember : false ,
lang : "en" ,
2023-10-10 11:03:20 +00:00
aid : profile.aid ,
2023-07-14 12:55:32 +01:00
taxonomy : 6 ,
2023-12-27 22:01:30 +00:00
activeProfileId : sessionID ,
2023-07-14 12:55:32 +01:00
backend : {
Lobby : this.httpServerHelper.getBackendUrl ( ) ,
Trading : this.httpServerHelper.getBackendUrl ( ) ,
Messaging : this.httpServerHelper.getBackendUrl ( ) ,
Main : this.httpServerHelper.getBackendUrl ( ) ,
2023-11-15 20:35:05 -05:00
RagFair : this.httpServerHelper.getBackendUrl ( ) ,
2023-07-14 12:55:32 +01:00
} ,
2023-10-10 11:03:20 +00:00
useProtobuf : false ,
2023-07-14 12:55:32 +01:00
utc_time : new Date ( ) . getTime ( ) / 1000 ,
2023-12-21 22:12:55 +00:00
totalInGame : gameTime ,
2023-07-14 12:55:32 +01:00
} ;
2023-07-09 11:33:43 +01:00
2023-07-14 12:55:32 +01:00
return config ;
}
2023-07-09 11:33:43 +01:00
2024-04-26 07:37:42 +00:00
/ * *
* Handle client / game / mode
* /
public getGameMode ( sessionID : string , info : IGameModeRequestData ) : any
{
return { gameMode : ESessionMode.REGULAR , backendUrl : this.httpServerHelper.getBackendUrl ( ) } ;
}
2023-07-14 12:55:32 +01:00
/ * *
* Handle client / server / list
* /
public getServer ( sessionId : string ) : IServerDetails [ ]
{
2024-04-17 07:39:11 +00:00
return [ { ip : this.httpConfig.backendIp , port : Number.parseInt ( this . httpConfig . backendPort ) } ] ;
2023-07-14 12:55:32 +01:00
}
/ * *
* Handle client / match / group / current
* /
public getCurrentGroup ( sessionId : string ) : ICurrentGroupResponse
{
2023-11-15 20:35:05 -05:00
return { squad : [ ] } ;
2023-07-14 12:55:32 +01:00
}
/ * *
* Handle client / checkVersion
* /
public getValidGameVersion ( sessionId : string ) : ICheckVersionResponse
{
2023-11-15 20:35:05 -05:00
return { isvalid : true , latestVersion : this.coreConfig.compatibleTarkovVersion } ;
2023-07-09 11:33:43 +01:00
}
2023-03-10 11:26:59 +00:00
2023-07-15 10:57:39 +01:00
/ * *
* Handle client / game / keepalive
* /
public getKeepAlive ( sessionId : string ) : IGameKeepAliveResponse
{
2024-04-13 12:46:43 +01:00
this . profileActivityService . setActivityTimestamp ( sessionId ) ;
2023-11-13 12:38:16 -05:00
return { msg : "OK" , utc_time : new Date ( ) . getTime ( ) / 1000 } ;
2023-07-15 10:57:39 +01:00
}
2023-11-26 21:11:03 +00:00
/ * *
2023-11-28 11:06:08 +00:00
* Handle singleplayer / settings / getRaidTime
2023-11-26 21:11:03 +00:00
* /
public getRaidTime ( sessionId : string , request : IGetRaidTimeRequest ) : IGetRaidTimeResponse
{
2024-03-30 15:15:06 +00:00
// Set interval times to in-raid value
2024-03-17 12:27:24 +00:00
this . ragfairConfig . runIntervalSeconds = this . ragfairConfig . runIntervalValues . inRaid ;
2024-03-30 15:15:06 +00:00
this . hideoutConfig . runIntervalSeconds = this . hideoutConfig . runIntervalValues . inRaid ;
2023-11-29 16:52:13 +00:00
return this . raidTimeAdjustmentService . getRaidAdjustments ( sessionId , request ) ;
2023-11-27 15:02:35 +00:00
}
2023-04-08 22:17:04 +01:00
/ * *
* BSG have two values for shotgun dispersion , we make sure both have the same value
* /
protected fixShotgunDispersions ( ) : void
{
const itemDb = this . databaseServer . getTables ( ) . templates . items ;
// Saiga 12ga
// Toz 106
// Remington 870
const shotguns = [ "576165642459773c7a400233" , "5a38e6bac4a2826c6e06d79b" , "5a7828548dc32e5a9c28b516" ] ;
for ( const shotgunId of shotguns )
{
if ( itemDb [ shotgunId ] . _props . ShotgunDispersion )
{
itemDb [ shotgunId ] . _props . shotgunDispersion = itemDb [ shotgunId ] . _props . ShotgunDispersion ;
}
}
}
2023-03-10 11:26:59 +00:00
/ * *
* Players set botReload to a high value and don ' t expect the crazy fast reload speeds , give them a warn about it
* @param pmcProfile Player profile
* /
protected warnOnActiveBotReloadSkill ( pmcProfile : IPmcData ) : void
{
2023-11-07 15:17:38 +00:00
const botReloadSkill = this . profileHelper . getSkillFromProfile ( pmcProfile , SkillTypes . BOT_RELOAD ) ;
2023-03-10 11:26:59 +00:00
if ( botReloadSkill ? . Progress > 0 )
{
this . logger . warning ( this . localisationService . getText ( "server_start_player_active_botreload_skill" ) ) ;
2023-03-03 15:23:46 +00:00
}
}
2023-07-31 15:41:10 +01:00
protected flagAllItemsInDbAsSellableOnFlea ( ) : void
{
const dbItems = Object . values ( this . databaseServer . getTables ( ) . templates . items ) ;
for ( const item of dbItems )
{
if ( item . _type === "Item" && ! item . _props ? . CanSellOnRagfair )
{
item . _props . CanSellOnRagfair = true ;
}
}
}
2023-03-03 15:23:46 +00:00
/ * *
* When player logs in , iterate over all active effects and reduce timer
2024-02-03 19:47:39 +00:00
* @param pmcProfile Profile to adjust values for
2023-03-03 15:23:46 +00:00
* /
protected updateProfileHealthValues ( pmcProfile : IPmcData ) : void
{
const healthLastUpdated = pmcProfile . Health . UpdateTime ;
const currentTimeStamp = this . timeUtil . getTimestamp ( ) ;
const diffSeconds = currentTimeStamp - healthLastUpdated ;
2024-02-03 19:47:39 +00:00
// Last update is in past
2023-03-03 15:23:46 +00:00
if ( healthLastUpdated < currentTimeStamp )
{
// Base values
let energyRegenPerHour = 60 ;
let hydrationRegenPerHour = 60 ;
let hpRegenPerHour = 456.6 ;
// Set new values, whatever is smallest
2024-05-17 15:32:41 -04:00
energyRegenPerHour += pmcProfile . Bonuses . filter (
( bonus ) = > bonus . type === BonusType . ENERGY_REGENERATION ,
2024-02-03 19:45:42 +00:00
) . reduce ( ( sum , curr ) = > sum + curr . value , 0 ) ;
2024-05-17 15:32:41 -04:00
hydrationRegenPerHour += pmcProfile . Bonuses . filter (
( bonus ) = > bonus . type === BonusType . HYDRATION_REGENERATION ,
) . reduce ( ( sum , curr ) = > sum + curr . value , 0 ) ;
hpRegenPerHour += pmcProfile . Bonuses . filter ( ( bonus ) = > bonus . type === BonusType . HEALTH_REGENERATION ) . reduce (
2023-11-15 20:35:05 -05:00
( sum , curr ) = > sum + curr . value ,
0 ,
) ;
2023-03-03 15:23:46 +00:00
2024-02-03 19:45:42 +00:00
// Player has energy deficit
2023-03-03 15:23:46 +00:00
if ( pmcProfile . Health . Energy . Current !== pmcProfile . Health . Energy . Maximum )
{
// Set new value, whatever is smallest
2023-11-15 20:35:05 -05:00
pmcProfile . Health . Energy . Current += Math . round ( energyRegenPerHour * ( diffSeconds / 3600 ) ) ;
2023-03-03 15:23:46 +00:00
if ( pmcProfile . Health . Energy . Current > pmcProfile . Health . Energy . Maximum )
{
pmcProfile . Health . Energy . Current = pmcProfile . Health . Energy . Maximum ;
}
}
2024-02-03 19:47:39 +00:00
// Player has hydration deficit
2023-03-03 15:23:46 +00:00
if ( pmcProfile . Health . Hydration . Current !== pmcProfile . Health . Hydration . Maximum )
{
2023-11-15 20:35:05 -05:00
pmcProfile . Health . Hydration . Current += Math . round ( hydrationRegenPerHour * ( diffSeconds / 3600 ) ) ;
2023-03-03 15:23:46 +00:00
if ( pmcProfile . Health . Hydration . Current > pmcProfile . Health . Hydration . Maximum )
{
pmcProfile . Health . Hydration . Current = pmcProfile . Health . Hydration . Maximum ;
}
}
// Check all body parts
for ( const bodyPartKey in pmcProfile . Health . BodyParts )
{
const bodyPart = pmcProfile . Health . BodyParts [ bodyPartKey ] as BodyPartHealth ;
2023-11-15 20:35:05 -05:00
2023-03-03 15:23:46 +00:00
// Check part hp
if ( bodyPart . Health . Current < bodyPart . Health . Maximum )
{
2023-11-15 20:35:05 -05:00
bodyPart . Health . Current += Math . round ( hpRegenPerHour * ( diffSeconds / 3600 ) ) ;
2023-03-03 15:23:46 +00:00
}
if ( bodyPart . Health . Current > bodyPart . Health . Maximum )
{
bodyPart . Health . Current = bodyPart . Health . Maximum ;
}
2023-11-15 20:35:05 -05:00
2023-03-03 15:23:46 +00:00
// Look for effects
if ( Object . keys ( bodyPart . Effects ? ? { } ) . length > 0 )
{
// Decrement effect time value by difference between current time and time health was last updated
for ( const effectKey in bodyPart . Effects )
{
2024-02-03 19:47:39 +00:00
// remove effects below 1, .e.g. bleeds at -1
2023-03-03 15:23:46 +00:00
if ( bodyPart . Effects [ effectKey ] . Time < 1 )
{
2024-02-03 19:45:42 +00:00
// More than 30 mins has passed
if ( diffSeconds > 1800 )
{
delete bodyPart . Effects [ effectKey ] ;
}
2023-03-03 15:23:46 +00:00
continue ;
}
bodyPart . Effects [ effectKey ] . Time -= diffSeconds ;
if ( bodyPart . Effects [ effectKey ] . Time < 1 )
{
// effect time was sub 1, set floor it can be
bodyPart . Effects [ effectKey ] . Time = 1 ;
}
}
}
}
pmcProfile . Health . UpdateTime = currentTimeStamp ;
}
}
/ * *
* Waves with an identical min / max values spawn nothing , the number of bots that spawn is the difference between min and max
* /
protected fixBrokenOfflineMapWaves ( ) : void
{
for ( const locationKey in this . databaseServer . getTables ( ) . locations )
{
// Skip ignored maps
if ( this . locationConfig . fixEmptyBotWavesSettings . ignoreMaps . includes ( locationKey ) )
{
continue ;
}
// Loop over all of the locations waves and look for waves with identical min and max slots
2024-03-20 09:43:51 +00:00
const location : ILocation = this . databaseServer . getTables ( ) . locations [ locationKey ] ;
2023-05-27 19:02:30 +01:00
if ( ! location . base )
{
2023-11-15 20:35:05 -05:00
this . logger . warning (
this . localisationService . getText ( "location-unable_to_fix_broken_waves_missing_base" , locationKey ) ,
) ;
2023-05-27 19:02:30 +01:00
continue ;
}
2023-05-27 19:03:52 +01:00
for ( const wave of location . base . waves ? ? [ ] )
2023-03-03 15:23:46 +00:00
{
2024-05-07 23:57:08 -04:00
if ( wave . slots_max - wave . slots_min === 0 )
2023-03-03 15:23:46 +00:00
{
2023-11-15 20:35:05 -05:00
this . logger . debug (
` Fixed ${ wave . WildSpawnType } Spawn: ${ locationKey } wave: ${ wave . number } of type: ${ wave . WildSpawnType } in zone: ${ wave . SpawnPoints } with Max Slots of ${ wave . slots_max } ` ,
) ;
2023-03-03 15:23:46 +00:00
wave . slots_max ++ ;
}
}
}
}
/ * *
* Make Rogues spawn later to allow for scavs to spawn first instead of rogues filling up all spawn positions
* /
protected fixRoguesSpawningInstantlyOnLighthouse ( ) : void
{
2023-11-13 11:51:02 -05:00
const lighthouse = this . databaseServer . getTables ( ) . locations . lighthouse . base ;
2023-03-03 15:23:46 +00:00
for ( const wave of lighthouse . BossLocationSpawn )
{
// Find Rogues that spawn instantly
if ( wave . BossName === "exUsec" && wave . Time === - 1 )
{
wave . Time = this . locationConfig . rogueLighthouseSpawnTimeSettings . waitTimeSeconds ;
}
}
}
2023-07-25 10:36:23 +01:00
/ * *
* Send starting gifts to profile after x days
* @param pmcProfile Profile to add gifts to
* /
2023-07-22 23:23:42 +01:00
protected sendPraporGiftsToNewProfiles ( pmcProfile : IPmcData ) : void
{
const timeStampProfileCreated = pmcProfile . Info . RegistrationDate ;
const oneDaySeconds = this . timeUtil . getHoursAsSeconds ( 24 ) ;
const currentTimeStamp = this . timeUtil . getTimestamp ( ) ;
2023-07-25 11:17:54 +01:00
// One day post-profile creation
2024-05-17 15:32:41 -04:00
if ( currentTimeStamp > timeStampProfileCreated + oneDaySeconds )
2023-07-22 23:23:42 +01:00
{
2023-10-10 11:03:20 +00:00
this . giftService . sendPraporStartingGift ( pmcProfile . sessionId , 1 ) ;
2023-07-22 23:23:42 +01:00
}
2023-07-25 11:17:54 +01:00
// Two day post-profile creation
2024-05-17 15:32:41 -04:00
if ( currentTimeStamp > timeStampProfileCreated + oneDaySeconds * 2 )
2023-07-22 23:23:42 +01:00
{
2023-10-10 11:03:20 +00:00
this . giftService . sendPraporStartingGift ( pmcProfile . sessionId , 2 ) ;
2023-07-22 23:23:42 +01:00
}
}
2023-03-03 15:23:46 +00:00
/ * *
2023-11-10 16:49:29 -05:00
* Find and split waves with large numbers of bots into smaller waves - BSG appears to reduce the size of these
* waves to one bot when they ' re waiting to spawn for too long
2023-03-03 15:23:46 +00:00
* /
protected splitBotWavesIntoSingleWaves ( ) : void
{
for ( const locationKey in this . databaseServer . getTables ( ) . locations )
{
if ( this . locationConfig . splitWaveIntoSingleSpawnsSettings . ignoreMaps . includes ( locationKey ) )
{
continue ;
}
// Iterate over all maps
2024-03-20 09:43:51 +00:00
const location : ILocation = this . databaseServer . getTables ( ) . locations [ locationKey ] ;
2023-03-03 15:23:46 +00:00
for ( const wave of location . base . waves )
{
// Wave has size that makes it candidate for splitting
2023-11-15 20:35:05 -05:00
if (
wave . slots_max - wave . slots_min
2024-05-07 23:57:08 -04:00
>= this . locationConfig . splitWaveIntoSingleSpawnsSettings . waveSizeThreshold
2023-11-15 20:35:05 -05:00
)
2023-03-03 15:23:46 +00:00
{
// Get count of bots to be spawned in wave
const waveSize = wave . slots_max - wave . slots_min ;
2023-11-15 20:35:05 -05:00
2023-03-03 15:23:46 +00:00
// Update wave to spawn single bot
wave . slots_min = 1 ;
wave . slots_max = 2 ;
2023-11-15 20:35:05 -05:00
2023-03-03 15:23:46 +00:00
// Get index of wave
const indexOfWaveToSplit = location . base . waves . indexOf ( wave ) ;
2023-11-15 20:35:05 -05:00
this . logger . debug (
` Splitting map: ${ location . base . Id } wave: ${ indexOfWaveToSplit } with ${ waveSize } bots ` ,
) ;
2023-03-03 15:23:46 +00:00
// Add new waves to fill gap from bots we removed in above wave
let wavesAddedCount = 0 ;
for ( let index = indexOfWaveToSplit + 1 ; index < indexOfWaveToSplit + waveSize ; index ++ )
{
// Clone wave ready to insert into array
2024-05-13 17:58:17 +00:00
const waveToAddClone = this . cloner . clone ( wave ) ;
2023-03-03 15:23:46 +00:00
// Some waves have value of 0 for some reason, preserve
2024-02-05 14:43:46 +00:00
if ( waveToAddClone . number !== 0 )
2023-03-03 15:23:46 +00:00
{
// Update wave number to new location in array
2024-02-05 14:43:46 +00:00
waveToAddClone . number = index ;
2023-03-03 15:23:46 +00:00
}
2023-11-10 16:49:29 -05:00
// Place wave into array in just-edited position + 1
2024-02-05 14:43:46 +00:00
location . base . waves . splice ( index , 0 , waveToAddClone ) ;
2023-03-03 15:23:46 +00:00
wavesAddedCount ++ ;
}
2023-11-10 16:49:29 -05:00
// Update subsequent wave number property to accommodate the new waves
2023-11-15 20:35:05 -05:00
for (
let index = indexOfWaveToSplit + wavesAddedCount + 1 ;
index < location . base . waves . length ;
index ++
)
2023-03-03 15:23:46 +00:00
{
// Some waves have value of 0, leave them as-is
if ( location . base . waves [ index ] . number !== 0 )
{
location . base . waves [ index ] . number += wavesAddedCount ;
}
}
}
}
}
}
/ * *
* Get a list of installed mods and save their details to the profile being used
* @param fullProfile Profile to add mod details to
* /
2024-05-21 17:59:04 +00:00
protected saveActiveModsToProfile ( fullProfile : ISptProfile ) : void
2023-03-03 15:23:46 +00:00
{
// Add empty mod array if undefined
2024-05-21 17:59:04 +00:00
if ( ! fullProfile . spt . mods )
2023-03-03 15:23:46 +00:00
{
2024-05-21 17:59:04 +00:00
fullProfile . spt . mods = [ ] ;
2023-03-03 15:23:46 +00:00
}
// Get active mods
2024-05-21 17:59:04 +00:00
const activeMods = this . preSptModLoader . getImportedModDetails ( ) ;
2023-03-03 15:23:46 +00:00
for ( const modKey in activeMods )
{
const modDetails = activeMods [ modKey ] ;
2023-11-15 20:35:05 -05:00
if (
2024-05-21 17:59:04 +00:00
fullProfile . spt . mods . some (
2024-05-17 15:32:41 -04:00
( x ) = >
x . author === modDetails . author
&& x . name === modDetails . name
&& x . version === modDetails . version ,
2023-11-15 20:35:05 -05:00
)
)
2023-03-03 15:23:46 +00:00
{
// Exists already, skip
continue ;
}
2024-05-21 17:59:04 +00:00
fullProfile . spt . mods . push ( {
2023-03-03 15:23:46 +00:00
author : modDetails.author ,
dateAdded : Date.now ( ) ,
name : modDetails.name ,
2023-11-15 20:35:05 -05:00
version : modDetails.version ,
2024-02-02 13:54:07 -05:00
url : modDetails.url ,
2023-03-03 15:23:46 +00:00
} ) ;
}
}
2023-07-14 12:55:32 +01:00
/ * *
2023-11-10 16:49:29 -05:00
* Check for any missing assorts inside each traders assort . json data , checking against traders questassort . json
2023-07-14 12:55:32 +01:00
* /
protected validateQuestAssortUnlocksExist ( ) : void
{
const db = this . databaseServer . getTables ( ) ;
const traders = db . traders ;
const quests = db . templates . quests ;
for ( const traderId of Object . values ( Traders ) )
{
const traderData = traders [ traderId ] ;
const traderAssorts = traderData ? . assort ;
if ( ! traderAssorts )
{
continue ;
}
// Merge started/success/fail quest assorts into one dictionary
2023-11-15 20:35:05 -05:00
const mergedQuestAssorts = {
2023-11-13 11:51:02 -05:00
. . . traderData . questassort . started ,
. . . traderData . questassort . success ,
. . . traderData . questassort . fail ,
2023-11-15 20:35:05 -05:00
} ;
2023-07-14 12:55:32 +01:00
2023-11-10 16:49:29 -05:00
// Loop over all assorts for trader
2023-07-14 12:55:32 +01:00
for ( const [ assortKey , questKey ] of Object . entries ( mergedQuestAssorts ) )
{
// Does assort key exist in trader assort file
if ( ! traderAssorts . loyal_level_items [ assortKey ] )
{
2023-11-10 16:49:29 -05:00
// Reverse lookup of enum key by value
2023-10-13 09:45:47 +01:00
const messageValues = {
traderName : Object.keys ( Traders ) [ Object . values ( Traders ) . indexOf ( traderId ) ] ,
2023-11-15 20:35:05 -05:00
questName : quests [ questKey ] ? . QuestName ? ? "UNKNOWN" ,
} ;
2024-02-04 09:12:27 +00:00
this . logger . warning (
2023-11-15 20:35:05 -05:00
this . localisationService . getText ( "assort-missing_quest_assort_unlock" , messageValues ) ,
) ;
2023-07-14 12:55:32 +01:00
}
}
}
}
2023-03-03 15:23:46 +00:00
/ * *
* Add the logged in players name to PMC name pool
2023-08-01 12:51:40 +01:00
* @param pmcProfile Profile of player to get name from
2023-03-03 15:23:46 +00:00
* /
protected addPlayerToPMCNames ( pmcProfile : IPmcData ) : void
{
const playerName = pmcProfile . Info . Nickname ;
if ( playerName )
{
const bots = this . databaseServer . getTables ( ) . bots . types ;
2023-11-13 11:51:02 -05:00
if ( bots . bear )
2023-03-03 15:23:46 +00:00
{
2023-11-13 11:51:02 -05:00
bots . bear . firstName . push ( playerName ) ;
2023-03-03 15:23:46 +00:00
}
2023-11-15 20:35:05 -05:00
2023-11-13 11:51:02 -05:00
if ( bots . usec )
2023-03-03 15:23:46 +00:00
{
2023-11-13 11:51:02 -05:00
bots . usec . firstName . push ( playerName ) ;
2023-11-15 20:35:05 -05:00
}
2023-03-03 15:23:46 +00:00
}
}
2023-08-01 23:16:06 +01:00
/ * *
* Check for a dialog with the key 'undefined' , and remove it
* @param fullProfile Profile to check for dialog in
* /
2024-05-21 17:59:04 +00:00
protected checkForAndRemoveUndefinedDialogs ( fullProfile : ISptProfile ) : void
2023-08-01 23:16:06 +01:00
{
2023-11-13 11:51:02 -05:00
const undefinedDialog = fullProfile . dialogues . undefined ;
2023-08-01 23:16:06 +01:00
if ( undefinedDialog )
{
2023-11-13 11:51:02 -05:00
delete fullProfile . dialogues . undefined ;
2023-08-01 23:16:06 +01:00
}
}
2023-03-03 15:23:46 +00:00
/ * *
* Blank out the "test" mail message from prapor
* /
protected removePraporTestMessage ( ) : void
{
2023-11-10 16:49:29 -05:00
// Iterate over all languages (e.g. "en", "fr")
2023-03-03 15:23:46 +00:00
for ( const localeKey in this . databaseServer . getTables ( ) . locales . global )
{
this . databaseServer . getTables ( ) . locales . global [ localeKey ] [ "61687e2c3e526901fa76baf9" ] = "" ;
}
}
/ * *
* Make non - trigger - spawned raiders spawn earlier + always
* /
protected adjustLabsRaiderSpawnRate ( ) : void
{
const labsBase = this . databaseServer . getTables ( ) . locations . laboratory . base ;
2024-05-17 15:32:41 -04:00
const nonTriggerLabsBossSpawns = labsBase . BossLocationSpawn . filter (
( x ) = > x . TriggerId === "" && x . TriggerName === "" ,
2023-11-15 20:35:05 -05:00
) ;
2023-03-03 15:23:46 +00:00
if ( nonTriggerLabsBossSpawns )
{
for ( const boss of nonTriggerLabsBossSpawns )
{
boss . BossChance = 100 ;
boss . Time /= 10 ;
}
}
}
2024-05-21 17:59:04 +00:00
protected logProfileDetails ( fullProfile : ISptProfile ) : void
2023-03-03 15:23:46 +00:00
{
2024-05-21 17:59:04 +00:00
this . logger . debug ( ` Profile made with: ${ fullProfile . spt . version } ` ) ;
2024-04-18 07:54:16 +00:00
this . logger . debug (
2024-05-21 17:59:04 +00:00
` Server version: ${ globalThis . G_SPTVERSION || this . coreConfig . sptVersion } ${ globalThis . G_COMMIT } ` ,
2024-04-18 07:54:16 +00:00
) ;
2023-03-03 15:23:46 +00:00
this . logger . debug ( ` Debug enabled: ${ globalThis . G_DEBUG_CONFIGURATION } ` ) ;
this . logger . debug ( ` Mods enabled: ${ globalThis . G_MODS_ENABLED } ` ) ;
}
2023-11-15 20:35:05 -05:00
}