Helpers Mongoid conversion + cleanup (#458)
* Start converting helper method ids to mongoids and remove underscore from injections... * Finish helper mongoIds
This commit is contained in:
@@ -392,8 +392,8 @@ public class RagfairController
|
||||
/// <returns>Array of offers</returns>
|
||||
protected List<RagfairOffer> GetOffersForSearchType(
|
||||
SearchRequestData searchRequest,
|
||||
List<string> itemsToAdd,
|
||||
Dictionary<string, TraderAssort> traderAssorts,
|
||||
List<MongoId> itemsToAdd,
|
||||
Dictionary<MongoId, TraderAssort> traderAssorts,
|
||||
PmcData pmcProfile
|
||||
)
|
||||
{
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
using SPTarkov.DI.Annotations;
|
||||
using SPTarkov.Server.Core.Extensions;
|
||||
using SPTarkov.Server.Core.Models.Common;
|
||||
using SPTarkov.Server.Core.Models.Eft.Common;
|
||||
using SPTarkov.Server.Core.Models.Eft.Common.Tables;
|
||||
using SPTarkov.Server.Core.Models.Enums;
|
||||
@@ -10,22 +11,22 @@ namespace SPTarkov.Server.Core.Helpers;
|
||||
|
||||
[Injectable]
|
||||
public class AssortHelper(
|
||||
ISptLogger<AssortHelper> _logger,
|
||||
ServerLocalisationService _serverLocalisationService
|
||||
ISptLogger<AssortHelper> logger,
|
||||
ServerLocalisationService serverLocalisationService
|
||||
)
|
||||
{
|
||||
/// <summary>
|
||||
/// Remove assorts from a trader that have not been unlocked yet (via player completing corresponding quest)
|
||||
/// </summary>
|
||||
/// <param name="pmcProfile"></param>
|
||||
/// <param name="traderId">Traders id the assort belongs to</param>
|
||||
/// <param name="traderId">Traders id assort belongs to</param>
|
||||
/// <param name="traderAssorts">All assort items from same trader</param>
|
||||
/// <param name="mergedQuestAssorts">Dict of quest assort to quest id unlocks for all traders (key = started/failed/complete)</param>
|
||||
/// <param name="isFlea">Is the trader assort being modified the flea market</param>
|
||||
/// <returns>items minus locked quest assorts</returns>
|
||||
public TraderAssort StripLockedQuestAssort(
|
||||
PmcData pmcProfile,
|
||||
string traderId,
|
||||
MongoId traderId,
|
||||
TraderAssort traderAssorts,
|
||||
Dictionary<string, Dictionary<string, string>> mergedQuestAssorts,
|
||||
bool isFlea = false
|
||||
@@ -36,8 +37,8 @@ public class AssortHelper(
|
||||
// Trader assort does not always contain loyal_level_items
|
||||
if (traderAssorts.LoyalLevelItems is null)
|
||||
{
|
||||
_logger.Warning(
|
||||
_serverLocalisationService.GetText("assort-missing_loyalty_level_object", traderId)
|
||||
logger.Warning(
|
||||
serverLocalisationService.GetText("assort-missing_loyalty_level_object", traderId)
|
||||
);
|
||||
|
||||
return traderAssorts;
|
||||
@@ -116,7 +117,7 @@ public class AssortHelper(
|
||||
/// <returns>Trader assorts minus locked loyalty assorts</returns>
|
||||
public TraderAssort StripLockedLoyaltyAssort(
|
||||
PmcData pmcProfile,
|
||||
string traderId,
|
||||
MongoId traderId,
|
||||
TraderAssort assort
|
||||
)
|
||||
{
|
||||
@@ -125,8 +126,8 @@ public class AssortHelper(
|
||||
// Trader assort does not always contain loyal_level_items
|
||||
if (assort.LoyalLevelItems is null)
|
||||
{
|
||||
_logger.Warning(
|
||||
_serverLocalisationService.GetText("assort-missing_loyalty_level_object", traderId)
|
||||
logger.Warning(
|
||||
serverLocalisationService.GetText("assort-missing_loyalty_level_object", traderId)
|
||||
);
|
||||
|
||||
return strippedAssort;
|
||||
|
||||
@@ -12,16 +12,16 @@ namespace SPTarkov.Server.Core.Helpers;
|
||||
|
||||
[Injectable]
|
||||
public class BotDifficultyHelper(
|
||||
ISptLogger<BotDifficultyHelper> _logger,
|
||||
DatabaseService _databaseService,
|
||||
RandomUtil _randomUtil,
|
||||
ServerLocalisationService _serverLocalisationService,
|
||||
BotHelper _botHelper,
|
||||
ConfigServer _configServer,
|
||||
ICloner _cloner
|
||||
ISptLogger<BotDifficultyHelper> logger,
|
||||
DatabaseService databaseService,
|
||||
RandomUtil randomUtil,
|
||||
ServerLocalisationService serverLocalisationService,
|
||||
BotHelper botHelper,
|
||||
ConfigServer configServer,
|
||||
ICloner cloner
|
||||
)
|
||||
{
|
||||
protected readonly PmcConfig _pmcConfig = _configServer.GetConfig<PmcConfig>();
|
||||
protected readonly PmcConfig _pmcConfig = configServer.GetConfig<PmcConfig>();
|
||||
|
||||
/// <summary>
|
||||
/// Get difficulty settings for desired bot type, if not found use assault bot types
|
||||
@@ -36,39 +36,36 @@ public class BotDifficultyHelper(
|
||||
Bots botDb
|
||||
)
|
||||
{
|
||||
var desiredType = _botHelper.IsBotPmc(type)
|
||||
? _botHelper.GetPmcSideByRole(type).ToLowerInvariant()
|
||||
var desiredType = botHelper.IsBotPmc(type)
|
||||
? botHelper.GetPmcSideByRole(type).ToLowerInvariant()
|
||||
: type.ToLowerInvariant();
|
||||
if (!botDb.Types.ContainsKey(desiredType))
|
||||
{
|
||||
// No bot found, get fallback difficulty values
|
||||
_logger.Warning(
|
||||
_serverLocalisationService.GetText(
|
||||
"bot-unable_to_get_bot_fallback_to_assault",
|
||||
type
|
||||
)
|
||||
logger.Warning(
|
||||
serverLocalisationService.GetText("bot-unable_to_get_bot_fallback_to_assault", type)
|
||||
);
|
||||
botDb.Types[desiredType] = _cloner.Clone(botDb.Types["assault"]);
|
||||
botDb.Types[desiredType] = cloner.Clone(botDb.Types["assault"]);
|
||||
}
|
||||
|
||||
// Get settings from raw bot json template file
|
||||
var botTemplate = _botHelper.GetBotTemplate(desiredType);
|
||||
var botTemplate = botHelper.GetBotTemplate(desiredType);
|
||||
botTemplate.BotDifficulty.TryGetValue(desiredDifficulty, out var difficultySettings);
|
||||
if (difficultySettings is null)
|
||||
{
|
||||
// No bot settings found, use 'assault' bot difficulty instead
|
||||
_logger.Warning(
|
||||
_serverLocalisationService.GetText(
|
||||
logger.Warning(
|
||||
serverLocalisationService.GetText(
|
||||
"bot-unable_to_get_bot_difficulty_fallback_to_assault",
|
||||
new { botType = desiredType, difficulty = desiredDifficulty }
|
||||
)
|
||||
);
|
||||
botDb.Types[desiredType].BotDifficulty[desiredDifficulty] = _cloner.Clone(
|
||||
botDb.Types[desiredType].BotDifficulty[desiredDifficulty] = cloner.Clone(
|
||||
botDb.Types["assault"].BotDifficulty[desiredDifficulty]
|
||||
);
|
||||
}
|
||||
|
||||
return _cloner.Clone(difficultySettings);
|
||||
return cloner.Clone(difficultySettings);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -89,9 +86,7 @@ public class BotDifficultyHelper(
|
||||
|
||||
difficultySetting = ConvertBotDifficultyDropdownToBotDifficulty(difficultySetting);
|
||||
|
||||
return _cloner.Clone(
|
||||
_databaseService.GetBots().Types[type].BotDifficulty[difficultySetting]
|
||||
);
|
||||
return cloner.Clone(databaseService.GetBots().Types[type].BotDifficulty[difficultySetting]);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -118,6 +113,6 @@ public class BotDifficultyHelper(
|
||||
/// <returns>random difficulty</returns>
|
||||
public string ChooseRandomDifficulty()
|
||||
{
|
||||
return _randomUtil.GetArrayValue(["easy", "normal", "hard", "impossible"]);
|
||||
return randomUtil.GetArrayValue(["easy", "normal", "hard", "impossible"]);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -17,14 +17,14 @@ namespace SPTarkov.Server.Core.Helpers;
|
||||
|
||||
[Injectable]
|
||||
public class BotGeneratorHelper(
|
||||
ISptLogger<BotGeneratorHelper> _logger,
|
||||
RandomUtil _randomUtil,
|
||||
DurabilityLimitsHelper _durabilityLimitsHelper,
|
||||
ItemHelper _itemHelper,
|
||||
InventoryHelper _inventoryHelper,
|
||||
ProfileActivityService _profileActivityService,
|
||||
ServerLocalisationService _serverLocalisationService,
|
||||
ConfigServer _configServer
|
||||
ISptLogger<BotGeneratorHelper> logger,
|
||||
RandomUtil randomUtil,
|
||||
DurabilityLimitsHelper durabilityLimitsHelper,
|
||||
ItemHelper itemHelper,
|
||||
InventoryHelper inventoryHelper,
|
||||
ProfileActivityService profileActivityService,
|
||||
ServerLocalisationService serverLocalisationService,
|
||||
ConfigServer configServer
|
||||
)
|
||||
{
|
||||
// Equipment slot ids that do not conflict with other slots
|
||||
@@ -43,7 +43,7 @@ public class BotGeneratorHelper(
|
||||
Sides.PmcUsec.ToLowerInvariant(),
|
||||
];
|
||||
|
||||
private readonly BotConfig _botConfig = _configServer.GetConfig<BotConfig>();
|
||||
private readonly BotConfig _botConfig = configServer.GetConfig<BotConfig>();
|
||||
|
||||
/// <summary>
|
||||
/// Adds properties to an item
|
||||
@@ -55,7 +55,7 @@ public class BotGeneratorHelper(
|
||||
public Upd GenerateExtraPropertiesForItem(TemplateItem? itemTemplate, string? botRole = null)
|
||||
{
|
||||
// Get raid settings, if no raid, default to day
|
||||
var raidSettings = _profileActivityService
|
||||
var raidSettings = profileActivityService
|
||||
.GetFirstProfileActivityRaidData()
|
||||
?.RaidConfiguration;
|
||||
|
||||
@@ -114,7 +114,7 @@ public class BotGeneratorHelper(
|
||||
? new UpdFireMode { FireMode = "fullauto" }
|
||||
: new UpdFireMode
|
||||
{
|
||||
FireMode = _randomUtil.GetArrayValue(itemTemplate.Properties.WeapFireType),
|
||||
FireMode = randomUtil.GetArrayValue(itemTemplate.Properties.WeapFireType),
|
||||
};
|
||||
hasProperties = true;
|
||||
}
|
||||
@@ -163,7 +163,7 @@ public class BotGeneratorHelper(
|
||||
);
|
||||
itemProperties.Light = new UpdLight
|
||||
{
|
||||
IsActive = _randomUtil.GetChance100(lightLaserActiveChance),
|
||||
IsActive = randomUtil.GetChance100(lightLaserActiveChance),
|
||||
SelectedMode = 0,
|
||||
};
|
||||
hasProperties = true;
|
||||
@@ -178,7 +178,7 @@ public class BotGeneratorHelper(
|
||||
);
|
||||
itemProperties.Light = new UpdLight
|
||||
{
|
||||
IsActive = _randomUtil.GetChance100(lightLaserActiveChance),
|
||||
IsActive = randomUtil.GetChance100(lightLaserActiveChance),
|
||||
SelectedMode = 0,
|
||||
};
|
||||
hasProperties = true;
|
||||
@@ -193,7 +193,7 @@ public class BotGeneratorHelper(
|
||||
: GetBotEquipmentSettingFromConfig(botRole, "nvgIsActiveChanceDayPercent", 15);
|
||||
itemProperties.Togglable = new UpdTogglable
|
||||
{
|
||||
On = _randomUtil.GetChance100(nvgActiveChance),
|
||||
On = randomUtil.GetChance100(nvgActiveChance),
|
||||
};
|
||||
hasProperties = true;
|
||||
}
|
||||
@@ -211,7 +211,7 @@ public class BotGeneratorHelper(
|
||||
);
|
||||
itemProperties.Togglable = new UpdTogglable
|
||||
{
|
||||
On = _randomUtil.GetChance100(faceShieldActiveChance),
|
||||
On = randomUtil.GetChance100(faceShieldActiveChance),
|
||||
};
|
||||
hasProperties = true;
|
||||
}
|
||||
@@ -236,13 +236,13 @@ public class BotGeneratorHelper(
|
||||
return maxResource;
|
||||
}
|
||||
|
||||
if (_randomUtil.GetChance100(randomizationValues.ChanceMaxResourcePercent))
|
||||
if (randomUtil.GetChance100(randomizationValues.ChanceMaxResourcePercent))
|
||||
{
|
||||
return maxResource;
|
||||
}
|
||||
|
||||
return _randomUtil.GetDouble(
|
||||
_randomUtil.GetPercentOfValue(randomizationValues.ResourcePercent, maxResource, 0),
|
||||
return randomUtil.GetDouble(
|
||||
randomUtil.GetPercentOfValue(randomizationValues.ResourcePercent, maxResource, 0),
|
||||
maxResource
|
||||
);
|
||||
}
|
||||
@@ -268,8 +268,8 @@ public class BotGeneratorHelper(
|
||||
var botEquipmentSettings = _botConfig.Equipment[GetBotEquipmentRole(botRole)];
|
||||
if (botEquipmentSettings is null)
|
||||
{
|
||||
_logger.Warning(
|
||||
_serverLocalisationService.GetText(
|
||||
logger.Warning(
|
||||
serverLocalisationService.GetText(
|
||||
"bot-missing_equipment_settings",
|
||||
new
|
||||
{
|
||||
@@ -296,8 +296,8 @@ public class BotGeneratorHelper(
|
||||
return propValue;
|
||||
}
|
||||
|
||||
_logger.Warning(
|
||||
_serverLocalisationService.GetText(
|
||||
logger.Warning(
|
||||
serverLocalisationService.GetText(
|
||||
"bot-missing_equipment_settings_property",
|
||||
new
|
||||
{
|
||||
@@ -322,11 +322,11 @@ public class BotGeneratorHelper(
|
||||
string? botRole = null
|
||||
)
|
||||
{
|
||||
var maxDurability = _durabilityLimitsHelper.GetRandomizedMaxWeaponDurability(
|
||||
var maxDurability = durabilityLimitsHelper.GetRandomizedMaxWeaponDurability(
|
||||
itemTemplate,
|
||||
botRole
|
||||
);
|
||||
var currentDurability = _durabilityLimitsHelper.GetRandomizedWeaponDurability(
|
||||
var currentDurability = durabilityLimitsHelper.GetRandomizedWeaponDurability(
|
||||
itemTemplate,
|
||||
botRole,
|
||||
maxDurability
|
||||
@@ -359,11 +359,11 @@ public class BotGeneratorHelper(
|
||||
}
|
||||
else
|
||||
{
|
||||
maxDurability = _durabilityLimitsHelper.GetRandomizedMaxArmorDurability(
|
||||
maxDurability = durabilityLimitsHelper.GetRandomizedMaxArmorDurability(
|
||||
itemTemplate,
|
||||
botRole
|
||||
);
|
||||
currentDurability = _durabilityLimitsHelper.GetRandomizedArmorDurability(
|
||||
currentDurability = durabilityLimitsHelper.GetRandomizedArmorDurability(
|
||||
itemTemplate,
|
||||
botRole,
|
||||
maxDurability
|
||||
@@ -403,14 +403,14 @@ public class BotGeneratorHelper(
|
||||
|
||||
// TODO: Can probably be optimized to cache itemTemplates as items are added to inventory
|
||||
var equippedItemsDb = itemsEquipped
|
||||
.Select(equippedItem => _itemHelper.GetItem(equippedItem.Template).Value)
|
||||
.Select(equippedItem => itemHelper.GetItem(equippedItem.Template).Value)
|
||||
.ToList();
|
||||
var (itemIsValid, itemToEquip) = _itemHelper.GetItem(tplToCheck);
|
||||
var (itemIsValid, itemToEquip) = itemHelper.GetItem(tplToCheck);
|
||||
|
||||
if (!itemIsValid)
|
||||
{
|
||||
_logger.Warning(
|
||||
_serverLocalisationService.GetText(
|
||||
logger.Warning(
|
||||
serverLocalisationService.GetText(
|
||||
"bot-invalid_item_compatibility_check",
|
||||
new { itemTpl = tplToCheck, slot = equipmentSlot }
|
||||
)
|
||||
@@ -426,8 +426,8 @@ public class BotGeneratorHelper(
|
||||
|
||||
if (itemToEquip?.Properties is null)
|
||||
{
|
||||
_logger.Warning(
|
||||
_serverLocalisationService.GetText(
|
||||
logger.Warning(
|
||||
serverLocalisationService.GetText(
|
||||
"bot-compatibility_check_missing_props",
|
||||
new
|
||||
{
|
||||
@@ -633,9 +633,9 @@ public class BotGeneratorHelper(
|
||||
if (missingContainerCount == equipmentSlots.Count)
|
||||
{
|
||||
// Bot doesn't have any containers we want to add item to
|
||||
if (_logger.IsLogEnabled(LogLevel.Debug))
|
||||
if (logger.IsLogEnabled(LogLevel.Debug))
|
||||
{
|
||||
_logger.Debug(
|
||||
logger.Debug(
|
||||
$"Unable to add item: {itemWithChildren.FirstOrDefault()?.Template} to bot as it lacks the following containers: {string.Join(",", equipmentSlots)}"
|
||||
);
|
||||
}
|
||||
@@ -648,11 +648,11 @@ public class BotGeneratorHelper(
|
||||
}
|
||||
|
||||
// Get container details from db
|
||||
var (key, value) = _itemHelper.GetItem(container.Template);
|
||||
var (key, value) = itemHelper.GetItem(container.Template);
|
||||
if (!key)
|
||||
{
|
||||
_logger.Warning(
|
||||
_serverLocalisationService.GetText(
|
||||
logger.Warning(
|
||||
serverLocalisationService.GetText(
|
||||
"bot-missing_container_with_tpl",
|
||||
container.Template
|
||||
)
|
||||
@@ -669,7 +669,7 @@ public class BotGeneratorHelper(
|
||||
}
|
||||
|
||||
// Get x/y grid size of item
|
||||
var (itemWidth, itemHeight) = _inventoryHelper.GetItemSize(
|
||||
var (itemWidth, itemHeight) = inventoryHelper.GetItemSize(
|
||||
rootItemTplId,
|
||||
rootItemId,
|
||||
itemWithChildren
|
||||
@@ -714,7 +714,7 @@ public class BotGeneratorHelper(
|
||||
if (slotGrid.Props is not null)
|
||||
{
|
||||
// Get rid of an items free/used spots in current grid
|
||||
var slotGridMap = _inventoryHelper.GetContainerMap(
|
||||
var slotGridMap = inventoryHelper.GetContainerMap(
|
||||
slotGrid.Props.CellsH.GetValueOrDefault(),
|
||||
slotGrid.Props.CellsV.GetValueOrDefault(),
|
||||
containerItemsWithChildren,
|
||||
@@ -830,7 +830,7 @@ public class BotGeneratorHelper(
|
||||
}
|
||||
|
||||
// Check if item base type is excluded
|
||||
var itemDetails = _itemHelper.GetItem(itemTpl).Value;
|
||||
var itemDetails = itemHelper.GetItem(itemTpl).Value;
|
||||
|
||||
// if item to add is found in exclude filter, not allowed
|
||||
if (excludedFilter.Contains(itemDetails?.Parent ?? string.Empty))
|
||||
|
||||
@@ -14,10 +14,10 @@ namespace SPTarkov.Server.Core.Helpers;
|
||||
|
||||
[Injectable]
|
||||
public class BotHelper(
|
||||
ISptLogger<BotHelper> _logger,
|
||||
DatabaseService _databaseService,
|
||||
RandomUtil _randomUtil,
|
||||
ConfigServer _configServer
|
||||
ISptLogger<BotHelper> logger,
|
||||
DatabaseService databaseService,
|
||||
RandomUtil randomUtil,
|
||||
ConfigServer configServer
|
||||
)
|
||||
{
|
||||
private static readonly FrozenSet<string> _pmcTypeIds =
|
||||
@@ -28,8 +28,8 @@ public class BotHelper(
|
||||
Sides.PmcUsec.ToLowerInvariant(),
|
||||
];
|
||||
|
||||
private readonly BotConfig _botConfig = _configServer.GetConfig<BotConfig>();
|
||||
private readonly PmcConfig _pmcConfig = _configServer.GetConfig<PmcConfig>();
|
||||
private readonly BotConfig _botConfig = configServer.GetConfig<BotConfig>();
|
||||
private readonly PmcConfig _pmcConfig = configServer.GetConfig<PmcConfig>();
|
||||
private readonly ConcurrentDictionary<string, List<string>> _pmcNameCache = new();
|
||||
|
||||
/// <summary>
|
||||
@@ -39,9 +39,9 @@ public class BotHelper(
|
||||
/// <returns>BotType object</returns>
|
||||
public BotType? GetBotTemplate(string role)
|
||||
{
|
||||
if (!_databaseService.GetBots().Types.TryGetValue(role?.ToLowerInvariant(), out var bot))
|
||||
if (!databaseService.GetBots().Types.TryGetValue(role?.ToLowerInvariant(), out var bot))
|
||||
{
|
||||
_logger.Error($"Unable to get bot of type: {role} from DB");
|
||||
logger.Error($"Unable to get bot of type: {role} from DB");
|
||||
|
||||
return null;
|
||||
}
|
||||
@@ -203,7 +203,7 @@ public class BotHelper(
|
||||
/// <returns>pmc side as string</returns>
|
||||
protected string GetRandomizedPmcSide()
|
||||
{
|
||||
return _randomUtil.GetChance100(_pmcConfig.IsUsec) ? Sides.Usec : Sides.Bear;
|
||||
return randomUtil.GetChance100(_pmcConfig.IsUsec) ? Sides.Usec : Sides.Bear;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -215,20 +215,20 @@ public class BotHelper(
|
||||
public string GetPmcNicknameOfMaxLength(int maxLength, string? side = null)
|
||||
{
|
||||
var chosenFaction = (
|
||||
side ?? (_randomUtil.GetInt(0, 1) == 0 ? Sides.Usec : Sides.Bear)
|
||||
side ?? (randomUtil.GetInt(0, 1) == 0 ? Sides.Usec : Sides.Bear)
|
||||
).ToLowerInvariant();
|
||||
var cacheKey = $"{chosenFaction}{maxLength}";
|
||||
if (!_pmcNameCache.TryGetValue(cacheKey, out var eligibleNames))
|
||||
{
|
||||
if (
|
||||
!_databaseService
|
||||
!databaseService
|
||||
.GetBots()
|
||||
.Types.TryGetValue(chosenFaction, out var chosenFactionDetails)
|
||||
)
|
||||
{
|
||||
_logger.Error($"Unknown faction: {chosenFaction} Defaulting to: {Sides.Usec}");
|
||||
logger.Error($"Unknown faction: {chosenFaction} Defaulting to: {Sides.Usec}");
|
||||
chosenFaction = Sides.Usec.ToLowerInvariant();
|
||||
chosenFactionDetails = _databaseService.GetBots().Types[chosenFaction];
|
||||
chosenFactionDetails = databaseService.GetBots().Types[chosenFaction];
|
||||
}
|
||||
|
||||
var matchingNames = chosenFactionDetails
|
||||
@@ -236,12 +236,12 @@ public class BotHelper(
|
||||
.ToList();
|
||||
if (!matchingNames.Any())
|
||||
{
|
||||
_logger.Warning(
|
||||
logger.Warning(
|
||||
$"Unable to filter: {chosenFaction} PMC names to only those under: {maxLength}, none found that match that criteria, selecting from entire name pool instead"
|
||||
);
|
||||
|
||||
// Return a random string from names
|
||||
return _randomUtil.GetCollectionValue(chosenFactionDetails.FirstNames);
|
||||
return randomUtil.GetCollectionValue(chosenFactionDetails.FirstNames);
|
||||
}
|
||||
|
||||
_pmcNameCache.TryAdd(cacheKey, matchingNames);
|
||||
@@ -249,6 +249,6 @@ public class BotHelper(
|
||||
eligibleNames = matchingNames;
|
||||
}
|
||||
|
||||
return _randomUtil.GetCollectionValue(eligibleNames);
|
||||
return randomUtil.GetCollectionValue(eligibleNames);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -9,10 +9,10 @@ namespace SPTarkov.Server.Core.Helpers;
|
||||
|
||||
[Injectable]
|
||||
public class BotWeaponGeneratorHelper(
|
||||
ISptLogger<BotWeaponGeneratorHelper> _logger,
|
||||
ItemHelper _itemHelper,
|
||||
WeightedRandomHelper _weightedRandomHelper,
|
||||
BotGeneratorHelper _botGeneratorHelper
|
||||
ISptLogger<BotWeaponGeneratorHelper> logger,
|
||||
ItemHelper itemHelper,
|
||||
WeightedRandomHelper weightedRandomHelper,
|
||||
BotGeneratorHelper botGeneratorHelper
|
||||
)
|
||||
{
|
||||
private static readonly FrozenSet<string> _magCheck =
|
||||
@@ -30,7 +30,7 @@ public class BotWeaponGeneratorHelper(
|
||||
public double? GetRandomizedBulletCount(GenerationData magCounts, TemplateItem magTemplate)
|
||||
{
|
||||
var randomizedMagazineCount = GetRandomizedMagazineCount(magCounts);
|
||||
var parentItem = _itemHelper.GetItem(magTemplate.Parent).Value;
|
||||
var parentItem = itemHelper.GetItem(magTemplate.Parent).Value;
|
||||
double? chamberBulletCount = 0;
|
||||
if (MagazineIsCylinderRelated(parentItem.Name))
|
||||
{
|
||||
@@ -40,7 +40,7 @@ public class BotWeaponGeneratorHelper(
|
||||
?.Props.Filters[0]
|
||||
.Filter.FirstOrDefault() ?? new MongoId(null);
|
||||
var ammoMaxStackSize =
|
||||
_itemHelper.GetItem(firstSlotAmmoTpl).Value?.Properties?.StackMaxSize ?? 1;
|
||||
itemHelper.GetItem(firstSlotAmmoTpl).Value?.Properties?.StackMaxSize ?? 1;
|
||||
chamberBulletCount =
|
||||
ammoMaxStackSize == 1
|
||||
? 1 // Rotating grenade launcher
|
||||
@@ -68,7 +68,7 @@ public class BotWeaponGeneratorHelper(
|
||||
/// <returns>Numerical value of magazine count</returns>
|
||||
public int GetRandomizedMagazineCount(GenerationData magCounts)
|
||||
{
|
||||
return (int)_weightedRandomHelper.GetWeightedValue(magCounts.Weights);
|
||||
return (int)weightedRandomHelper.GetWeightedValue(magCounts.Weights);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -89,14 +89,14 @@ public class BotWeaponGeneratorHelper(
|
||||
/// <param name="magTemplate">Template object of magazine</param>
|
||||
/// <returns>Item array</returns>
|
||||
public List<Item> CreateMagazineWithAmmo(
|
||||
string magazineTpl,
|
||||
string ammoTpl,
|
||||
MongoId magazineTpl,
|
||||
MongoId ammoTpl,
|
||||
TemplateItem magTemplate
|
||||
)
|
||||
{
|
||||
List<Item> magazine = [new() { Id = new MongoId(), Template = magazineTpl }];
|
||||
|
||||
_itemHelper.FillMagazineWithCartridge(magazine, magTemplate, ammoTpl, 1);
|
||||
itemHelper.FillMagazineWithCartridge(magazine, magTemplate, ammoTpl, 1);
|
||||
|
||||
return magazine;
|
||||
}
|
||||
@@ -109,7 +109,7 @@ public class BotWeaponGeneratorHelper(
|
||||
/// <param name="inventory">Bot inventory to add cartridges to</param>
|
||||
/// <param name="equipmentSlotsToAddTo">What equipment slots should bullets be added into</param>
|
||||
public void AddAmmoIntoEquipmentSlots(
|
||||
string ammoTpl,
|
||||
MongoId ammoTpl,
|
||||
int cartridgeCount,
|
||||
BotBaseInventory inventory,
|
||||
HashSet<EquipmentSlots>? equipmentSlotsToAddTo = null
|
||||
@@ -120,7 +120,7 @@ public class BotWeaponGeneratorHelper(
|
||||
equipmentSlotsToAddTo = [EquipmentSlots.TacticalVest, EquipmentSlots.Pockets];
|
||||
}
|
||||
|
||||
var ammoItems = _itemHelper.SplitStack(
|
||||
var ammoItems = itemHelper.SplitStack(
|
||||
new Item
|
||||
{
|
||||
Id = new MongoId(),
|
||||
@@ -131,7 +131,7 @@ public class BotWeaponGeneratorHelper(
|
||||
|
||||
foreach (var ammoItem in ammoItems)
|
||||
{
|
||||
var result = _botGeneratorHelper.AddItemWithChildrenToEquipmentSlot(
|
||||
var result = botGeneratorHelper.AddItemWithChildrenToEquipmentSlot(
|
||||
equipmentSlotsToAddTo,
|
||||
ammoItem.Id,
|
||||
ammoItem.Template,
|
||||
@@ -141,7 +141,7 @@ public class BotWeaponGeneratorHelper(
|
||||
|
||||
if (result != ItemAddedResult.SUCCESS)
|
||||
{
|
||||
_logger.Debug(
|
||||
logger.Debug(
|
||||
$"Unable to add ammo: {ammoItem.Template} to bot inventory, {result.ToString()}"
|
||||
);
|
||||
|
||||
|
||||
@@ -8,7 +8,7 @@ using SPTarkov.Server.Core.Utils;
|
||||
namespace SPTarkov.Server.Core.Helpers;
|
||||
|
||||
[Injectable]
|
||||
public class CertificateHelper(ISptLogger<CertificateHelper> _logger, FileUtil _fileUtil)
|
||||
public class CertificateHelper(ISptLogger<CertificateHelper> logger, FileUtil fileUtil)
|
||||
{
|
||||
private const string certificatePath = "./user/certs/server.crt";
|
||||
private const string certificateKeyPath = "./user/certs/server.key";
|
||||
@@ -41,7 +41,7 @@ public class CertificateHelper(ISptLogger<CertificateHelper> _logger, FileUtil _
|
||||
throw new Exception("Certificate could not be loaded for the second time.");
|
||||
}
|
||||
|
||||
_logger.Success($"Generated and stored self-signed certificate ({certificatePath})");
|
||||
logger.Success($"Generated and stored self-signed certificate ({certificatePath})");
|
||||
}
|
||||
|
||||
return certificate;
|
||||
@@ -57,12 +57,12 @@ public class CertificateHelper(ISptLogger<CertificateHelper> _logger, FileUtil _
|
||||
|
||||
if (TryLoadCertificatePfx(out var cert))
|
||||
{
|
||||
_logger.Success($"Loaded self-signed certificate ({certificatePath})");
|
||||
logger.Success($"Loaded self-signed certificate ({certificatePath})");
|
||||
return cert;
|
||||
}
|
||||
|
||||
// shit went wrong, throw a wobbly and close app
|
||||
_logger.Critical("Certificate pfx could not be loaded. Stopping server...");
|
||||
logger.Critical("Certificate pfx could not be loaded. Stopping server...");
|
||||
Environment.Exit(1);
|
||||
return null;
|
||||
}
|
||||
@@ -91,7 +91,7 @@ public class CertificateHelper(ISptLogger<CertificateHelper> _logger, FileUtil _
|
||||
// file doesnt exist so create straight away
|
||||
cert = GenerateSelfSignedCertificate("localhost");
|
||||
SaveCertificatePfx(cert);
|
||||
_logger.Success($"Generated and stored self-signed certificate ({certificatePath})");
|
||||
logger.Success($"Generated and stored self-signed certificate ({certificatePath})");
|
||||
}
|
||||
|
||||
try
|
||||
@@ -182,11 +182,11 @@ public class CertificateHelper(ISptLogger<CertificateHelper> _logger, FileUtil _
|
||||
Base64FormattingOptions.InsertLineBreaks
|
||||
)
|
||||
+ "\n-----END CERTIFICATE-----";
|
||||
_fileUtil.WriteFile(certificatePath, certPem);
|
||||
fileUtil.WriteFile(certificatePath, certPem);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
_logger.Error($"Error saving certificate: {ex.Message}");
|
||||
logger.Error($"Error saving certificate: {ex.Message}");
|
||||
}
|
||||
}
|
||||
|
||||
@@ -198,11 +198,11 @@ public class CertificateHelper(ISptLogger<CertificateHelper> _logger, FileUtil _
|
||||
{
|
||||
try
|
||||
{
|
||||
_fileUtil.WriteFile(certificatePfxPath, certificate.Export(X509ContentType.Pfx));
|
||||
fileUtil.WriteFile(certificatePfxPath, certificate.Export(X509ContentType.Pfx));
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
_logger.Error($"Error saving certificate: {ex.Message}");
|
||||
logger.Error($"Error saving certificate: {ex.Message}");
|
||||
}
|
||||
}
|
||||
|
||||
@@ -218,11 +218,11 @@ public class CertificateHelper(ISptLogger<CertificateHelper> _logger, FileUtil _
|
||||
+ Convert.ToBase64String(privateKeyBytes, Base64FormattingOptions.InsertLineBreaks)
|
||||
+ "\n-----END PRIVATE KEY-----";
|
||||
|
||||
_fileUtil.WriteFile(certificateKeyPath, privateKeyString);
|
||||
fileUtil.WriteFile(certificateKeyPath, privateKeyString);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
_logger.Error($"Error saving certificate key: {ex.Message}");
|
||||
logger.Error($"Error saving certificate key: {ex.Message}");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,47 +1,46 @@
|
||||
using SPTarkov.DI.Annotations;
|
||||
using SPTarkov.Server.Core.Models.Common;
|
||||
|
||||
namespace SPTarkov.Server.Core.Helpers
|
||||
namespace SPTarkov.Server.Core.Helpers;
|
||||
|
||||
[Injectable]
|
||||
public class CounterTrackerHelper
|
||||
{
|
||||
[Injectable]
|
||||
public class CounterTrackerHelper
|
||||
private Dictionary<MongoId, int> _maxCounts = new();
|
||||
private readonly Dictionary<MongoId, int> _trackedCounts = new();
|
||||
|
||||
/// <summary>
|
||||
/// Add dictionary of keys and their matching limits to track
|
||||
/// </summary>
|
||||
/// <param name="maxCounts">Values to store</param>
|
||||
public void AddDataToTrack(Dictionary<MongoId, int> maxCounts)
|
||||
{
|
||||
private Dictionary<MongoId, int> _maxCounts = new();
|
||||
private readonly Dictionary<MongoId, int> _trackedCounts = new();
|
||||
_maxCounts = maxCounts;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Add dictionary of keys and their matching limits to track
|
||||
/// </summary>
|
||||
/// <param name="maxCounts">Values to store</param>
|
||||
public void AddDataToTrack(Dictionary<MongoId, int> maxCounts)
|
||||
/// <summary>
|
||||
/// Increment the counter for passed in key, get back value determining if max value passed
|
||||
/// </summary>
|
||||
/// <param name="key"></param>
|
||||
/// <param name="countToIncrementBy"></param>
|
||||
/// <returns>True = above max count</returns>
|
||||
public bool IncrementCount(MongoId key, int countToIncrementBy = 1)
|
||||
{
|
||||
// Not tracked, skip
|
||||
if (!_maxCounts.Any() || !_maxCounts.ContainsKey(key))
|
||||
{
|
||||
_maxCounts = maxCounts;
|
||||
return false;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Increment the counter for passed in key, get back value determining if max value passed
|
||||
/// </summary>
|
||||
/// <param name="key"></param>
|
||||
/// <param name="countToIncrementBy"></param>
|
||||
/// <returns>True = above max count</returns>
|
||||
public bool IncrementCount(MongoId key, int countToIncrementBy = 1)
|
||||
{
|
||||
// Not tracked, skip
|
||||
if (!_maxCounts.Any() || !_maxCounts.ContainsKey(key))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
_trackedCounts.TryAdd(key, 0);
|
||||
_trackedCounts[key] += countToIncrementBy;
|
||||
|
||||
_trackedCounts.TryAdd(key, 0);
|
||||
_trackedCounts[key] += countToIncrementBy;
|
||||
return _trackedCounts[key] > _maxCounts[key];
|
||||
}
|
||||
|
||||
return _trackedCounts[key] > _maxCounts[key];
|
||||
}
|
||||
|
||||
public void Clear()
|
||||
{
|
||||
_trackedCounts.Clear();
|
||||
_maxCounts.Clear();
|
||||
}
|
||||
public void Clear()
|
||||
{
|
||||
_trackedCounts.Clear();
|
||||
_maxCounts.Clear();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -47,7 +47,7 @@ public class DialogueHelper(ISptLogger<DialogueHelper> logger, ProfileHelper pro
|
||||
/// <param name="sessionID">Session/player id</param>
|
||||
/// <param name="itemId">Item being moved to inventory</param>
|
||||
/// <returns>Collection of items from message</returns>
|
||||
public List<Item> GetMessageItemContents(string messageID, string sessionID, MongoId itemId)
|
||||
public List<Item> GetMessageItemContents(string messageID, MongoId sessionID, MongoId itemId)
|
||||
{
|
||||
var fullProfile = profileHelper.GetFullProfile(sessionID);
|
||||
var dialogueData = fullProfile.DialogueRecords;
|
||||
@@ -95,7 +95,7 @@ public class DialogueHelper(ISptLogger<DialogueHelper> logger, ProfileHelper pro
|
||||
/// </summary>
|
||||
/// <param name="sessionId">Session/player id</param>
|
||||
/// <returns>Dialog dictionary</returns>
|
||||
public Dictionary<string, Models.Eft.Profile.Dialogue> GetDialogsForProfile(string sessionId)
|
||||
public Dictionary<string, Models.Eft.Profile.Dialogue> GetDialogsForProfile(MongoId sessionId)
|
||||
{
|
||||
var profile = profileHelper.GetFullProfile(sessionId);
|
||||
return profile.DialogueRecords
|
||||
@@ -108,7 +108,7 @@ public class DialogueHelper(ISptLogger<DialogueHelper> logger, ProfileHelper pro
|
||||
/// <param name="profileId">Profile to look in</param>
|
||||
/// <param name="dialogueId">Dialog to return</param>
|
||||
/// <returns>Dialogue</returns>
|
||||
public Models.Eft.Profile.Dialogue? GetDialogueFromProfile(string profileId, string dialogueId)
|
||||
public Models.Eft.Profile.Dialogue? GetDialogueFromProfile(MongoId profileId, string dialogueId)
|
||||
{
|
||||
var dialogues = GetDialogsForProfile(profileId);
|
||||
if (dialogues.TryGetValue(dialogueId, out var dialogue))
|
||||
|
||||
@@ -11,9 +11,9 @@ namespace SPTarkov.Server.Core.Helpers;
|
||||
|
||||
[Injectable(InjectionType.Singleton)]
|
||||
public class HandbookHelper(
|
||||
DatabaseService _databaseService,
|
||||
ConfigServer _configServer,
|
||||
ICloner _cloner
|
||||
DatabaseService databaseService,
|
||||
ConfigServer configServer,
|
||||
ICloner cloner
|
||||
)
|
||||
{
|
||||
private LookupCollection? _handbookPriceCache;
|
||||
@@ -22,7 +22,7 @@ public class HandbookHelper(
|
||||
get { return _handbookPriceCache ??= HydrateHandbookCache(); }
|
||||
}
|
||||
|
||||
protected readonly ItemConfig _itemConfig = _configServer.GetConfig<ItemConfig>();
|
||||
protected readonly ItemConfig _itemConfig = configServer.GetConfig<ItemConfig>();
|
||||
|
||||
/// <summary>
|
||||
/// Create an in-memory cache of all items with associated handbook price in handbookPriceCache class
|
||||
@@ -30,7 +30,7 @@ public class HandbookHelper(
|
||||
protected LookupCollection HydrateHandbookCache()
|
||||
{
|
||||
var result = new LookupCollection();
|
||||
var handbook = _databaseService.GetHandbook();
|
||||
var handbook = databaseService.GetHandbook();
|
||||
// Add handbook overrides found in items.json config into db
|
||||
foreach (var (key, priceOverride) in _itemConfig.HandbookPriceOverride)
|
||||
{
|
||||
@@ -52,7 +52,7 @@ public class HandbookHelper(
|
||||
itemToUpdate.ParentId = priceOverride.ParentId;
|
||||
}
|
||||
|
||||
var handbookDbClone = _cloner.Clone(handbook);
|
||||
var handbookDbClone = cloner.Clone(handbook);
|
||||
foreach (var handbookItem in handbookDbClone.Items)
|
||||
{
|
||||
result.Items.ById.TryAdd(handbookItem.Id, handbookItem.Price ?? 0);
|
||||
@@ -70,12 +70,16 @@ public class HandbookHelper(
|
||||
result.Categories.ById.TryAdd(handbookCategory.Id, handbookCategory.ParentId);
|
||||
if (handbookCategory.ParentId is not null)
|
||||
{
|
||||
if (!result.Categories.ByParent.TryGetValue(handbookCategory.ParentId, out _))
|
||||
if (!result.Categories.ByParent.TryGetValue(handbookCategory.ParentId.Value, out _))
|
||||
{
|
||||
result.Categories.ByParent.TryAdd(handbookCategory.ParentId, []);
|
||||
result.Categories.ByParent.TryAdd(handbookCategory.ParentId.Value, []);
|
||||
}
|
||||
|
||||
result.Categories.ByParent.TryGetValue(handbookCategory.ParentId, out var itemIds);
|
||||
result.Categories.ByParent.TryGetValue(
|
||||
handbookCategory.ParentId.Value,
|
||||
out var itemIds
|
||||
);
|
||||
|
||||
itemIds.Add(handbookCategory.Id);
|
||||
}
|
||||
}
|
||||
@@ -96,7 +100,7 @@ public class HandbookHelper(
|
||||
return itemPrice;
|
||||
}
|
||||
|
||||
var handbookItem = _databaseService
|
||||
var handbookItem = databaseService
|
||||
.GetHandbook()
|
||||
.Items?.FirstOrDefault(item => item.Id == tpl);
|
||||
if (handbookItem is null)
|
||||
@@ -142,7 +146,7 @@ public class HandbookHelper(
|
||||
/// </summary>
|
||||
/// <param name="parentId"></param>
|
||||
/// <returns>string array</returns>
|
||||
public List<string> TemplatesWithParent(string parentId)
|
||||
public List<MongoId> TemplatesWithParent(MongoId parentId)
|
||||
{
|
||||
HandbookPriceCache.Items.ByParent.TryGetValue(parentId, out var template);
|
||||
|
||||
@@ -154,7 +158,7 @@ public class HandbookHelper(
|
||||
/// </summary>
|
||||
/// <param name="category"></param>
|
||||
/// <returns>true if exists in cache</returns>
|
||||
public bool IsCategory(string category)
|
||||
public bool IsCategory(MongoId category)
|
||||
{
|
||||
return HandbookPriceCache.Categories.ById.TryGetValue(category, out _);
|
||||
}
|
||||
@@ -176,7 +180,7 @@ public class HandbookHelper(
|
||||
/// <param name="nonRoubleCurrencyCount">Currency count to convert</param>
|
||||
/// <param name="currencyTypeFrom">What current currency is</param>
|
||||
/// <returns>Count in roubles</returns>
|
||||
public double InRUB(double nonRoubleCurrencyCount, string currencyTypeFrom)
|
||||
public double InRUB(double nonRoubleCurrencyCount, MongoId currencyTypeFrom)
|
||||
{
|
||||
return currencyTypeFrom == Money.ROUBLES
|
||||
? nonRoubleCurrencyCount
|
||||
@@ -189,7 +193,7 @@ public class HandbookHelper(
|
||||
/// <param name="roubleCurrencyCount">roubles to convert</param>
|
||||
/// <param name="currencyTypeTo">Currency to convert roubles into</param>
|
||||
/// <returns>currency count in desired type</returns>
|
||||
public double FromRUB(double roubleCurrencyCount, string currencyTypeTo)
|
||||
public double FromRUB(double roubleCurrencyCount, MongoId currencyTypeTo)
|
||||
{
|
||||
if (currencyTypeTo == Money.ROUBLES)
|
||||
{
|
||||
@@ -201,9 +205,9 @@ public class HandbookHelper(
|
||||
return price > 0 ? Math.Max(1, Math.Round(roubleCurrencyCount / price)) : 0;
|
||||
}
|
||||
|
||||
public HandbookCategory GetCategoryById(string handbookId)
|
||||
public HandbookCategory GetCategoryById(MongoId handbookId)
|
||||
{
|
||||
return _databaseService
|
||||
return databaseService
|
||||
.GetHandbook()
|
||||
.Categories.FirstOrDefault(category => category.Id == handbookId);
|
||||
}
|
||||
@@ -213,23 +217,23 @@ public class HandbookHelper(
|
||||
public LookupItem()
|
||||
{
|
||||
ById = new Dictionary<MongoId, T>();
|
||||
ByParent = new Dictionary<string, List<I>>();
|
||||
ByParent = new Dictionary<MongoId, List<I>>();
|
||||
}
|
||||
|
||||
public Dictionary<MongoId, T> ById { get; set; }
|
||||
|
||||
public Dictionary<string, List<I>> ByParent { get; set; }
|
||||
public Dictionary<MongoId, List<I>> ByParent { get; set; }
|
||||
}
|
||||
|
||||
protected record LookupCollection
|
||||
{
|
||||
public LookupCollection()
|
||||
{
|
||||
Items = new LookupItem<double, string>();
|
||||
Items = new LookupItem<double, MongoId>();
|
||||
Categories = new LookupItem<string, string>();
|
||||
}
|
||||
|
||||
public LookupItem<double, string> Items { get; set; }
|
||||
public LookupItem<double, MongoId> Items { get; set; }
|
||||
|
||||
public LookupItem<string, string> Categories { get; set; }
|
||||
}
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
using SPTarkov.DI.Annotations;
|
||||
using SPTarkov.Server.Core.Models.Common;
|
||||
using SPTarkov.Server.Core.Models.Eft.Common;
|
||||
using SPTarkov.Server.Core.Models.Eft.Common.Tables;
|
||||
using SPTarkov.Server.Core.Models.Spt.Config;
|
||||
@@ -10,13 +11,13 @@ namespace SPTarkov.Server.Core.Helpers;
|
||||
|
||||
[Injectable]
|
||||
public class HealthHelper(
|
||||
TimeUtil _timeUtil,
|
||||
SaveServer _saveServer,
|
||||
ProfileHelper _profileHelper,
|
||||
ConfigServer _configServer
|
||||
TimeUtil timeUtil,
|
||||
SaveServer saveServer,
|
||||
ProfileHelper profileHelper,
|
||||
ConfigServer configServer
|
||||
)
|
||||
{
|
||||
protected readonly HealthConfig _healthConfig = _configServer.GetConfig<HealthConfig>();
|
||||
protected readonly HealthConfig _healthConfig = configServer.GetConfig<HealthConfig>();
|
||||
|
||||
/// <summary>
|
||||
/// Update player profile vitality values with changes from client request object
|
||||
@@ -26,18 +27,18 @@ public class HealthHelper(
|
||||
/// <param name="healthChanges">Changes to apply </param>
|
||||
/// <param name="isDead">OPTIONAL - Is player dead</param>
|
||||
public void ApplyHealthChangesToProfile(
|
||||
string sessionID,
|
||||
MongoId sessionID,
|
||||
PmcData pmcProfileToUpdate,
|
||||
BotBaseHealth healthChanges,
|
||||
bool isDead = false
|
||||
)
|
||||
{
|
||||
var fullProfile = _saveServer.GetProfile(sessionID);
|
||||
var fullProfile = saveServer.GetProfile(sessionID);
|
||||
var profileEdition = fullProfile.ProfileInfo.Edition;
|
||||
var profileSide = fullProfile.CharacterData.PmcData.Info.Side;
|
||||
|
||||
// Get matching 'side' e.g. USEC
|
||||
var matchingSide = _profileHelper.GetProfileTemplateForSide(profileEdition, profileSide);
|
||||
var matchingSide = profileHelper.GetProfileTemplateForSide(profileEdition, profileSide);
|
||||
|
||||
var defaultTemperature =
|
||||
matchingSide?.Character?.Health?.Temperature ?? new CurrentMinMax { Current = 36.6 };
|
||||
@@ -53,7 +54,7 @@ public class HealthHelper(
|
||||
AdjustProfileHydrationEnergyTemperature(pmcProfileToUpdate, healthChanges);
|
||||
|
||||
// Update last edited timestamp
|
||||
pmcProfileToUpdate.Health.UpdateTime = _timeUtil.GetTimeStamp();
|
||||
pmcProfileToUpdate.Health.UpdateTime = timeUtil.GetTimeStamp();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
||||
@@ -18,16 +18,16 @@ namespace SPTarkov.Server.Core.Helpers;
|
||||
|
||||
[Injectable]
|
||||
public class HideoutHelper(
|
||||
ISptLogger<HideoutHelper> _logger,
|
||||
TimeUtil _timeUtil,
|
||||
ServerLocalisationService _serverLocalisationService,
|
||||
DatabaseService _databaseService,
|
||||
EventOutputHolder _eventOutputHolder,
|
||||
HttpResponseUtil _httpResponseUtil,
|
||||
ProfileHelper _profileHelper,
|
||||
InventoryHelper _inventoryHelper,
|
||||
ItemHelper _itemHelper,
|
||||
ICloner _cloner
|
||||
ISptLogger<HideoutHelper> logger,
|
||||
TimeUtil timeUtil,
|
||||
ServerLocalisationService serverLocalisationService,
|
||||
DatabaseService databaseService,
|
||||
EventOutputHolder eventOutputHolder,
|
||||
HttpResponseUtil httpResponseUtil,
|
||||
ProfileHelper profileHelper,
|
||||
InventoryHelper inventoryHelper,
|
||||
ItemHelper itemHelper,
|
||||
ICloner cloner
|
||||
)
|
||||
{
|
||||
public static readonly MongoId BitcoinProductionId = new("5d5c205bd582a50d042a3c0e");
|
||||
@@ -44,24 +44,24 @@ public class HideoutHelper(
|
||||
public void RegisterProduction(
|
||||
PmcData pmcData,
|
||||
HideoutSingleProductionStartRequestData productionRequest,
|
||||
string sessionID
|
||||
MongoId sessionID
|
||||
)
|
||||
{
|
||||
var recipe = _databaseService
|
||||
var recipe = databaseService
|
||||
.GetHideout()
|
||||
.Production.Recipes.FirstOrDefault(production =>
|
||||
production.Id == productionRequest.RecipeId
|
||||
);
|
||||
if (recipe is null)
|
||||
{
|
||||
_logger.Error(
|
||||
_serverLocalisationService.GetText(
|
||||
logger.Error(
|
||||
serverLocalisationService.GetText(
|
||||
"hideout-missing_recipe_in_db",
|
||||
productionRequest.RecipeId
|
||||
)
|
||||
);
|
||||
|
||||
_httpResponseUtil.AppendErrorToOutput(_eventOutputHolder.GetOutput(sessionID));
|
||||
httpResponseUtil.AppendErrorToOutput(eventOutputHolder.GetOutput(sessionID));
|
||||
}
|
||||
|
||||
// @Important: Here we need to be very exact:
|
||||
@@ -90,12 +90,12 @@ public class HideoutHelper(
|
||||
|
||||
foreach (var tool in productionRequest.Tools)
|
||||
{
|
||||
var toolItem = _cloner.Clone(
|
||||
var toolItem = cloner.Clone(
|
||||
pmcData.Inventory.Items.FirstOrDefault(x => x.Id == tool.Id)
|
||||
);
|
||||
|
||||
// Make sure we only return as many as we took
|
||||
_itemHelper.AddUpdObjectToItem(toolItem);
|
||||
itemHelper.AddUpdObjectToItem(toolItem);
|
||||
|
||||
toolItem.Upd.StackObjectsCount = tool.Count;
|
||||
|
||||
@@ -123,24 +123,24 @@ public class HideoutHelper(
|
||||
public void RegisterProduction(
|
||||
PmcData pmcData,
|
||||
HideoutContinuousProductionStartRequestData productionRequest,
|
||||
string sessionID
|
||||
MongoId sessionID
|
||||
)
|
||||
{
|
||||
var recipe = _databaseService
|
||||
var recipe = databaseService
|
||||
.GetHideout()
|
||||
.Production.Recipes.FirstOrDefault(production =>
|
||||
production.Id == productionRequest.RecipeId
|
||||
);
|
||||
if (recipe is null)
|
||||
{
|
||||
_logger.Error(
|
||||
_serverLocalisationService.GetText(
|
||||
logger.Error(
|
||||
serverLocalisationService.GetText(
|
||||
"hideout-missing_recipe_in_db",
|
||||
productionRequest.RecipeId
|
||||
)
|
||||
);
|
||||
|
||||
_httpResponseUtil.AppendErrorToOutput(_eventOutputHolder.GetOutput(sessionID));
|
||||
httpResponseUtil.AppendErrorToOutput(eventOutputHolder.GetOutput(sessionID));
|
||||
}
|
||||
|
||||
// @Important: Here we need to be very exact:
|
||||
@@ -153,11 +153,11 @@ public class HideoutHelper(
|
||||
|
||||
var modifiedProductionTime = GetAdjustedCraftTimeWithSkills(
|
||||
pmcData,
|
||||
productionRequest.RecipeId
|
||||
productionRequest.RecipeId.Value
|
||||
);
|
||||
|
||||
var production = InitProduction(
|
||||
productionRequest.RecipeId,
|
||||
productionRequest.RecipeId.Value,
|
||||
modifiedProductionTime ?? 0,
|
||||
recipe.NeedFuelForAllProductionTime
|
||||
);
|
||||
@@ -170,7 +170,7 @@ public class HideoutHelper(
|
||||
/// with all the constants.
|
||||
/// </summary>
|
||||
public Production InitProduction(
|
||||
string recipeId,
|
||||
MongoId recipeId,
|
||||
double productionTime,
|
||||
bool? needFuelForAllProductionTime
|
||||
)
|
||||
@@ -180,7 +180,7 @@ public class HideoutHelper(
|
||||
Progress = 0,
|
||||
InProgress = true,
|
||||
RecipeId = recipeId,
|
||||
StartTimestamp = _timeUtil.GetTimeStamp(),
|
||||
StartTimestamp = timeUtil.GetTimeStamp(),
|
||||
ProductionTime = productionTime,
|
||||
Products = [],
|
||||
GivenItemsInStart = [],
|
||||
@@ -209,8 +209,8 @@ public class HideoutHelper(
|
||||
);
|
||||
if (stashItem is null)
|
||||
{
|
||||
_logger.Warning(
|
||||
_serverLocalisationService.GetText(
|
||||
logger.Warning(
|
||||
serverLocalisationService.GetText(
|
||||
"hideout-unable_to_apply_stashsize_bonus_no_stash_found",
|
||||
profileData.Inventory.Stash
|
||||
)
|
||||
@@ -235,9 +235,9 @@ public class HideoutHelper(
|
||||
|
||||
// Add bonus to player bonuses array in profile
|
||||
// EnergyRegeneration, HealthRegeneration, RagfairCommission, ScavCooldownTimer, SkillGroupLevelingBoost, ExperienceRate, QuestMoneyReward etc
|
||||
if (_logger.IsLogEnabled(LogLevel.Debug))
|
||||
if (logger.IsLogEnabled(LogLevel.Debug))
|
||||
{
|
||||
_logger.Debug($"Adding bonus: {bonus.Type} to profile, value: {bonus.Value}");
|
||||
logger.Debug($"Adding bonus: {bonus.Type} to profile, value: {bonus.Value}");
|
||||
}
|
||||
|
||||
profileData.Bonuses.Add(bonus);
|
||||
@@ -247,16 +247,16 @@ public class HideoutHelper(
|
||||
/// Process a players hideout, update areas that use resources + increment production timers
|
||||
/// </summary>
|
||||
/// <param name="sessionID">Session id</param>
|
||||
public void UpdatePlayerHideout(string sessionID)
|
||||
public void UpdatePlayerHideout(MongoId sessionID)
|
||||
{
|
||||
var pmcData = _profileHelper.GetPmcProfile(sessionID);
|
||||
var pmcData = profileHelper.GetPmcProfile(sessionID);
|
||||
var hideoutProperties = GetHideoutProperties(pmcData);
|
||||
|
||||
pmcData.Hideout.SptUpdateLastRunTimestamp ??= _timeUtil.GetTimeStamp();
|
||||
pmcData.Hideout.SptUpdateLastRunTimestamp ??= timeUtil.GetTimeStamp();
|
||||
|
||||
UpdateAreasWithResources(sessionID, pmcData, hideoutProperties);
|
||||
UpdateProductionTimers(pmcData, hideoutProperties);
|
||||
pmcData.Hideout.SptUpdateLastRunTimestamp = _timeUtil.GetTimeStamp();
|
||||
pmcData.Hideout.SptUpdateLastRunTimestamp = timeUtil.GetTimeStamp();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -313,7 +313,7 @@ public class HideoutHelper(
|
||||
/// <param name="hideoutProperties">Hideout properties</param>
|
||||
protected void UpdateProductionTimers(PmcData pmcData, HideoutProperties hideoutProperties)
|
||||
{
|
||||
var recipes = _databaseService.GetHideout().Production;
|
||||
var recipes = databaseService.GetHideout().Production;
|
||||
|
||||
// Check each production and handle edge cases if necessary
|
||||
foreach (var prodId in pmcData.Hideout?.Production)
|
||||
@@ -328,8 +328,8 @@ public class HideoutHelper(
|
||||
|
||||
if (craft.Progress == null)
|
||||
{
|
||||
_logger.Warning(
|
||||
_serverLocalisationService.GetText(
|
||||
logger.Warning(
|
||||
serverLocalisationService.GetText(
|
||||
"hideout-craft_has_undefined_progress_value_defaulting",
|
||||
prodId
|
||||
)
|
||||
@@ -383,8 +383,8 @@ public class HideoutHelper(
|
||||
var recipe = recipes?.Recipes?.FirstOrDefault(r => r.Id == prodId.Key);
|
||||
if (recipe is null)
|
||||
{
|
||||
_logger.Error(
|
||||
_serverLocalisationService.GetText("hideout-missing_recipe_for_area", prodId)
|
||||
logger.Error(
|
||||
serverLocalisationService.GetText("hideout-missing_recipe_for_area", prodId)
|
||||
);
|
||||
|
||||
continue;
|
||||
@@ -486,7 +486,7 @@ public class HideoutHelper(
|
||||
|
||||
// Get seconds since last hideout update
|
||||
var timeElapsedSeconds =
|
||||
_timeUtil.GetTimeStamp() - pmcData.Hideout.SptUpdateLastRunTimestamp;
|
||||
timeUtil.GetTimeStamp() - pmcData.Hideout.SptUpdateLastRunTimestamp;
|
||||
|
||||
// Increment progress by time passed if progress is less than time needed
|
||||
if (production.Progress < production.ProductionTime)
|
||||
@@ -536,7 +536,7 @@ public class HideoutHelper(
|
||||
protected void UpdateScavCaseProductionTimer(PmcData pmcData, string productionId)
|
||||
{
|
||||
var timeElapsed =
|
||||
_timeUtil.GetTimeStamp()
|
||||
timeUtil.GetTimeStamp()
|
||||
- pmcData.Hideout.Production[productionId].StartTimestamp
|
||||
- pmcData.Hideout.Production[productionId].Progress;
|
||||
|
||||
@@ -550,7 +550,7 @@ public class HideoutHelper(
|
||||
/// <param name="pmcData">Profile to update areas of</param>
|
||||
/// <param name="hideoutProperties">hideout properties</param>
|
||||
protected void UpdateAreasWithResources(
|
||||
string sessionID,
|
||||
MongoId sessionID,
|
||||
PmcData pmcData,
|
||||
HideoutProperties hideoutProperties
|
||||
)
|
||||
@@ -592,7 +592,7 @@ public class HideoutHelper(
|
||||
// 1 resource last 14 min 27 sec, 1/14.45/60 = 0.00115
|
||||
// 10-10-2021 From wiki, 1 resource last 12 minutes 38 seconds, 1/12.63333/60 = 0.00131
|
||||
var fuelUsedSinceLastTick =
|
||||
_databaseService.GetHideout().Settings.GeneratorFuelFlowRate
|
||||
databaseService.GetHideout().Settings.GeneratorFuelFlowRate
|
||||
* GetTimeElapsedSinceLastServerTick(pmcData, isGeneratorOn);
|
||||
|
||||
// Get all fuel consumption bonuses, returns an empty array if none found
|
||||
@@ -645,7 +645,7 @@ public class HideoutHelper(
|
||||
// Undefined fuel, fresh fuel item and needs its max fuel amount looked up
|
||||
if (fuelRemaining is null)
|
||||
{
|
||||
var fuelItemTemplate = _itemHelper.GetItem(fuelItemInSlot.Template).Value;
|
||||
var fuelItemTemplate = itemHelper.GetItem(fuelItemInSlot.Template).Value;
|
||||
pointsConsumed = fuelUsedSinceLastTick ?? 0;
|
||||
fuelRemaining = fuelItemTemplate.Properties.MaxResource - fuelUsedSinceLastTick;
|
||||
}
|
||||
@@ -665,7 +665,7 @@ public class HideoutHelper(
|
||||
// Fuel consumed / 10 is over 1, add hideout management skill point
|
||||
if (pmcData is not null && Math.Floor(pointsConsumed / 10) >= 1)
|
||||
{
|
||||
_profileHelper.AddSkillPointsToPlayer(pmcData, SkillTypes.HideoutManagement, 1);
|
||||
profileHelper.AddSkillPointsToPlayer(pmcData, SkillTypes.HideoutManagement, 1);
|
||||
pointsConsumed -= 10;
|
||||
}
|
||||
|
||||
@@ -680,9 +680,9 @@ public class HideoutHelper(
|
||||
isFuelItemFoundInRaid
|
||||
);
|
||||
|
||||
if (_logger.IsLogEnabled(LogLevel.Debug))
|
||||
if (logger.IsLogEnabled(LogLevel.Debug))
|
||||
{
|
||||
_logger.Debug(
|
||||
logger.Debug(
|
||||
$"Profile: {pmcData.Id} Generator has: {fuelRemaining} fuel left in slot {i + 1}"
|
||||
);
|
||||
}
|
||||
@@ -696,9 +696,9 @@ public class HideoutHelper(
|
||||
|
||||
// Ran out of fuel items to deduct fuel from
|
||||
fuelUsedSinceLastTick = Math.Abs(fuelRemaining ?? 0);
|
||||
if (_logger.IsLogEnabled(LogLevel.Debug))
|
||||
if (logger.IsLogEnabled(LogLevel.Debug))
|
||||
{
|
||||
_logger.Debug($"Profile: {pmcData.Id} Generator ran out of fuel");
|
||||
logger.Debug($"Profile: {pmcData.Id} Generator ran out of fuel");
|
||||
}
|
||||
}
|
||||
|
||||
@@ -710,7 +710,7 @@ public class HideoutHelper(
|
||||
}
|
||||
|
||||
protected void UpdateWaterCollector(
|
||||
string sessionId,
|
||||
MongoId sessionId,
|
||||
PmcData pmcData,
|
||||
BotHideoutArea area,
|
||||
HideoutProperties hideoutProperties
|
||||
@@ -752,7 +752,7 @@ public class HideoutHelper(
|
||||
Action = "HideoutSingleProductionStart",
|
||||
Items = [],
|
||||
Tools = [],
|
||||
Timestamp = _timeUtil.GetTimeStamp(),
|
||||
Timestamp = timeUtil.GetTimeStamp(),
|
||||
};
|
||||
|
||||
RegisterProduction(pmcData, recipe, sessionId);
|
||||
@@ -768,19 +768,19 @@ public class HideoutHelper(
|
||||
/// <returns>Items craft time with bonuses subtracted</returns>
|
||||
public double? GetAdjustedCraftTimeWithSkills(
|
||||
PmcData pmcData,
|
||||
string recipeId,
|
||||
MongoId recipeId,
|
||||
bool applyHideoutManagementBonus = false
|
||||
)
|
||||
{
|
||||
var globalSkillsDb = _databaseService.GetGlobals().Configuration.SkillsSettings;
|
||||
var globalSkillsDb = databaseService.GetGlobals().Configuration.SkillsSettings;
|
||||
|
||||
var recipe = _databaseService
|
||||
var recipe = databaseService
|
||||
.GetHideout()
|
||||
.Production.Recipes.FirstOrDefault(production => production.Id == recipeId);
|
||||
if (recipe is null)
|
||||
{
|
||||
_logger.Error(
|
||||
_serverLocalisationService.GetText("hideout-missing_recipe_in_db", recipeId)
|
||||
logger.Error(
|
||||
serverLocalisationService.GetText("hideout-missing_recipe_in_db", recipeId)
|
||||
);
|
||||
|
||||
return null;
|
||||
@@ -812,7 +812,7 @@ public class HideoutHelper(
|
||||
}
|
||||
|
||||
var modifiedProductionTime = recipe.ProductionTime - timeReductionSeconds;
|
||||
if (modifiedProductionTime > 0 && _profileHelper.IsDeveloperAccount(pmcData.Id.Value))
|
||||
if (modifiedProductionTime > 0 && profileHelper.IsDeveloperAccount(pmcData.Id.Value))
|
||||
{
|
||||
modifiedProductionTime = 40;
|
||||
}
|
||||
@@ -896,7 +896,7 @@ public class HideoutHelper(
|
||||
// Check units consumed for possible increment of hideout mgmt skill point
|
||||
if (pmcData is not null && Math.Floor(pointsConsumed / 10) >= 1)
|
||||
{
|
||||
_profileHelper.AddSkillPointsToPlayer(pmcData, SkillTypes.HideoutManagement, 1);
|
||||
profileHelper.AddSkillPointsToPlayer(pmcData, SkillTypes.HideoutManagement, 1);
|
||||
pointsConsumed -= 10;
|
||||
}
|
||||
|
||||
@@ -912,9 +912,9 @@ public class HideoutHelper(
|
||||
pointsConsumed,
|
||||
isWaterFilterFoundInRaid
|
||||
);
|
||||
if (_logger.IsLogEnabled(LogLevel.Debug))
|
||||
if (logger.IsLogEnabled(LogLevel.Debug))
|
||||
{
|
||||
_logger.Debug($"Water filter has: {resourceValue} units left in slot {i + 1}");
|
||||
logger.Debug($"Water filter has: {resourceValue} units left in slot {i + 1}");
|
||||
}
|
||||
|
||||
break; // Break here to avoid iterating other filters now w're done
|
||||
@@ -959,7 +959,7 @@ public class HideoutHelper(
|
||||
/// <returns>Drain rate</returns>
|
||||
protected double GetWaterFilterDrainRate(PmcData pmcData)
|
||||
{
|
||||
var globalSkillsDb = _databaseService.GetGlobals().Configuration.SkillsSettings;
|
||||
var globalSkillsDb = databaseService.GetGlobals().Configuration.SkillsSettings;
|
||||
|
||||
// 100 resources last 8 hrs 20 min, 100/8.33/60/60 = 0.00333
|
||||
const double filterDrainRate = 0.00333d;
|
||||
@@ -989,9 +989,9 @@ public class HideoutHelper(
|
||||
/// </summary>
|
||||
/// <param name="prodId">Id, e.g. Water collector id</param>
|
||||
/// <returns>Seconds to produce item</returns>
|
||||
protected double GetTotalProductionTimeSeconds(string prodId)
|
||||
protected double GetTotalProductionTimeSeconds(MongoId prodId)
|
||||
{
|
||||
return _databaseService
|
||||
return databaseService
|
||||
.GetHideout()
|
||||
.Production.Recipes.FirstOrDefault(prod => prod.Id == prodId)
|
||||
?.ProductionTime ?? 0;
|
||||
@@ -1036,7 +1036,7 @@ public class HideoutHelper(
|
||||
300/17.64694/60/60 = 0.004722
|
||||
*/
|
||||
var filterDrainRate =
|
||||
_databaseService.GetHideout().Settings.AirFilterUnitFlowRate
|
||||
databaseService.GetHideout().Settings.AirFilterUnitFlowRate
|
||||
* GetTimeElapsedSinceLastServerTick(pmcData, isGeneratorOn);
|
||||
|
||||
// Hideout management resource consumption bonus:
|
||||
@@ -1072,7 +1072,7 @@ public class HideoutHelper(
|
||||
// check unit consumed for increment skill point
|
||||
if (pmcData is not null && Math.Floor(pointsConsumed / 10) >= 1)
|
||||
{
|
||||
_profileHelper.AddSkillPointsToPlayer(pmcData, SkillTypes.HideoutManagement, 1);
|
||||
profileHelper.AddSkillPointsToPlayer(pmcData, SkillTypes.HideoutManagement, 1);
|
||||
pointsConsumed -= 10;
|
||||
}
|
||||
|
||||
@@ -1087,9 +1087,9 @@ public class HideoutHelper(
|
||||
UnitsConsumed = pointsConsumed,
|
||||
},
|
||||
};
|
||||
if (_logger.IsLogEnabled(LogLevel.Debug))
|
||||
if (logger.IsLogEnabled(LogLevel.Debug))
|
||||
{
|
||||
_logger.Debug($"Air filter: {resourceValue} filter left on slot {i + 1}");
|
||||
logger.Debug($"Air filter: {resourceValue} filter left on slot {i + 1}");
|
||||
}
|
||||
|
||||
break; // Break here to avoid updating all filters
|
||||
@@ -1118,7 +1118,7 @@ public class HideoutHelper(
|
||||
{
|
||||
if (btcProduction is null)
|
||||
{
|
||||
_logger.Error(_serverLocalisationService.GetText("hideout-bitcoin_craft_missing"));
|
||||
logger.Error(serverLocalisationService.GetText("hideout-bitcoin_craft_missing"));
|
||||
|
||||
return;
|
||||
}
|
||||
@@ -1181,17 +1181,17 @@ public class HideoutHelper(
|
||||
return;
|
||||
}
|
||||
|
||||
var bitcoinProdData = _databaseService
|
||||
var bitcoinProdData = databaseService
|
||||
.GetHideout()
|
||||
.Production.Recipes.FirstOrDefault(production => production.Id == BitcoinProductionId);
|
||||
|
||||
// BSG finally fixed their settings, they now get loaded from the settings and used in the client
|
||||
var adjustedCraftTime =
|
||||
(
|
||||
_profileHelper.IsDeveloperAccount(pmcData.SessionId)
|
||||
profileHelper.IsDeveloperAccount(pmcData.SessionId)
|
||||
? 40
|
||||
: bitcoinProdData.ProductionTime
|
||||
) / (1 + (btcFarmCGs - 1) * _databaseService.GetHideout().Settings.GpuBoostRate);
|
||||
) / (1 + (btcFarmCGs - 1) * databaseService.GetHideout().Settings.GpuBoostRate);
|
||||
|
||||
// The progress should be adjusted based on the GPU boost rate, but the target is still the base productionTime
|
||||
var timeMultiplier = bitcoinProdData.ProductionTime / adjustedCraftTime;
|
||||
@@ -1212,7 +1212,7 @@ public class HideoutHelper(
|
||||
}
|
||||
}
|
||||
|
||||
btcProduction.StartTimestamp = _timeUtil.GetTimeStamp();
|
||||
btcProduction.StartTimestamp = timeUtil.GetTimeStamp();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -1249,11 +1249,11 @@ public class HideoutHelper(
|
||||
)
|
||||
{
|
||||
// Reduce time elapsed (and progress) when generator is off
|
||||
var timeElapsed = _timeUtil.GetTimeStamp() - pmcData.Hideout.SptUpdateLastRunTimestamp;
|
||||
var timeElapsed = timeUtil.GetTimeStamp() - pmcData.Hideout.SptUpdateLastRunTimestamp;
|
||||
|
||||
if (recipe is not null)
|
||||
{
|
||||
var hideoutArea = _databaseService
|
||||
var hideoutArea = databaseService
|
||||
.GetHideout()
|
||||
.Areas.FirstOrDefault(area => area.Type == recipe.AreaType);
|
||||
if (!(hideoutArea.NeedsFuel ?? false))
|
||||
@@ -1266,7 +1266,7 @@ public class HideoutHelper(
|
||||
if (!isGeneratorOn)
|
||||
{
|
||||
timeElapsed = (long)(
|
||||
timeElapsed * _databaseService.GetHideout().Settings.GeneratorSpeedWithoutFuel
|
||||
timeElapsed * databaseService.GetHideout().Settings.GeneratorSpeedWithoutFuel
|
||||
);
|
||||
}
|
||||
|
||||
@@ -1280,11 +1280,11 @@ public class HideoutHelper(
|
||||
/// <returns>Coin slot count</returns>
|
||||
protected double GetBTCSlots(PmcData pmcData)
|
||||
{
|
||||
var bitcoinProductions = _databaseService
|
||||
var bitcoinProductions = databaseService
|
||||
.GetHideout()
|
||||
.Production.Recipes.FirstOrDefault(production => production.Id == BitcoinProductionId);
|
||||
var productionSlots = bitcoinProductions?.ProductionLimitCount ?? 3; // Default to 3 if none found
|
||||
var hasManagementSkillSlots = _profileHelper.HasEliteSkillLevel(
|
||||
var hasManagementSkillSlots = profileHelper.HasEliteSkillLevel(
|
||||
SkillTypes.HideoutManagement,
|
||||
pmcData
|
||||
);
|
||||
@@ -1298,7 +1298,7 @@ public class HideoutHelper(
|
||||
/// </summary>
|
||||
protected double? GetEliteSkillAdditionalBitcoinSlotCount()
|
||||
{
|
||||
return _databaseService
|
||||
return databaseService
|
||||
.GetGlobals()
|
||||
.Configuration.SkillsSettings.HideoutManagement.EliteSlots.BitcoinFarm.Container;
|
||||
}
|
||||
@@ -1324,7 +1324,7 @@ public class HideoutHelper(
|
||||
roundedLevel = roundedLevel == 51 ? roundedLevel - 1 : roundedLevel;
|
||||
|
||||
return roundedLevel
|
||||
* _databaseService
|
||||
* databaseService
|
||||
.GetGlobals()
|
||||
.Configuration.SkillsSettings.HideoutManagement.ConsumptionReductionPerLevel
|
||||
/ 100;
|
||||
@@ -1392,7 +1392,7 @@ public class HideoutHelper(
|
||||
public void GetBTC(
|
||||
PmcData pmcData,
|
||||
HideoutTakeProductionRequestData request,
|
||||
string sessionId,
|
||||
MongoId sessionId,
|
||||
ItemEventRouterResponse output
|
||||
)
|
||||
{
|
||||
@@ -1401,10 +1401,10 @@ public class HideoutHelper(
|
||||
var craftedCoinCount = bitcoinCraft?.Products?.Count;
|
||||
if (bitcoinCraft is null || craftedCoinCount is null)
|
||||
{
|
||||
var errorMsg = _serverLocalisationService.GetText("hideout-no_bitcoins_to_collect");
|
||||
_logger.Error(errorMsg);
|
||||
var errorMsg = serverLocalisationService.GetText("hideout-no_bitcoins_to_collect");
|
||||
logger.Error(errorMsg);
|
||||
|
||||
_httpResponseUtil.AppendErrorToOutput(output, errorMsg);
|
||||
httpResponseUtil.AppendErrorToOutput(output, errorMsg);
|
||||
|
||||
return;
|
||||
}
|
||||
@@ -1434,7 +1434,7 @@ public class HideoutHelper(
|
||||
};
|
||||
|
||||
// Add FiR coins to player inventory
|
||||
_inventoryHelper.AddItemsToStash(sessionId, addItemsRequest, pmcData, output);
|
||||
inventoryHelper.AddItemsToStash(sessionId, addItemsRequest, pmcData, output);
|
||||
if (output.Warnings?.Count > 0)
|
||||
{
|
||||
return;
|
||||
@@ -1446,7 +1446,7 @@ public class HideoutHelper(
|
||||
// Set start to now
|
||||
{
|
||||
pmcData.Hideout.Production[BitcoinProductionId].StartTimestamp =
|
||||
_timeUtil.GetTimeStamp();
|
||||
timeUtil.GetTimeStamp();
|
||||
}
|
||||
|
||||
// Remove crafted coins from production in profile now they've been collected
|
||||
@@ -1484,7 +1484,7 @@ public class HideoutHelper(
|
||||
|
||||
if (
|
||||
improvementDetails.Completed == false
|
||||
&& improvementDetails.ImproveCompleteTimestamp < _timeUtil.GetTimeStamp()
|
||||
&& improvementDetails.ImproveCompleteTimestamp < timeUtil.GetTimeStamp()
|
||||
)
|
||||
{
|
||||
improvementDetails.Completed = true;
|
||||
@@ -1503,7 +1503,7 @@ public class HideoutHelper(
|
||||
);
|
||||
|
||||
// Get hideout area 16 bonus array
|
||||
var fameAreaDb = _databaseService
|
||||
var fameAreaDb = databaseService
|
||||
.GetHideout()
|
||||
.Areas.FirstOrDefault(area => area.Type == HideoutAreas.PlaceOfFame);
|
||||
|
||||
@@ -1584,9 +1584,9 @@ public class HideoutHelper(
|
||||
bonusIdsToRemove.Add(bonus.Id);
|
||||
}
|
||||
|
||||
if (_logger.IsLogEnabled(LogLevel.Debug))
|
||||
if (logger.IsLogEnabled(LogLevel.Debug))
|
||||
{
|
||||
_logger.Debug($"Removing: {bonusIdsToRemove.Count} bonuses from profile");
|
||||
logger.Debug($"Removing: {bonusIdsToRemove.Count} bonuses from profile");
|
||||
}
|
||||
|
||||
// Remove the wall bonuses from profile by id
|
||||
|
||||
@@ -13,10 +13,10 @@ namespace SPTarkov.Server.Core.Helpers;
|
||||
|
||||
[Injectable]
|
||||
public class InRaidHelper(
|
||||
InventoryHelper _inventoryHelper,
|
||||
ConfigServer _configServer,
|
||||
ICloner _cloner,
|
||||
DatabaseService _databaseService
|
||||
InventoryHelper inventoryHelper,
|
||||
ConfigServer configServer,
|
||||
ICloner cloner,
|
||||
DatabaseService databaseService
|
||||
)
|
||||
{
|
||||
protected static readonly List<string> _pocketSlots =
|
||||
@@ -26,9 +26,9 @@ public class InRaidHelper(
|
||||
"pocket3",
|
||||
"pocket4",
|
||||
];
|
||||
protected readonly InRaidConfig _inRaidConfig = _configServer.GetConfig<InRaidConfig>();
|
||||
protected readonly InRaidConfig _inRaidConfig = configServer.GetConfig<InRaidConfig>();
|
||||
protected readonly LostOnDeathConfig _lostOnDeathConfig =
|
||||
_configServer.GetConfig<LostOnDeathConfig>();
|
||||
configServer.GetConfig<LostOnDeathConfig>();
|
||||
|
||||
/// <summary>
|
||||
/// Deprecated. Reset the skill points earned in a raid to 0, ready for next raid.
|
||||
@@ -54,7 +54,7 @@ public class InRaidHelper(
|
||||
/// <param name="isSurvived">Indicates if the player survived the raid</param>
|
||||
/// <param name="isTransfer">Indicates if it is a transfer operation</param>
|
||||
public void SetInventory(
|
||||
string sessionID,
|
||||
MongoId sessionID,
|
||||
PmcData serverProfile,
|
||||
PmcData postRaidProfile,
|
||||
bool isSurvived,
|
||||
@@ -62,17 +62,17 @@ public class InRaidHelper(
|
||||
)
|
||||
{
|
||||
// Store insurance (as removeItem() removes insured items)
|
||||
var insured = _cloner.Clone(serverProfile.InsuredItems);
|
||||
var insured = cloner.Clone(serverProfile.InsuredItems);
|
||||
|
||||
// Remove equipment and loot items stored on player from server profile in preparation for data from client being added
|
||||
_inventoryHelper.RemoveItem(
|
||||
inventoryHelper.RemoveItem(
|
||||
serverProfile,
|
||||
serverProfile.Inventory.Equipment.Value,
|
||||
sessionID
|
||||
);
|
||||
|
||||
// Remove quest items stored on player from server profile in preparation for data from client being added
|
||||
_inventoryHelper.RemoveItem(
|
||||
inventoryHelper.RemoveItem(
|
||||
serverProfile,
|
||||
serverProfile.Inventory.QuestRaidItems.Value,
|
||||
sessionID
|
||||
@@ -111,7 +111,7 @@ public class InRaidHelper(
|
||||
/// <param name="items">Items to process</param>
|
||||
protected void RemoveFiRStatusFromItems(List<Item> items)
|
||||
{
|
||||
var dbItems = _databaseService.GetItems();
|
||||
var dbItems = databaseService.GetItems();
|
||||
|
||||
var itemsToRemovePropertyFrom = items.Where(item =>
|
||||
{
|
||||
@@ -166,7 +166,7 @@ public class InRaidHelper(
|
||||
/// </summary>
|
||||
/// <param name="pmcData">Player profile</param>
|
||||
/// <param name="sessionId">Session id</param>
|
||||
public void DeleteInventory(PmcData pmcData, string sessionId)
|
||||
public void DeleteInventory(PmcData pmcData, MongoId sessionId)
|
||||
{
|
||||
// Get inventory item ids to remove from players profile
|
||||
var itemIdsToDeleteFromProfile = GetInventoryItemsLostOnDeath(pmcData)
|
||||
@@ -174,7 +174,7 @@ public class InRaidHelper(
|
||||
foreach (var itemIdToDelete in itemIdsToDeleteFromProfile)
|
||||
// Items inside containers are handled as part of function
|
||||
{
|
||||
_inventoryHelper.RemoveItem(pmcData, itemIdToDelete, sessionId);
|
||||
inventoryHelper.RemoveItem(pmcData, itemIdToDelete, sessionId);
|
||||
}
|
||||
|
||||
// Remove contents of fast panel
|
||||
@@ -188,7 +188,7 @@ public class InRaidHelper(
|
||||
/// <param name="pmcData">Player profile</param>
|
||||
/// <param name="secureContainerSlotId">Container slot id to find items for and remove FiR from</param>
|
||||
public void RemoveFiRStatusFromItemsInContainer(
|
||||
string sessionId,
|
||||
MongoId sessionId,
|
||||
PmcData pmcData,
|
||||
string secureContainerSlotId
|
||||
)
|
||||
|
||||
@@ -22,15 +22,15 @@ namespace SPTarkov.Server.Core.Helpers;
|
||||
|
||||
[Injectable]
|
||||
public class InventoryHelper(
|
||||
ISptLogger<InventoryHelper> _logger,
|
||||
HttpResponseUtil _httpResponseUtil,
|
||||
DialogueHelper _dialogueHelper,
|
||||
EventOutputHolder _eventOutputHolder,
|
||||
ProfileHelper _profileHelper,
|
||||
ItemHelper _itemHelper,
|
||||
ServerLocalisationService _serverLocalisationService,
|
||||
ConfigServer _configServer,
|
||||
ICloner _cloner
|
||||
ISptLogger<InventoryHelper> logger,
|
||||
HttpResponseUtil httpResponseUtil,
|
||||
DialogueHelper dialogueHelper,
|
||||
EventOutputHolder eventOutputHolder,
|
||||
ProfileHelper profileHelper,
|
||||
ItemHelper itemHelper,
|
||||
ServerLocalisationService serverLocalisationService,
|
||||
ConfigServer configServer,
|
||||
ICloner cloner
|
||||
)
|
||||
{
|
||||
private static readonly FrozenSet<MongoId> _variableSizeItemTypes =
|
||||
@@ -39,8 +39,7 @@ public class InventoryHelper(
|
||||
BaseClasses.FUNCTIONAL_MOD,
|
||||
BaseClasses.MOD,
|
||||
];
|
||||
protected readonly InventoryConfig _inventoryConfig =
|
||||
_configServer.GetConfig<InventoryConfig>();
|
||||
protected readonly InventoryConfig _inventoryConfig = configServer.GetConfig<InventoryConfig>();
|
||||
|
||||
/// <summary>
|
||||
/// Add multiple items to player stash (assuming they all fit)
|
||||
@@ -50,7 +49,7 @@ public class InventoryHelper(
|
||||
/// <param name="pmcData">Player profile</param>
|
||||
/// <param name="output">Client response object</param>
|
||||
public void AddItemsToStash(
|
||||
string sessionId,
|
||||
MongoId sessionId,
|
||||
AddItemsDirectRequest request,
|
||||
PmcData pmcData,
|
||||
ItemEventRouterResponse output
|
||||
@@ -60,9 +59,9 @@ public class InventoryHelper(
|
||||
if (!CanPlaceItemsInInventory(sessionId, request.ItemsWithModsToAdd))
|
||||
{
|
||||
// No space, exit
|
||||
_httpResponseUtil.AppendErrorToOutput(
|
||||
httpResponseUtil.AppendErrorToOutput(
|
||||
output,
|
||||
_serverLocalisationService.GetText("inventory-no_stash_space"),
|
||||
serverLocalisationService.GetText("inventory-no_stash_space"),
|
||||
BackendErrorCodes.NotEnoughSpace
|
||||
);
|
||||
|
||||
@@ -96,19 +95,19 @@ public class InventoryHelper(
|
||||
/// <param name="pmcData">Player profile</param>
|
||||
/// <param name="output">Client response object</param>
|
||||
public void AddItemToStash(
|
||||
string sessionId,
|
||||
MongoId sessionId,
|
||||
AddItemDirectRequest request,
|
||||
PmcData pmcData,
|
||||
ItemEventRouterResponse output
|
||||
)
|
||||
{
|
||||
var itemWithModsToAddClone = _cloner.Clone(request.ItemWithModsToAdd);
|
||||
var itemWithModsToAddClone = cloner.Clone(request.ItemWithModsToAdd);
|
||||
|
||||
// Get stash layouts ready for use
|
||||
var stashFS2D = GetStashSlotMap(pmcData);
|
||||
if (stashFS2D is null)
|
||||
{
|
||||
_logger.Error($"Unable to get stash map for players: {sessionId} stash");
|
||||
logger.Error($"Unable to get stash map for players: {sessionId} stash");
|
||||
|
||||
return;
|
||||
}
|
||||
@@ -148,8 +147,8 @@ public class InventoryHelper(
|
||||
{
|
||||
// Callback failed
|
||||
var message = ex.Message;
|
||||
_httpResponseUtil.AppendErrorToOutput(output, message);
|
||||
_logger.Error($"[InventoryHelper]: {ex.Message}");
|
||||
httpResponseUtil.AppendErrorToOutput(output, message);
|
||||
logger.Error($"[InventoryHelper]: {ex.Message}");
|
||||
|
||||
return;
|
||||
}
|
||||
@@ -159,9 +158,9 @@ public class InventoryHelper(
|
||||
output.ProfileChanges[sessionId].Items.NewItems.AddRange(itemWithModsToAddClone);
|
||||
pmcData.Inventory.Items.AddRange(itemWithModsToAddClone);
|
||||
|
||||
if (_logger.IsLogEnabled(LogLevel.Debug))
|
||||
if (logger.IsLogEnabled(LogLevel.Debug))
|
||||
{
|
||||
_logger.Debug(
|
||||
logger.Debug(
|
||||
$"Added: {itemWithModsToAddClone[0].Upd?.StackObjectsCount ?? 1} item: {itemWithModsToAddClone[0].Template} with: {itemWithModsToAddClone.Count - 1} mods to inventory"
|
||||
);
|
||||
}
|
||||
@@ -177,10 +176,10 @@ public class InventoryHelper(
|
||||
foreach (var item in itemWithChildren)
|
||||
{
|
||||
// Ensure item has upd object
|
||||
_itemHelper.AddUpdObjectToItem(item);
|
||||
itemHelper.AddUpdObjectToItem(item);
|
||||
|
||||
// Ammo / currency can NEVER be FiR or have a 'SpawnedInSession' property
|
||||
item.Upd.SpawnedInSession = _itemHelper.IsOfBaseclass(item.Template, BaseClasses.AMMO)
|
||||
item.Upd.SpawnedInSession = itemHelper.IsOfBaseclass(item.Template, BaseClasses.AMMO)
|
||||
? null
|
||||
: foundInRaid;
|
||||
}
|
||||
@@ -216,12 +215,12 @@ public class InventoryHelper(
|
||||
/// <returns>True all items fit</returns>
|
||||
public bool CanPlaceItemsInInventory(string sessionId, List<List<Item>> itemsWithChildren)
|
||||
{
|
||||
var pmcData = _profileHelper.GetPmcProfile(sessionId);
|
||||
var pmcData = profileHelper.GetPmcProfile(sessionId);
|
||||
|
||||
var stashFS2D = _cloner.Clone(GetStashSlotMap(pmcData));
|
||||
var stashFS2D = cloner.Clone(GetStashSlotMap(pmcData));
|
||||
if (stashFS2D is null)
|
||||
{
|
||||
_logger.Error($"Unable to get stash map for players: {sessionId} stash");
|
||||
logger.Error($"Unable to get stash map for players: {sessionId} stash");
|
||||
|
||||
return false;
|
||||
}
|
||||
@@ -273,8 +272,8 @@ public class InventoryHelper(
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
_logger.Error(
|
||||
_serverLocalisationService.GetText(
|
||||
logger.Error(
|
||||
serverLocalisationService.GetText(
|
||||
"inventory-unable_to_fit_item_into_inventory",
|
||||
ex.Message
|
||||
)
|
||||
@@ -328,11 +327,8 @@ public class InventoryHelper(
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
_logger.Error(
|
||||
_serverLocalisationService.GetText(
|
||||
"inventory-fill_container_failed",
|
||||
ex.Message
|
||||
)
|
||||
logger.Error(
|
||||
serverLocalisationService.GetText("inventory-fill_container_failed", ex.Message)
|
||||
);
|
||||
|
||||
return;
|
||||
@@ -449,9 +445,9 @@ public class InventoryHelper(
|
||||
}
|
||||
else
|
||||
{
|
||||
_httpResponseUtil.AppendErrorToOutput(
|
||||
httpResponseUtil.AppendErrorToOutput(
|
||||
output,
|
||||
_serverLocalisationService.GetText("inventory-no_stash_space"),
|
||||
serverLocalisationService.GetText("inventory-no_stash_space"),
|
||||
BackendErrorCodes.NotEnoughSpace
|
||||
);
|
||||
}
|
||||
@@ -459,13 +455,13 @@ public class InventoryHelper(
|
||||
|
||||
protected void HandleContainerPlacementError(string errorText, ItemEventRouterResponse output)
|
||||
{
|
||||
_logger.Error(
|
||||
_serverLocalisationService.GetText("inventory-fill_container_failed", errorText)
|
||||
logger.Error(
|
||||
serverLocalisationService.GetText("inventory-fill_container_failed", errorText)
|
||||
);
|
||||
|
||||
_httpResponseUtil.AppendErrorToOutput(
|
||||
httpResponseUtil.AppendErrorToOutput(
|
||||
output,
|
||||
_serverLocalisationService.GetText("inventory-no_stash_space")
|
||||
serverLocalisationService.GetText("inventory-no_stash_space")
|
||||
);
|
||||
}
|
||||
|
||||
@@ -481,14 +477,14 @@ public class InventoryHelper(
|
||||
public void RemoveItem(
|
||||
PmcData profile,
|
||||
MongoId itemId,
|
||||
string sessionId,
|
||||
MongoId sessionId,
|
||||
ItemEventRouterResponse? output = null
|
||||
)
|
||||
{
|
||||
if (itemId.IsEmpty())
|
||||
{
|
||||
_logger.Warning(
|
||||
_serverLocalisationService.GetText("inventory-unable_to_remove_item_no_id_given")
|
||||
logger.Warning(
|
||||
serverLocalisationService.GetText("inventory-unable_to_remove_item_no_id_given")
|
||||
);
|
||||
|
||||
return;
|
||||
@@ -498,10 +494,10 @@ public class InventoryHelper(
|
||||
var itemAndChildrenToRemove = profile.Inventory.Items.FindAndReturnChildrenAsItems(itemId);
|
||||
if (!itemAndChildrenToRemove.Any())
|
||||
{
|
||||
if (_logger.IsLogEnabled(LogLevel.Debug))
|
||||
if (logger.IsLogEnabled(LogLevel.Debug))
|
||||
{
|
||||
_logger.Debug(
|
||||
_serverLocalisationService.GetText(
|
||||
logger.Debug(
|
||||
serverLocalisationService.GetText(
|
||||
"inventory-unable_to_remove_item_id_not_found",
|
||||
new { ChildId = itemId, ProfileId = profile.Id }
|
||||
)
|
||||
@@ -530,8 +526,8 @@ public class InventoryHelper(
|
||||
}
|
||||
else
|
||||
{
|
||||
_logger.Warning(
|
||||
_serverLocalisationService.GetText(
|
||||
logger.Warning(
|
||||
serverLocalisationService.GetText(
|
||||
"inventory-unable_to_remove_item_id_not_found",
|
||||
new { childId = item.Id, ProfileId = profile.Id }
|
||||
)
|
||||
@@ -555,12 +551,12 @@ public class InventoryHelper(
|
||||
/// <param name="removeRequest">Remove request</param>
|
||||
/// <param name="output">OPTIONAL - ItemEventRouterResponse</param>
|
||||
public void RemoveItemAndChildrenFromMailRewards(
|
||||
string sessionId,
|
||||
MongoId sessionId,
|
||||
InventoryRemoveRequestData removeRequest,
|
||||
ItemEventRouterResponse? output
|
||||
)
|
||||
{
|
||||
var fullProfile = _profileHelper.GetFullProfile(sessionId);
|
||||
var fullProfile = profileHelper.GetFullProfile(sessionId);
|
||||
|
||||
// Iterate over all dialogs and look for mesasage with key from request, that has item (and maybe its children) we want to remove
|
||||
var dialogs = fullProfile.DialogueRecords;
|
||||
@@ -581,8 +577,8 @@ public class InventoryHelper(
|
||||
var indexOfItemToRemove = messageWithReward.Items.Data.IndexOf(itemToDelete);
|
||||
if (indexOfItemToRemove == -1)
|
||||
{
|
||||
_logger.Error(
|
||||
_serverLocalisationService.GetText(
|
||||
logger.Error(
|
||||
serverLocalisationService.GetText(
|
||||
"inventory-unable_to_remove_item_restart_immediately",
|
||||
new
|
||||
{
|
||||
@@ -619,7 +615,7 @@ public class InventoryHelper(
|
||||
PmcData pmcData,
|
||||
MongoId itemId,
|
||||
int countToRemove,
|
||||
string sessionId,
|
||||
MongoId sessionId,
|
||||
ItemEventRouterResponse? output
|
||||
)
|
||||
{
|
||||
@@ -658,7 +654,7 @@ public class InventoryHelper(
|
||||
}
|
||||
}
|
||||
|
||||
return output ?? _eventOutputHolder.GetOutput(sessionId);
|
||||
return output ?? eventOutputHolder.GetOutput(sessionId);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -689,21 +685,18 @@ public class InventoryHelper(
|
||||
)
|
||||
{
|
||||
// Invalid item
|
||||
var (isValidItem, itemTemplate) = _itemHelper.GetItem(itemTpl);
|
||||
var (isValidItem, itemTemplate) = itemHelper.GetItem(itemTpl);
|
||||
if (!isValidItem)
|
||||
{
|
||||
_logger.Error(
|
||||
_serverLocalisationService.GetText(
|
||||
"inventory-invalid_item_missing_from_db",
|
||||
itemTpl
|
||||
)
|
||||
logger.Error(
|
||||
serverLocalisationService.GetText("inventory-invalid_item_missing_from_db", itemTpl)
|
||||
);
|
||||
}
|
||||
|
||||
// Item found but no _props property
|
||||
if (isValidItem && itemTemplate.Properties is null)
|
||||
{
|
||||
_serverLocalisationService.GetText(
|
||||
serverLocalisationService.GetText(
|
||||
"inventory-item_missing_props_property",
|
||||
new { itemTpl, itemName = itemTemplate?.Name }
|
||||
);
|
||||
@@ -713,8 +706,8 @@ public class InventoryHelper(
|
||||
if (!isValidItem && itemTemplate is null)
|
||||
{
|
||||
// return default size of 1x1
|
||||
_logger.Error(
|
||||
_serverLocalisationService.GetText("inventory-return_default_size", itemTpl)
|
||||
logger.Error(
|
||||
serverLocalisationService.GetText("inventory-return_default_size", itemTpl)
|
||||
);
|
||||
|
||||
return (1, 1); // Invalid input data, return defaults
|
||||
@@ -722,7 +715,7 @@ public class InventoryHelper(
|
||||
|
||||
if (!inventoryItemHash.ByItemId.TryGetValue(itemId, out var rootItem))
|
||||
{
|
||||
_logger.Error(
|
||||
logger.Error(
|
||||
$"Unable to get root item with Id: {itemId} from player inventory. Defaulting to 1x1"
|
||||
);
|
||||
|
||||
@@ -757,7 +750,7 @@ public class InventoryHelper(
|
||||
}
|
||||
|
||||
// Item can have child items that adjust its size
|
||||
if (_itemHelper.IsOfBaseclasses(itemTpl, _variableSizeItemTypes))
|
||||
if (itemHelper.IsOfBaseclasses(itemTpl, _variableSizeItemTypes))
|
||||
{
|
||||
// Storage for root item and its children, store root item id for now
|
||||
// Will store child items that may have sub-children to process
|
||||
@@ -781,11 +774,11 @@ public class InventoryHelper(
|
||||
toDo.Enqueue(childItem.Id);
|
||||
|
||||
// Get child item from db
|
||||
var (isValid, template) = _itemHelper.GetItem(childItem.Template);
|
||||
var (isValid, template) = itemHelper.GetItem(childItem.Template);
|
||||
if (!isValid)
|
||||
{
|
||||
_logger.Error(
|
||||
_serverLocalisationService.GetText(
|
||||
logger.Error(
|
||||
serverLocalisationService.GetText(
|
||||
"inventory-get_item_size_item_not_found_by_tpl",
|
||||
childItem.Template
|
||||
)
|
||||
@@ -866,11 +859,11 @@ public class InventoryHelper(
|
||||
int containerSizeHorizontalX,
|
||||
int containerSizeVerticalY,
|
||||
List<Item> itemList,
|
||||
string containerId
|
||||
MongoId containerId
|
||||
)
|
||||
{
|
||||
// Create blank 2d map of container
|
||||
var container = _itemHelper.GetBlankContainerMap(
|
||||
var container = itemHelper.GetBlankContainerMap(
|
||||
containerSizeHorizontalX, // Column count
|
||||
containerSizeVerticalY // Row count
|
||||
);
|
||||
@@ -892,7 +885,7 @@ public class InventoryHelper(
|
||||
if (itemLocation is null)
|
||||
{
|
||||
// Item has no location property
|
||||
_logger.Error(
|
||||
logger.Error(
|
||||
$"Unable to find 'location' property on item with id: {rootItem.Id}, skipping"
|
||||
);
|
||||
|
||||
@@ -937,8 +930,8 @@ public class InventoryHelper(
|
||||
var message =
|
||||
$"Item: {rootItem.Id} at: {itemLocation.X}, {itemLocation.Y} size: {itemHeight}x{itemWidth} extends outside the containers bounds";
|
||||
|
||||
_logger.Error(
|
||||
_serverLocalisationService.GetText(
|
||||
logger.Error(
|
||||
serverLocalisationService.GetText(
|
||||
"inventory-unable_to_fill_container",
|
||||
new { id = rootItem.Id, error = $"{message}" }
|
||||
)
|
||||
@@ -998,11 +991,11 @@ public class InventoryHelper(
|
||||
public OwnerInventoryItems GetOwnerInventoryItems(
|
||||
InventoryBaseActionRequestData request,
|
||||
MongoId itemId,
|
||||
string sessionId
|
||||
MongoId sessionId
|
||||
)
|
||||
{
|
||||
var pmcItems = _profileHelper.GetPmcProfile(sessionId).Inventory.Items;
|
||||
var scavProfile = _profileHelper.GetScavProfile(sessionId);
|
||||
var pmcItems = profileHelper.GetPmcProfile(sessionId).Inventory.Items;
|
||||
var scavProfile = profileHelper.GetScavProfile(sessionId);
|
||||
var fromInventoryItems = pmcItems;
|
||||
var fromType = "pmc";
|
||||
|
||||
@@ -1018,7 +1011,7 @@ public class InventoryHelper(
|
||||
)
|
||||
{
|
||||
// Split requests don't use 'use' but 'splitItem' property
|
||||
fromInventoryItems = _dialogueHelper.GetMessageItemContents(
|
||||
fromInventoryItems = dialogueHelper.GetMessageItemContents(
|
||||
request.FromOwner.Id,
|
||||
sessionId,
|
||||
itemId
|
||||
@@ -1064,7 +1057,7 @@ public class InventoryHelper(
|
||||
horizontal,
|
||||
vertical,
|
||||
pmcData.Inventory.Items,
|
||||
pmcData.Inventory.Stash
|
||||
pmcData.Inventory.Stash.Value
|
||||
);
|
||||
}
|
||||
|
||||
@@ -1075,16 +1068,13 @@ public class InventoryHelper(
|
||||
/// <returns>blank two-dimensional array</returns>
|
||||
public int[,] GetContainerSlotMap(string containerTpl)
|
||||
{
|
||||
var containerTemplate = _itemHelper.GetItem(containerTpl).Value;
|
||||
var containerTemplate = itemHelper.GetItem(containerTpl).Value;
|
||||
|
||||
var firstContainerGrid = containerTemplate.Properties.Grids.FirstOrDefault();
|
||||
var containerRowCount = firstContainerGrid.Props.CellsH;
|
||||
var containerColumnCount = firstContainerGrid.Props.CellsV;
|
||||
|
||||
return _itemHelper.GetBlankContainerMap(
|
||||
containerColumnCount.Value,
|
||||
containerRowCount.Value
|
||||
);
|
||||
return itemHelper.GetBlankContainerMap(containerColumnCount.Value, containerRowCount.Value);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -1094,7 +1084,12 @@ public class InventoryHelper(
|
||||
/// <returns>two-dimensional array</returns>
|
||||
protected int[,] GetSortingTableSlotMap(PmcData pmcData)
|
||||
{
|
||||
return GetContainerMap(10, 45, pmcData.Inventory.Items, pmcData.Inventory.SortingTable);
|
||||
return GetContainerMap(
|
||||
10,
|
||||
45,
|
||||
pmcData.Inventory.Items,
|
||||
pmcData.Inventory.SortingTable.Value
|
||||
);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -1109,18 +1104,16 @@ public class InventoryHelper(
|
||||
var stashTpl = GetProfileStashTpl(pmcData);
|
||||
if (stashTpl is null)
|
||||
{
|
||||
_logger.Error(_serverLocalisationService.GetText("inventory-missing_stash_size"));
|
||||
logger.Error(serverLocalisationService.GetText("inventory-missing_stash_size"));
|
||||
|
||||
return (0, 0);
|
||||
}
|
||||
|
||||
// Look up details of stash in db
|
||||
var (isValidItem, stashItemDbItem) = _itemHelper.GetItem(stashTpl);
|
||||
var (isValidItem, stashItemDbItem) = itemHelper.GetItem(stashTpl);
|
||||
if (!isValidItem)
|
||||
{
|
||||
_logger.Error(
|
||||
_serverLocalisationService.GetText("inventory-stash_not_found", stashTpl)
|
||||
);
|
||||
logger.Error(serverLocalisationService.GetText("inventory-stash_not_found", stashTpl));
|
||||
|
||||
return (0, 0);
|
||||
}
|
||||
@@ -1156,7 +1149,7 @@ public class InventoryHelper(
|
||||
);
|
||||
if (stashObj is null)
|
||||
{
|
||||
_logger.Error(_serverLocalisationService.GetText("inventory-unable_to_find_stash"));
|
||||
logger.Error(serverLocalisationService.GetText("inventory-unable_to_find_stash"));
|
||||
}
|
||||
|
||||
return stashObj?.Template;
|
||||
@@ -1183,8 +1176,8 @@ public class InventoryHelper(
|
||||
var itemToMove = sourceItems.FirstOrDefault(item => item.Id == itemId);
|
||||
if (itemToMove is null)
|
||||
{
|
||||
_logger.Error(
|
||||
_serverLocalisationService.GetText(
|
||||
logger.Error(
|
||||
serverLocalisationService.GetText(
|
||||
"inventory-unable_to_find_item_to_move",
|
||||
itemId
|
||||
)
|
||||
@@ -1241,15 +1234,15 @@ public class InventoryHelper(
|
||||
{
|
||||
var noMatchingItemMesage =
|
||||
$"Unable to move item: {moveRequest.Item}, cannot find in inventory";
|
||||
_logger.Error(noMatchingItemMesage);
|
||||
logger.Error(noMatchingItemMesage);
|
||||
|
||||
errorMessage = noMatchingItemMesage;
|
||||
return false;
|
||||
}
|
||||
|
||||
if (_logger.IsLogEnabled(LogLevel.Debug))
|
||||
if (logger.IsLogEnabled(LogLevel.Debug))
|
||||
{
|
||||
_logger.Debug(
|
||||
logger.Debug(
|
||||
$"{moveRequest.Action} item: {moveRequest.Item} from slotid: {matchingInventoryItem.SlotId} to container: {moveRequest.To.Container}"
|
||||
);
|
||||
}
|
||||
@@ -1260,8 +1253,8 @@ public class InventoryHelper(
|
||||
&& moveRequest.To.Container == "cartridges"
|
||||
)
|
||||
{
|
||||
_logger.Warning(
|
||||
_serverLocalisationService.GetText(
|
||||
logger.Warning(
|
||||
serverLocalisationService.GetText(
|
||||
"inventory-invalid_move_to_container",
|
||||
new
|
||||
{
|
||||
@@ -1380,7 +1373,7 @@ public class InventoryHelper(
|
||||
.ToList();
|
||||
foreach (var message in errors)
|
||||
{
|
||||
_logger.Error(message);
|
||||
logger.Error(message);
|
||||
}
|
||||
|
||||
throw new Exception(
|
||||
|
||||
@@ -1439,7 +1439,7 @@ public class ItemHelper(
|
||||
0
|
||||
].Filter?.FirstOrDefault();
|
||||
ammoBox.Add(
|
||||
CreateCartridges(ammoBox[0].Id, cartridgeTpl, (int)ammoBoxMaxCartridgeCount, 0)
|
||||
CreateCartridges(ammoBox[0].Id, cartridgeTpl.Value, (int)ammoBoxMaxCartridgeCount, 0)
|
||||
);
|
||||
}
|
||||
|
||||
@@ -1459,7 +1459,7 @@ public class ItemHelper(
|
||||
Dictionary<string, List<StaticAmmoDetails>> staticAmmoDist,
|
||||
string? caliber = null,
|
||||
double minSizePercent = 0.25,
|
||||
string? defaultCartridgeTpl = null,
|
||||
MongoId? defaultCartridgeTpl = null,
|
||||
TemplateItem? weapon = null
|
||||
)
|
||||
{
|
||||
@@ -1504,7 +1504,7 @@ public class ItemHelper(
|
||||
public void FillMagazineWithCartridge(
|
||||
List<Item> magazineWithChildCartridges,
|
||||
TemplateItem magTemplate,
|
||||
string cartridgeTpl,
|
||||
MongoId cartridgeTpl,
|
||||
double minSizeMultiplier = 0.25
|
||||
)
|
||||
{
|
||||
@@ -1624,7 +1624,7 @@ public class ItemHelper(
|
||||
protected string? DrawAmmoTpl(
|
||||
string caliber,
|
||||
Dictionary<string, List<StaticAmmoDetails>> staticAmmoDist,
|
||||
string? fallbackCartridgeTpl = null,
|
||||
MongoId? fallbackCartridgeTpl = null,
|
||||
ICollection<MongoId>? cartridgeWhitelist = null
|
||||
)
|
||||
{
|
||||
@@ -1677,7 +1677,7 @@ public class ItemHelper(
|
||||
/// <param name="stackCount">Count of cartridges inside parent</param>
|
||||
/// <param name="location">Location inside parent (e.g. 0, 1)</param>
|
||||
/// <returns>Item</returns>
|
||||
public Item CreateCartridges(string parentId, string ammoTpl, int stackCount, double location)
|
||||
public Item CreateCartridges(MongoId parentId, MongoId ammoTpl, int stackCount, double location)
|
||||
{
|
||||
return new Item
|
||||
{
|
||||
@@ -1957,7 +1957,7 @@ public class ItemHelper(
|
||||
);
|
||||
}
|
||||
|
||||
public string? GetItemBaseType(MongoId tpl, bool rootOnly = true)
|
||||
public MongoId? GetItemBaseType(MongoId tpl, bool rootOnly = true)
|
||||
{
|
||||
var result = GetItem(tpl);
|
||||
if (!result.Key)
|
||||
@@ -1992,7 +1992,7 @@ public class ItemHelper(
|
||||
/// Get a 2D grid of a container's item slots
|
||||
/// </summary>
|
||||
/// <param name="containerTpl">Tpl id of the container</param>
|
||||
public int[,] GetContainerMapping(string containerTpl)
|
||||
public int[,] GetContainerMapping(MongoId containerTpl)
|
||||
{
|
||||
// Get template from db
|
||||
var containerTemplate = GetItem(containerTpl).Value;
|
||||
|
||||
@@ -14,12 +14,12 @@ namespace SPTarkov.Server.Core.Helpers;
|
||||
|
||||
[Injectable]
|
||||
public class NotificationSendHelper(
|
||||
ISptLogger<NotificationSendHelper> _logger,
|
||||
SptWebSocketConnectionHandler _sptWebSocketConnectionHandler,
|
||||
SaveServer _saveServer,
|
||||
NotificationService _notificationService,
|
||||
TimeUtil _timeUtil,
|
||||
JsonUtil _jsonUtil
|
||||
ISptLogger<NotificationSendHelper> logger,
|
||||
SptWebSocketConnectionHandler sptWebSocketConnectionHandler,
|
||||
SaveServer saveServer,
|
||||
NotificationService notificationService,
|
||||
TimeUtil timeUtil,
|
||||
JsonUtil jsonUtil
|
||||
)
|
||||
{
|
||||
/// <summary>
|
||||
@@ -27,33 +27,33 @@ public class NotificationSendHelper(
|
||||
/// </summary>
|
||||
/// <param name="sessionID">Session/player id</param>
|
||||
/// <param name="notificationMessage"></param>
|
||||
public void SendMessage(string sessionID, WsNotificationEvent notificationMessage)
|
||||
public void SendMessage(MongoId sessionID, WsNotificationEvent notificationMessage)
|
||||
{
|
||||
if (_logger.IsLogEnabled(LogLevel.Debug))
|
||||
if (logger.IsLogEnabled(LogLevel.Debug))
|
||||
{
|
||||
_logger.Debug(
|
||||
$"Send message for {sessionID} started, message: {_jsonUtil.Serialize(notificationMessage)}"
|
||||
logger.Debug(
|
||||
$"Send message for {sessionID} started, message: {jsonUtil.Serialize(notificationMessage)}"
|
||||
);
|
||||
}
|
||||
if (_sptWebSocketConnectionHandler.IsWebSocketConnected(sessionID))
|
||||
if (sptWebSocketConnectionHandler.IsWebSocketConnected(sessionID))
|
||||
{
|
||||
if (_logger.IsLogEnabled(LogLevel.Debug))
|
||||
if (logger.IsLogEnabled(LogLevel.Debug))
|
||||
{
|
||||
_logger.Debug(
|
||||
logger.Debug(
|
||||
$"Send message for {sessionID} websocket available, message being sent"
|
||||
);
|
||||
}
|
||||
_sptWebSocketConnectionHandler.SendMessage(sessionID, notificationMessage);
|
||||
sptWebSocketConnectionHandler.SendMessage(sessionID, notificationMessage);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (_logger.IsLogEnabled(LogLevel.Debug))
|
||||
if (logger.IsLogEnabled(LogLevel.Debug))
|
||||
{
|
||||
_logger.Debug(
|
||||
logger.Debug(
|
||||
$"Send message for {sessionID} websocket not available, queuing into profile"
|
||||
);
|
||||
}
|
||||
_notificationService.Add(sessionID, notificationMessage);
|
||||
notificationService.Add(sessionID, notificationMessage);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -65,7 +65,7 @@ public class NotificationSendHelper(
|
||||
/// <param name="messageText">Text to send player</param>
|
||||
/// <param name="messageType">Underlying type of message being sent</param>
|
||||
public void SendMessageToPlayer(
|
||||
string sessionId,
|
||||
MongoId sessionId,
|
||||
UserDialogInfo senderDetails,
|
||||
string messageText,
|
||||
MessageType messageType
|
||||
@@ -79,7 +79,7 @@ public class NotificationSendHelper(
|
||||
Id = new MongoId(),
|
||||
UserId = dialog.Id,
|
||||
MessageType = messageType,
|
||||
DateTime = _timeUtil.GetTimeStamp(),
|
||||
DateTime = timeUtil.GetTimeStamp(),
|
||||
Text = messageText,
|
||||
HasRewards = null,
|
||||
RewardCollected = null,
|
||||
@@ -105,7 +105,7 @@ public class NotificationSendHelper(
|
||||
/// <param name="senderDetails">Who is sending the message</param>
|
||||
/// <returns>Dialogue</returns>
|
||||
protected Models.Eft.Profile.Dialogue GetDialog(
|
||||
string sessionId,
|
||||
MongoId sessionId,
|
||||
MessageType messageType,
|
||||
UserDialogInfo senderDetails
|
||||
)
|
||||
@@ -114,7 +114,7 @@ public class NotificationSendHelper(
|
||||
var dialogKey = senderDetails.Id;
|
||||
|
||||
// Get all dialogs with pmcs/traders player has
|
||||
var dialogueData = _saveServer.GetProfile(sessionId).DialogueRecords;
|
||||
var dialogueData = saveServer.GetProfile(sessionId).DialogueRecords;
|
||||
|
||||
// Ensure empty dialog exists based on sender details passed in
|
||||
dialogueData.TryAdd(
|
||||
|
||||
@@ -9,10 +9,10 @@ using SPTarkov.Server.Core.Utils.Cloners;
|
||||
namespace SPTarkov.Server.Core.Helpers;
|
||||
|
||||
[Injectable(InjectionType.Singleton)]
|
||||
public class PresetHelper(DatabaseService _databaseService, ItemHelper _itemHelper, ICloner _cloner)
|
||||
public class PresetHelper(DatabaseService databaseService, ItemHelper itemHelper, ICloner cloner)
|
||||
{
|
||||
protected Dictionary<string, Preset> _defaultEquipmentPresets;
|
||||
protected Dictionary<string, Preset> _defaultWeaponPresets;
|
||||
protected Dictionary<string, Preset>? _defaultEquipmentPresets;
|
||||
protected Dictionary<string, Preset>? _defaultWeaponPresets;
|
||||
|
||||
/// <summary>
|
||||
/// Preset cache - key = item tpl, value = preset ids
|
||||
@@ -60,11 +60,11 @@ public class PresetHelper(DatabaseService _databaseService, ItemHelper _itemHelp
|
||||
{
|
||||
if (_defaultWeaponPresets is null)
|
||||
{
|
||||
var tempPresets = _databaseService.GetGlobals().ItemPresets;
|
||||
var tempPresets = databaseService.GetGlobals().ItemPresets;
|
||||
_defaultWeaponPresets = tempPresets
|
||||
.Where(p =>
|
||||
p.Value.Encyclopedia != null
|
||||
&& _itemHelper.IsOfBaseclass(p.Value.Encyclopedia, BaseClasses.WEAPON)
|
||||
&& itemHelper.IsOfBaseclass(p.Value.Encyclopedia, BaseClasses.WEAPON)
|
||||
)
|
||||
.ToDictionary();
|
||||
}
|
||||
@@ -80,11 +80,11 @@ public class PresetHelper(DatabaseService _databaseService, ItemHelper _itemHelp
|
||||
{
|
||||
if (_defaultEquipmentPresets == null)
|
||||
{
|
||||
var tempPresets = _databaseService.GetGlobals().ItemPresets;
|
||||
var tempPresets = databaseService.GetGlobals().ItemPresets;
|
||||
_defaultEquipmentPresets = tempPresets
|
||||
.Where(p =>
|
||||
p.Value.Encyclopedia != null
|
||||
&& _itemHelper.ArmorItemCanHoldMods(p.Value.Encyclopedia)
|
||||
&& itemHelper.ArmorItemCanHoldMods(p.Value.Encyclopedia)
|
||||
)
|
||||
.ToDictionary();
|
||||
}
|
||||
@@ -97,14 +97,14 @@ public class PresetHelper(DatabaseService _databaseService, ItemHelper _itemHelp
|
||||
/// </summary>
|
||||
/// <param name="id">Value to check</param>
|
||||
/// <returns>True = preset exists for this id</returns>
|
||||
public bool IsPreset(string id)
|
||||
public bool IsPreset(MongoId id)
|
||||
{
|
||||
if (string.IsNullOrEmpty(id))
|
||||
if (id.IsEmpty())
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
return _databaseService.GetGlobals().ItemPresets.ContainsKey(id);
|
||||
return databaseService.GetGlobals().ItemPresets.ContainsKey(id);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -113,9 +113,9 @@ public class PresetHelper(DatabaseService _databaseService, ItemHelper _itemHelp
|
||||
* @param baseClass The BaseClasses enum to check against
|
||||
* @returns True if the preset is of the given base class, false otherwise
|
||||
*/
|
||||
public bool IsPresetBaseClass(string id, MongoId baseClass)
|
||||
public bool IsPresetBaseClass(MongoId id, MongoId baseClass)
|
||||
{
|
||||
return IsPreset(id) && _itemHelper.IsOfBaseclass(GetPreset(id).Encyclopedia, baseClass);
|
||||
return IsPreset(id) && itemHelper.IsOfBaseclass(GetPreset(id).Encyclopedia, baseClass);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -128,9 +128,9 @@ public class PresetHelper(DatabaseService _databaseService, ItemHelper _itemHelp
|
||||
return _lookup.ContainsKey(templateId);
|
||||
}
|
||||
|
||||
public Preset GetPreset(string id)
|
||||
public Preset GetPreset(MongoId id)
|
||||
{
|
||||
return _cloner.Clone(_databaseService.GetGlobals().ItemPresets[id]);
|
||||
return cloner.Clone(databaseService.GetGlobals().ItemPresets[id]);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -139,7 +139,7 @@ public class PresetHelper(DatabaseService _databaseService, ItemHelper _itemHelp
|
||||
/// <returns>List</returns>
|
||||
public List<Preset> GetAllPresets()
|
||||
{
|
||||
return _cloner.Clone(_databaseService.GetGlobals().ItemPresets.Values.ToList());
|
||||
return cloner.Clone(databaseService.GetGlobals().ItemPresets.Values.ToList());
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -147,7 +147,7 @@ public class PresetHelper(DatabaseService _databaseService, ItemHelper _itemHelp
|
||||
/// </summary>
|
||||
/// <param name="templateId">Tpl to get presets for</param>
|
||||
/// <returns>List</returns>
|
||||
public List<Preset> GetPresets(string templateId)
|
||||
public List<Preset> GetPresets(MongoId templateId)
|
||||
{
|
||||
// Try adn get preset ids from cache if they exist
|
||||
if (!_lookup.TryGetValue(templateId, out var presetDetailsForTpl))
|
||||
@@ -157,9 +157,9 @@ public class PresetHelper(DatabaseService _databaseService, ItemHelper _itemHelp
|
||||
}
|
||||
|
||||
// Use gathered preset ids to get full preset objects, clone and return
|
||||
return _cloner.Clone(
|
||||
return cloner.Clone(
|
||||
presetDetailsForTpl
|
||||
.PresetIds.Select(x => _databaseService.GetGlobals().ItemPresets[x])
|
||||
.PresetIds.Select(x => databaseService.GetGlobals().ItemPresets[x])
|
||||
.ToList()
|
||||
);
|
||||
}
|
||||
@@ -188,13 +188,13 @@ public class PresetHelper(DatabaseService _databaseService, ItemHelper _itemHelp
|
||||
if (!_defaultEquipmentPresets.TryGetValue(presetDetails.DefaultId, out defaultPreset))
|
||||
{
|
||||
// Default not found in weapon or equipment, return first preset in list
|
||||
return _cloner.Clone(
|
||||
_databaseService.GetGlobals().ItemPresets[presetDetails.PresetIds.First()]
|
||||
return cloner.Clone(
|
||||
databaseService.GetGlobals().ItemPresets[presetDetails.PresetIds.First()]
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
return _cloner.Clone(defaultPreset);
|
||||
return cloner.Clone(defaultPreset);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -204,7 +204,7 @@ public class PresetHelper(DatabaseService _databaseService, ItemHelper _itemHelp
|
||||
/// <returns>tpl mongoid</returns>
|
||||
public MongoId GetBaseItemTpl(MongoId presetId)
|
||||
{
|
||||
if (!_databaseService.GetGlobals().ItemPresets.TryGetValue(presetId, out var preset))
|
||||
if (!databaseService.GetGlobals().ItemPresets.TryGetValue(presetId, out var preset))
|
||||
{
|
||||
// No preset exists
|
||||
return "";
|
||||
@@ -236,6 +236,6 @@ public class PresetHelper(DatabaseService _databaseService, ItemHelper _itemHelp
|
||||
: [tpl];
|
||||
|
||||
// Get price of tpls
|
||||
return _itemHelper.GetItemAndChildrenPrice(tpls);
|
||||
return itemHelper.GetItemAndChildrenPrice(tpls);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
using SPTarkov.DI.Annotations;
|
||||
using SPTarkov.Server.Core.Extensions;
|
||||
using SPTarkov.Server.Core.Models.Common;
|
||||
using SPTarkov.Server.Core.Models.Eft.Common.Tables;
|
||||
using SPTarkov.Server.Core.Models.Eft.Profile;
|
||||
using SPTarkov.Server.Core.Models.Enums;
|
||||
@@ -10,32 +11,15 @@ using SPTarkov.Server.Core.Utils;
|
||||
namespace SPTarkov.Server.Core.Helpers;
|
||||
|
||||
[Injectable]
|
||||
public class PrestigeHelper
|
||||
public class PrestigeHelper(
|
||||
ISptLogger<PrestigeHelper> logger,
|
||||
TimeUtil timeUtil,
|
||||
DatabaseService databaseService,
|
||||
MailSendService mailSendService,
|
||||
ProfileHelper profileHelper,
|
||||
RewardHelper rewardHelper
|
||||
)
|
||||
{
|
||||
protected DatabaseService _databaseService;
|
||||
protected ISptLogger<PrestigeHelper> _logger;
|
||||
protected MailSendService _mailSendService;
|
||||
protected ProfileHelper _profileHelper;
|
||||
protected RewardHelper _rewardHelper;
|
||||
protected TimeUtil _timeUtil;
|
||||
|
||||
public PrestigeHelper(
|
||||
ISptLogger<PrestigeHelper> logger,
|
||||
TimeUtil timeUtil,
|
||||
DatabaseService databaseService,
|
||||
MailSendService mailSendService,
|
||||
ProfileHelper profileHelper,
|
||||
RewardHelper rewardHelper
|
||||
)
|
||||
{
|
||||
_logger = logger;
|
||||
_timeUtil = timeUtil;
|
||||
_databaseService = databaseService;
|
||||
_mailSendService = mailSendService;
|
||||
_profileHelper = profileHelper;
|
||||
_rewardHelper = rewardHelper;
|
||||
}
|
||||
|
||||
public void ProcessPendingPrestige(
|
||||
SptProfile oldProfile,
|
||||
SptProfile newProfile,
|
||||
@@ -92,23 +76,22 @@ public class PrestigeHelper
|
||||
// Add "Prestigious" achievement
|
||||
if (!newProfile.CharacterData.PmcData.Achievements.ContainsKey("676091c0f457869a94017a23"))
|
||||
{
|
||||
_rewardHelper.AddAchievementToProfile(newProfile, "676091c0f457869a94017a23");
|
||||
rewardHelper.AddAchievementToProfile(newProfile, "676091c0f457869a94017a23");
|
||||
}
|
||||
|
||||
// Assumes Prestige data is in descending order
|
||||
var currentPrestigeData = _databaseService.GetTemplates().Prestige.Elements[
|
||||
var currentPrestigeData = databaseService.GetTemplates().Prestige.Elements[
|
||||
indexOfPrestigeObtained
|
||||
];
|
||||
var prestigeRewards = _databaseService
|
||||
var prestigeRewards = databaseService
|
||||
.GetTemplates()
|
||||
.Prestige.Elements.Slice(0, indexOfPrestigeObtained + 1)
|
||||
.SelectMany(prestige => prestige.Rewards);
|
||||
|
||||
AddPrestigeRewardsToProfile(sessionId, newProfile, prestigeRewards);
|
||||
AddPrestigeRewardsToProfile(sessionId.Value, newProfile, prestigeRewards);
|
||||
|
||||
// Flag profile as having achieved this prestige level
|
||||
newProfile.CharacterData.PmcData.Prestige[currentPrestigeData.Id] =
|
||||
_timeUtil.GetTimeStamp();
|
||||
newProfile.CharacterData.PmcData.Prestige[currentPrestigeData.Id] = timeUtil.GetTimeStamp();
|
||||
|
||||
var itemsToTransfer = new List<Item>();
|
||||
|
||||
@@ -120,7 +103,7 @@ public class PrestigeHelper
|
||||
);
|
||||
if (item is null)
|
||||
{
|
||||
_logger.Error(
|
||||
logger.Error(
|
||||
$"Unable to find item with id: {transferRequest.Id} in profile: {sessionId}, skipping"
|
||||
);
|
||||
continue;
|
||||
@@ -129,13 +112,13 @@ public class PrestigeHelper
|
||||
itemsToTransfer.Add(item);
|
||||
}
|
||||
|
||||
_mailSendService.SendSystemMessageToPlayer(sessionId.Value, "", itemsToTransfer, 31536000);
|
||||
mailSendService.SendSystemMessageToPlayer(sessionId.Value, "", itemsToTransfer, 31536000);
|
||||
|
||||
newProfile.CharacterData.PmcData.Info.PrestigeLevel = prestige.PrestigeLevel;
|
||||
}
|
||||
|
||||
private void AddPrestigeRewardsToProfile(
|
||||
string sessionId,
|
||||
MongoId sessionId,
|
||||
SptProfile newProfile,
|
||||
IEnumerable<Reward> rewards
|
||||
)
|
||||
@@ -148,7 +131,7 @@ public class PrestigeHelper
|
||||
{
|
||||
case RewardType.CustomizationDirect:
|
||||
{
|
||||
_profileHelper.AddHideoutCustomisationUnlock(
|
||||
profileHelper.AddHideoutCustomisationUnlock(
|
||||
newProfile,
|
||||
reward,
|
||||
CustomisationSource.PRESTIGE
|
||||
@@ -158,7 +141,7 @@ public class PrestigeHelper
|
||||
case RewardType.Skill:
|
||||
if (Enum.TryParse(reward.Target, out SkillTypes result))
|
||||
{
|
||||
_profileHelper.AddSkillPointsToPlayer(
|
||||
profileHelper.AddSkillPointsToPlayer(
|
||||
newProfile.CharacterData.PmcData,
|
||||
result,
|
||||
reward.Value
|
||||
@@ -166,7 +149,7 @@ public class PrestigeHelper
|
||||
}
|
||||
else
|
||||
{
|
||||
_logger.Error($"Unable to parse reward Target to Enum: {reward.Target}");
|
||||
logger.Error($"Unable to parse reward Target to Enum: {reward.Target}");
|
||||
}
|
||||
|
||||
break;
|
||||
@@ -181,14 +164,14 @@ public class PrestigeHelper
|
||||
break;
|
||||
}
|
||||
default:
|
||||
_logger.Error($"Unhandled prestige reward type: {reward.Type}");
|
||||
logger.Error($"Unhandled prestige reward type: {reward.Type}");
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (itemsToSend.Count > 0)
|
||||
{
|
||||
_mailSendService.SendSystemMessageToPlayer(sessionId, "", itemsToSend, 31536000);
|
||||
mailSendService.SendSystemMessageToPlayer(sessionId, "", itemsToSend, 31536000);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -18,14 +18,14 @@ namespace SPTarkov.Server.Core.Helpers;
|
||||
|
||||
[Injectable]
|
||||
public class ProfileHelper(
|
||||
ISptLogger<ProfileHelper> _logger,
|
||||
ICloner _cloner,
|
||||
SaveServer _saveServer,
|
||||
DatabaseService _databaseService,
|
||||
Watermark _watermark,
|
||||
TimeUtil _timeUtil,
|
||||
ServerLocalisationService _serverLocalisationService,
|
||||
ConfigServer _configServer
|
||||
ISptLogger<ProfileHelper> logger,
|
||||
ICloner cloner,
|
||||
SaveServer saveServer,
|
||||
DatabaseService databaseService,
|
||||
Watermark watermark,
|
||||
TimeUtil timeUtil,
|
||||
ServerLocalisationService serverLocalisationService,
|
||||
ConfigServer configServer
|
||||
)
|
||||
{
|
||||
protected static readonly FrozenSet<string> _gameEditionsWithFreeRefresh =
|
||||
@@ -33,8 +33,7 @@ public class ProfileHelper(
|
||||
"edge_of_darkness",
|
||||
"unheard_edition",
|
||||
];
|
||||
protected readonly InventoryConfig _inventoryConfig =
|
||||
_configServer.GetConfig<InventoryConfig>();
|
||||
protected readonly InventoryConfig _inventoryConfig = configServer.GetConfig<InventoryConfig>();
|
||||
|
||||
/// <summary>
|
||||
/// Remove/reset a completed quest condition from players profile quest data
|
||||
@@ -64,7 +63,7 @@ public class ProfileHelper(
|
||||
/// <returns>Dictionary of profiles</returns>
|
||||
public Dictionary<MongoId, SptProfile> GetProfiles()
|
||||
{
|
||||
return _saveServer.GetProfiles();
|
||||
return saveServer.GetProfiles();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -81,7 +80,7 @@ public class ProfileHelper(
|
||||
return output;
|
||||
}
|
||||
|
||||
var FullProfileClone = _cloner.Clone(GetFullProfile(sessionId));
|
||||
var FullProfileClone = cloner.Clone(GetFullProfile(sessionId));
|
||||
|
||||
// Sanitize any data the client can not receive
|
||||
SanitizeProfileForClient(FullProfileClone);
|
||||
@@ -115,7 +114,7 @@ public class ProfileHelper(
|
||||
/// <returns>True if already in use</returns>
|
||||
public bool IsNicknameTaken(ValidateNicknameRequestData nicknameRequest, MongoId sessionID)
|
||||
{
|
||||
var allProfiles = _saveServer.GetProfiles().Values;
|
||||
var allProfiles = saveServer.GetProfiles().Values;
|
||||
|
||||
// Find a profile that doesn't have same session id but has same name
|
||||
return allProfiles.Any(p =>
|
||||
@@ -153,7 +152,7 @@ public class ProfileHelper(
|
||||
}
|
||||
else
|
||||
{
|
||||
_logger.Error($"Profile {sessionID} does not exist");
|
||||
logger.Error($"Profile {sessionID} does not exist");
|
||||
}
|
||||
}
|
||||
|
||||
@@ -162,12 +161,12 @@ public class ProfileHelper(
|
||||
/// </summary>
|
||||
/// <param name="pmcId">Profile id to find</param>
|
||||
/// <returns>PmcData</returns>
|
||||
public PmcData? GetProfileByPmcId(string pmcId)
|
||||
public PmcData? GetProfileByPmcId(MongoId pmcId)
|
||||
{
|
||||
return _saveServer
|
||||
return saveServer
|
||||
.GetProfiles()
|
||||
.Values.First(p => p.CharacterData?.PmcData?.Id == pmcId)
|
||||
.CharacterData.PmcData;
|
||||
.CharacterData?.PmcData;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -178,7 +177,7 @@ public class ProfileHelper(
|
||||
public int? GetExperience(int level)
|
||||
{
|
||||
var playerLevel = level;
|
||||
var expTable = _databaseService.GetGlobals().Configuration.Exp.Level.ExperienceTable;
|
||||
var expTable = databaseService.GetGlobals().Configuration.Exp.Level.ExperienceTable;
|
||||
int? exp = 0;
|
||||
|
||||
if (playerLevel >= expTable.Length) // make sure to not go out of bounds
|
||||
@@ -200,7 +199,7 @@ public class ProfileHelper(
|
||||
/// <returns>Max level</returns>
|
||||
public int GetMaxLevel()
|
||||
{
|
||||
return _databaseService.GetGlobals().Configuration.Exp.Level.ExperienceTable.Length - 1;
|
||||
return databaseService.GetGlobals().Configuration.Exp.Level.ExperienceTable.Length - 1;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -211,7 +210,7 @@ public class ProfileHelper(
|
||||
{
|
||||
return new Spt
|
||||
{
|
||||
Version = _watermark.GetVersionTag(true),
|
||||
Version = watermark.GetVersionTag(true),
|
||||
Mods = [],
|
||||
ReceivedGifts = [],
|
||||
BlacklistedItemTemplates = [],
|
||||
@@ -230,7 +229,7 @@ public class ProfileHelper(
|
||||
/// <returns>SptProfile object</returns>
|
||||
public SptProfile? GetFullProfile(MongoId sessionID)
|
||||
{
|
||||
return _saveServer.ProfileExists(sessionID) ? _saveServer.GetProfile(sessionID) : null;
|
||||
return saveServer.ProfileExists(sessionID) ? saveServer.GetProfile(sessionID) : null;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -243,13 +242,10 @@ public class ProfileHelper(
|
||||
var check = int.TryParse(accountId, out var aid);
|
||||
if (!check)
|
||||
{
|
||||
_logger.Error($"Account {accountId} does not exist");
|
||||
logger.Error($"Account {accountId} does not exist");
|
||||
}
|
||||
|
||||
return _saveServer
|
||||
.GetProfiles()
|
||||
.FirstOrDefault(p => p.Value?.ProfileInfo?.Aid == aid)
|
||||
.Value;
|
||||
return saveServer.GetProfiles().FirstOrDefault(p => p.Value?.ProfileInfo?.Aid == aid).Value;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -308,7 +304,7 @@ public class ProfileHelper(
|
||||
/// UNUSED?
|
||||
public bool IsPlayer(MongoId userId)
|
||||
{
|
||||
return _saveServer.ProfileExists(userId);
|
||||
return saveServer.ProfileExists(userId);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -318,7 +314,7 @@ public class ProfileHelper(
|
||||
/// <returns>IPmcData object</returns>
|
||||
public PmcData? GetScavProfile(MongoId sessionID)
|
||||
{
|
||||
return _saveServer.GetProfile(sessionID).CharacterData?.ScavData;
|
||||
return saveServer.GetProfile(sessionID).CharacterData?.ScavData;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -362,7 +358,7 @@ public class ProfileHelper(
|
||||
/// TODO: logic doesn't feel right to have IsWiped being nullable
|
||||
protected bool IsWiped(MongoId sessionID)
|
||||
{
|
||||
return _saveServer.GetProfile(sessionID)?.ProfileInfo?.IsWiped ?? false;
|
||||
return saveServer.GetProfile(sessionID)?.ProfileInfo?.IsWiped ?? false;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -417,7 +413,7 @@ public class ProfileHelper(
|
||||
new ReceivedGift
|
||||
{
|
||||
GiftId = giftId,
|
||||
TimestampLastAccepted = _timeUtil.GetTimeStamp(),
|
||||
TimestampLastAccepted = timeUtil.GetTimeStamp(),
|
||||
Current = 1,
|
||||
}
|
||||
);
|
||||
@@ -435,9 +431,9 @@ public class ProfileHelper(
|
||||
var profile = GetFullProfile(playerId);
|
||||
if (profile == null)
|
||||
{
|
||||
if (_logger.IsLogEnabled(LogLevel.Debug))
|
||||
if (logger.IsLogEnabled(LogLevel.Debug))
|
||||
{
|
||||
_logger.Debug($"Unable to gift {giftId}, Profile: {playerId} does not exist");
|
||||
logger.Debug($"Unable to gift {giftId}, Profile: {playerId} does not exist");
|
||||
}
|
||||
|
||||
return false;
|
||||
@@ -486,7 +482,7 @@ public class ProfileHelper(
|
||||
var profileSkill = profileSkills.FirstOrDefault(s => s.Id == skill);
|
||||
if (profileSkill == null)
|
||||
{
|
||||
_logger.Error(_serverLocalisationService.GetText("quest-no_skill_found", skill));
|
||||
logger.Error(serverLocalisationService.GetText("quest-no_skill_found", skill));
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -509,8 +505,8 @@ public class ProfileHelper(
|
||||
{
|
||||
if (pointsToAddToSkill < 0D)
|
||||
{
|
||||
_logger.Warning(
|
||||
_serverLocalisationService.GetText(
|
||||
logger.Warning(
|
||||
serverLocalisationService.GetText(
|
||||
"player-attempt_to_increment_skill_with_negative_value",
|
||||
skill
|
||||
)
|
||||
@@ -521,7 +517,7 @@ public class ProfileHelper(
|
||||
var profileSkills = pmcProfile?.Skills?.Common;
|
||||
if (profileSkills == null)
|
||||
{
|
||||
_logger.Warning(
|
||||
logger.Warning(
|
||||
$"Unable to add: {pointsToAddToSkill} points to {skill}, Profile has no skills"
|
||||
);
|
||||
return;
|
||||
@@ -530,13 +526,13 @@ public class ProfileHelper(
|
||||
var profileSkill = profileSkills.FirstOrDefault(s => s.Id == skill);
|
||||
if (profileSkill == null)
|
||||
{
|
||||
_logger.Error(_serverLocalisationService.GetText("quest-no_skill_found", skill));
|
||||
logger.Error(serverLocalisationService.GetText("quest-no_skill_found", skill));
|
||||
return;
|
||||
}
|
||||
|
||||
if (useSkillProgressRateMultiplier)
|
||||
{
|
||||
var skillProgressRate = _databaseService
|
||||
var skillProgressRate = databaseService
|
||||
.GetGlobals()
|
||||
.Configuration.SkillsSettings.SkillProgressRate;
|
||||
pointsToAddToSkill *= skillProgressRate;
|
||||
@@ -553,7 +549,7 @@ public class ProfileHelper(
|
||||
profileSkill.PointsEarnedDuringSession ??= 0;
|
||||
profileSkill.PointsEarnedDuringSession += pointsToAddToSkill;
|
||||
|
||||
profileSkill.LastAccess = _timeUtil.GetTimeStamp();
|
||||
profileSkill.LastAccess = timeUtil.GetTimeStamp();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -619,7 +615,7 @@ public class ProfileHelper(
|
||||
var pockets = pmcProfile.Inventory.Items.Where(i => i.SlotId == "Pockets");
|
||||
if (!pockets.Any())
|
||||
{
|
||||
_logger.Error(
|
||||
logger.Error(
|
||||
$"Unable to replace profile: {pmcProfile.Id} pocket tpl with: {newPocketTpl} as Pocket item could not be found."
|
||||
);
|
||||
return;
|
||||
@@ -647,7 +643,7 @@ public class ProfileHelper(
|
||||
if (itemAndChildren?.Count > 0)
|
||||
{
|
||||
// To get the client to actually see the items, we set the main item's parent to null, so it's treated as a root item
|
||||
var clonedItems = _cloner.Clone(itemAndChildren);
|
||||
var clonedItems = cloner.Clone(itemAndChildren);
|
||||
clonedItems.First().ParentId = null;
|
||||
|
||||
fullFavorites.AddRange(clonedItems);
|
||||
@@ -666,13 +662,13 @@ public class ProfileHelper(
|
||||
|
||||
if (fullProfile?.CustomisationUnlocks?.Any(u => u.Id == reward.Target) ?? false)
|
||||
{
|
||||
_logger.Warning(
|
||||
logger.Warning(
|
||||
$"Profile: {fullProfile.ProfileInfo.ProfileId} already has hideout customisation reward: {reward.Target}, skipping"
|
||||
);
|
||||
return;
|
||||
}
|
||||
|
||||
var customisationTemplateDb = _databaseService.GetTemplates().Customization;
|
||||
var customisationTemplateDb = databaseService.GetTemplates().Customization;
|
||||
var matchingCustomisation = customisationTemplateDb.GetValueOrDefault(reward.Target, null);
|
||||
|
||||
if (matchingCustomisation is not null)
|
||||
@@ -711,7 +707,7 @@ public class ProfileHelper(
|
||||
rewardToStore.Type = CustomisationType.SHOOTING_RANGE_MARK;
|
||||
break;
|
||||
default:
|
||||
_logger.Error(
|
||||
logger.Error(
|
||||
$"Unhandled customisation unlock type: {matchingCustomisation.Parent} not added to profile"
|
||||
);
|
||||
return;
|
||||
@@ -729,7 +725,7 @@ public class ProfileHelper(
|
||||
/// <returns></returns>
|
||||
public TemplateSide GetProfileTemplateForSide(string accountEdition, string side)
|
||||
{
|
||||
var profileTemplates = _databaseService.GetProfileTemplates();
|
||||
var profileTemplates = databaseService.GetProfileTemplates();
|
||||
|
||||
// Get matching profile 'type' e.g. 'standard'
|
||||
profileTemplates.TryGetValue(accountEdition, out var matchingProfileTemplate);
|
||||
|
||||
@@ -22,20 +22,20 @@ namespace SPTarkov.Server.Core.Helpers;
|
||||
|
||||
[Injectable(InjectionType.Singleton)]
|
||||
public class QuestHelper(
|
||||
ISptLogger<QuestHelper> _logger,
|
||||
TimeUtil _timeUtil,
|
||||
ItemHelper _itemHelper,
|
||||
DatabaseService _databaseService,
|
||||
EventOutputHolder _eventOutputHolder,
|
||||
LocaleService _localeService,
|
||||
ProfileHelper _profileHelper,
|
||||
QuestRewardHelper _questRewardHelper,
|
||||
RewardHelper _rewardHelper,
|
||||
ServerLocalisationService _serverLocalisationService,
|
||||
SeasonalEventService _seasonalEventService,
|
||||
MailSendService _mailSendService,
|
||||
ConfigServer _configServer,
|
||||
ICloner _cloner
|
||||
ISptLogger<QuestHelper> logger,
|
||||
TimeUtil timeUtil,
|
||||
ItemHelper itemHelper,
|
||||
DatabaseService databaseService,
|
||||
EventOutputHolder eventOutputHolder,
|
||||
LocaleService localeService,
|
||||
ProfileHelper profileHelper,
|
||||
QuestRewardHelper questRewardHelper,
|
||||
RewardHelper rewardHelper,
|
||||
ServerLocalisationService serverLocalisationService,
|
||||
SeasonalEventService seasonalEventService,
|
||||
MailSendService mailSendService,
|
||||
ConfigServer configServer,
|
||||
ICloner cloner
|
||||
)
|
||||
{
|
||||
protected readonly HashSet<QuestStatusEnum> _startedOrAvailToFinish =
|
||||
@@ -43,7 +43,7 @@ public class QuestHelper(
|
||||
QuestStatusEnum.Started,
|
||||
QuestStatusEnum.AvailableForFinish,
|
||||
];
|
||||
protected readonly QuestConfig _questConfig = _configServer.GetConfig<QuestConfig>();
|
||||
protected readonly QuestConfig _questConfig = configServer.GetConfig<QuestConfig>();
|
||||
private Dictionary<string, List<QuestCondition>>? _sellToTraderQuestConditionCache;
|
||||
|
||||
/// <summary>
|
||||
@@ -85,8 +85,8 @@ public class QuestHelper(
|
||||
case "=":
|
||||
return playerLevel == conditionValue;
|
||||
default:
|
||||
_logger.Error(
|
||||
_serverLocalisationService.GetText(
|
||||
logger.Error(
|
||||
serverLocalisationService.GetText(
|
||||
"quest-unable_to_find_compare_condition",
|
||||
condition.CompareMethod
|
||||
)
|
||||
@@ -147,16 +147,16 @@ public class QuestHelper(
|
||||
{
|
||||
// Calculate how much progress to add, limiting it to the current level max progress
|
||||
var currentLevelRemainingProgress = (currentLevel + 1) * 10 - startingLevelProgress;
|
||||
if (_logger.IsLogEnabled(LogLevel.Debug))
|
||||
if (logger.IsLogEnabled(LogLevel.Debug))
|
||||
{
|
||||
_logger.Debug($"currentLevelRemainingProgress: {currentLevelRemainingProgress}");
|
||||
logger.Debug($"currentLevelRemainingProgress: {currentLevelRemainingProgress}");
|
||||
}
|
||||
|
||||
var progressToAdd = Math.Min(remainingProgress, currentLevelRemainingProgress ?? 0);
|
||||
var adjustedProgressToAdd = 10 / (currentLevel + 1) * progressToAdd;
|
||||
if (_logger.IsLogEnabled(LogLevel.Debug))
|
||||
if (logger.IsLogEnabled(LogLevel.Debug))
|
||||
{
|
||||
_logger.Debug(
|
||||
logger.Debug(
|
||||
$"Progress To Add: {progressToAdd} Adjusted for level: {adjustedProgressToAdd}"
|
||||
);
|
||||
}
|
||||
@@ -185,7 +185,7 @@ public class QuestHelper(
|
||||
public string GetQuestNameFromLocale(string questId)
|
||||
{
|
||||
var questNameKey = $"{questId} name";
|
||||
return _localeService.GetLocaleDb().GetValueOrDefault(questNameKey, "UNKNOWN");
|
||||
return localeService.GetLocaleDb().GetValueOrDefault(questNameKey, "UNKNOWN");
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -205,8 +205,8 @@ public class QuestHelper(
|
||||
)
|
||||
)
|
||||
{
|
||||
_logger.Error(
|
||||
_serverLocalisationService.GetText(
|
||||
logger.Error(
|
||||
serverLocalisationService.GetText(
|
||||
"quest-unable_to_find_trader_in_profile",
|
||||
questProperties.Target
|
||||
)
|
||||
@@ -238,8 +238,8 @@ public class QuestHelper(
|
||||
)
|
||||
)
|
||||
{
|
||||
_logger.Error(
|
||||
_serverLocalisationService.GetText(
|
||||
logger.Error(
|
||||
serverLocalisationService.GetText(
|
||||
"quest-unable_to_find_trader_in_profile",
|
||||
questProperties.Target
|
||||
)
|
||||
@@ -278,8 +278,8 @@ public class QuestHelper(
|
||||
return current == required;
|
||||
|
||||
default:
|
||||
_logger.Error(
|
||||
_serverLocalisationService.GetText(
|
||||
logger.Error(
|
||||
serverLocalisationService.GetText(
|
||||
"quest-compare_operator_unhandled",
|
||||
compareMethod
|
||||
)
|
||||
@@ -309,7 +309,7 @@ public class QuestHelper(
|
||||
AcceptQuestRequestData acceptedQuest
|
||||
)
|
||||
{
|
||||
var currentTimestamp = _timeUtil.GetTimeStamp();
|
||||
var currentTimestamp = timeUtil.GetTimeStamp();
|
||||
var existingQuest = pmcData.Quests.FirstOrDefault(q => q.QId == acceptedQuest.QuestId);
|
||||
if (existingQuest is not null)
|
||||
{
|
||||
@@ -340,8 +340,8 @@ public class QuestHelper(
|
||||
var questDbData = GetQuestFromDb(acceptedQuest.QuestId, pmcData);
|
||||
if (questDbData is null)
|
||||
{
|
||||
_logger.Error(
|
||||
_serverLocalisationService.GetText(
|
||||
logger.Error(
|
||||
serverLocalisationService.GetText(
|
||||
"quest-unable_to_find_quest_in_db",
|
||||
new { questId = acceptedQuest.QuestId, questType = acceptedQuest.Type }
|
||||
)
|
||||
@@ -374,12 +374,12 @@ public class QuestHelper(
|
||||
/// <param name="sessionID">Session/Player id</param>
|
||||
/// <returns>Quests accessible to player including newly unlocked quests now quest (startedQuestId) was started</returns>
|
||||
public List<Quest> GetNewlyAccessibleQuestsWhenStartingQuest(
|
||||
string startedQuestId,
|
||||
string sessionID
|
||||
MongoId startedQuestId,
|
||||
MongoId sessionID
|
||||
)
|
||||
{
|
||||
// Get quest acceptance data from profile
|
||||
var profile = _profileHelper.GetPmcProfile(sessionID);
|
||||
var profile = profileHelper.GetPmcProfile(sessionID);
|
||||
var startedQuestInProfile = profile.Quests.FirstOrDefault(profileQuest =>
|
||||
profileQuest.QId == startedQuestId
|
||||
);
|
||||
@@ -479,15 +479,15 @@ public class QuestHelper(
|
||||
/// </summary>
|
||||
/// <param name="questId">Quest to check</param>
|
||||
/// <returns>true = show to player</returns>
|
||||
public bool ShowEventQuestToPlayer(string questId)
|
||||
public bool ShowEventQuestToPlayer(MongoId questId)
|
||||
{
|
||||
var isChristmasEventActive = _seasonalEventService.ChristmasEventEnabled();
|
||||
var isHalloweenEventActive = _seasonalEventService.HalloweenEventEnabled();
|
||||
var isChristmasEventActive = seasonalEventService.ChristmasEventEnabled();
|
||||
var isHalloweenEventActive = seasonalEventService.HalloweenEventEnabled();
|
||||
|
||||
// Not christmas + quest is for christmas
|
||||
if (
|
||||
!isChristmasEventActive
|
||||
&& _seasonalEventService.IsQuestRelatedToEvent(questId, SeasonalEventType.Christmas)
|
||||
&& seasonalEventService.IsQuestRelatedToEvent(questId, SeasonalEventType.Christmas)
|
||||
)
|
||||
{
|
||||
return false;
|
||||
@@ -496,7 +496,7 @@ public class QuestHelper(
|
||||
// Not halloween + quest is for halloween
|
||||
if (
|
||||
!isHalloweenEventActive
|
||||
&& _seasonalEventService.IsQuestRelatedToEvent(questId, SeasonalEventType.Halloween)
|
||||
&& seasonalEventService.IsQuestRelatedToEvent(questId, SeasonalEventType.Halloween)
|
||||
)
|
||||
{
|
||||
return false;
|
||||
@@ -505,7 +505,7 @@ public class QuestHelper(
|
||||
// Should non-season event quests be shown to player
|
||||
if (
|
||||
!_questConfig.ShowNonSeasonalEventQuests
|
||||
&& _seasonalEventService.IsQuestRelatedToEvent(questId, SeasonalEventType.None)
|
||||
&& seasonalEventService.IsQuestRelatedToEvent(questId, SeasonalEventType.None)
|
||||
)
|
||||
{
|
||||
return false;
|
||||
@@ -520,7 +520,7 @@ public class QuestHelper(
|
||||
/// <param name="playerSide">Player side (usec/bear)</param>
|
||||
/// <param name="questId">QuestId to check</param>
|
||||
/// <returns>true = quest isn't for player</returns>
|
||||
public bool QuestIsForOtherSide(string playerSide, string questId)
|
||||
public bool QuestIsForOtherSide(string playerSide, MongoId questId)
|
||||
{
|
||||
var isUsec = string.Equals(playerSide, "usec", StringComparison.OrdinalIgnoreCase);
|
||||
if (isUsec && _questConfig.BearOnlyQuests.Contains(questId))
|
||||
@@ -546,9 +546,9 @@ public class QuestHelper(
|
||||
/// <param name="gameVersion">Game version to check against</param>
|
||||
/// <param name="questId">Quest id to check</param>
|
||||
/// <returns>True = Quest should not be visible to game version</returns>
|
||||
protected bool QuestIsProfileBlacklisted(string gameVersion, string questId)
|
||||
protected bool QuestIsProfileBlacklisted(string gameVersion, MongoId questId)
|
||||
{
|
||||
var questBlacklist = _questConfig.ProfileBlacklist?.GetValueOrDefault(gameVersion);
|
||||
var questBlacklist = _questConfig.ProfileBlacklist.GetValueOrDefault(gameVersion);
|
||||
if (questBlacklist is null)
|
||||
{
|
||||
// Not blacklisted
|
||||
@@ -565,7 +565,7 @@ public class QuestHelper(
|
||||
/// <param name="gameVersion">Game version to check against</param>
|
||||
/// <param name="questId">Quest id to check</param>
|
||||
/// <returns>True = Quest should be visible to game version</returns>
|
||||
protected bool QuestIsProfileWhitelisted(string gameVersion, string questId)
|
||||
protected bool QuestIsProfileWhitelisted(string gameVersion, MongoId questId)
|
||||
{
|
||||
var questBlacklist = _questConfig.ProfileBlacklist.GetValueOrDefault(gameVersion);
|
||||
if (questBlacklist is null)
|
||||
@@ -583,9 +583,9 @@ public class QuestHelper(
|
||||
/// <param name="failedQuestId">Id of the quest failed by player</param>
|
||||
/// <param name="sessionId">Session/Player id</param>
|
||||
/// <returns>List of Quest</returns>
|
||||
public List<Quest> FailedUnlocked(string failedQuestId, string sessionId)
|
||||
public List<Quest> FailedUnlocked(MongoId failedQuestId, MongoId sessionId)
|
||||
{
|
||||
var profile = _profileHelper.GetPmcProfile(sessionId);
|
||||
var profile = profileHelper.GetPmcProfile(sessionId);
|
||||
var profileQuest = profile.Quests.FirstOrDefault(x => x.QId == failedQuestId);
|
||||
|
||||
var quests = GetQuestsFromDb()
|
||||
@@ -626,7 +626,7 @@ public class QuestHelper(
|
||||
PmcData pmcData,
|
||||
MongoId itemId,
|
||||
int newStackSize,
|
||||
string sessionID,
|
||||
MongoId sessionID,
|
||||
ItemEventRouterResponse output
|
||||
)
|
||||
{
|
||||
@@ -634,8 +634,8 @@ public class QuestHelper(
|
||||
var inventoryItemIndex = pmcData.Inventory.Items.FindIndex(item => item.Id == itemId);
|
||||
if (inventoryItemIndex < 0)
|
||||
{
|
||||
_logger.Error(
|
||||
_serverLocalisationService.GetText("quest-item_not_found_in_inventory", itemId)
|
||||
logger.Error(
|
||||
serverLocalisationService.GetText("quest-item_not_found_in_inventory", itemId)
|
||||
);
|
||||
|
||||
return;
|
||||
@@ -644,7 +644,7 @@ public class QuestHelper(
|
||||
if (newStackSize > 0)
|
||||
{
|
||||
var item = pmcData.Inventory.Items[inventoryItemIndex];
|
||||
_itemHelper.AddUpdObjectToItem(item);
|
||||
itemHelper.AddUpdObjectToItem(item);
|
||||
|
||||
item.Upd.StackObjectsCount = newStackSize;
|
||||
|
||||
@@ -680,7 +680,7 @@ public class QuestHelper(
|
||||
/// <returns>Quest</returns>
|
||||
public Quest RemoveQuestConditionsExceptLevel(Quest quest)
|
||||
{
|
||||
var updatedQuest = _cloner.Clone(quest);
|
||||
var updatedQuest = cloner.Clone(quest);
|
||||
updatedQuest.Conditions.AvailableForStart = updatedQuest
|
||||
.Conditions.AvailableForStart.Where(q => q.ConditionType == "Level")
|
||||
.ToList();
|
||||
@@ -720,9 +720,9 @@ public class QuestHelper(
|
||||
}
|
||||
}
|
||||
|
||||
if (_logger.IsLogEnabled(LogLevel.Debug))
|
||||
if (logger.IsLogEnabled(LogLevel.Debug))
|
||||
{
|
||||
_logger.Debug($"GetSellToTraderQuests found: {result.Count} quests");
|
||||
logger.Debug($"GetSellToTraderQuests found: {result.Count} quests");
|
||||
}
|
||||
|
||||
return result;
|
||||
@@ -768,8 +768,8 @@ public class QuestHelper(
|
||||
// Condition is in profile, but quest doesn't exist in database
|
||||
if (!SellToTraderQuestConditionCache.TryGetValue(counter.SourceId, out var conditions))
|
||||
{
|
||||
_logger.Error(
|
||||
_serverLocalisationService.GetText(
|
||||
logger.Error(
|
||||
serverLocalisationService.GetText(
|
||||
"quest_unable_to_find_quest_in_db_no_type",
|
||||
counter.SourceId
|
||||
)
|
||||
@@ -812,8 +812,8 @@ public class QuestHelper(
|
||||
);
|
||||
if (itemDetails is null)
|
||||
{
|
||||
_logger.Error(
|
||||
_serverLocalisationService.GetText(
|
||||
logger.Error(
|
||||
serverLocalisationService.GetText(
|
||||
"trader-unable_to_find_inventory_item_for_selltotrader_counter",
|
||||
taskCounter.SourceId
|
||||
)
|
||||
@@ -840,15 +840,15 @@ public class QuestHelper(
|
||||
public void FailQuest(
|
||||
PmcData pmcData,
|
||||
FailQuestRequestData failRequest,
|
||||
string sessionID,
|
||||
MongoId sessionID,
|
||||
ItemEventRouterResponse? output = null
|
||||
)
|
||||
{
|
||||
// Prepare response to send back to client
|
||||
var updatedOutput = output ?? _eventOutputHolder.GetOutput(sessionID);
|
||||
var updatedOutput = output ?? eventOutputHolder.GetOutput(sessionID);
|
||||
|
||||
UpdateQuestState(pmcData, QuestStatusEnum.Fail, failRequest.QuestId);
|
||||
var questRewards = _questRewardHelper.ApplyQuestReward(
|
||||
var questRewards = questRewardHelper.ApplyQuestReward(
|
||||
pmcData,
|
||||
failRequest.QuestId,
|
||||
QuestStatusEnum.Fail,
|
||||
@@ -869,13 +869,13 @@ public class QuestHelper(
|
||||
{
|
||||
if (quest.FailMessageText.Trim().Any())
|
||||
{
|
||||
_mailSendService.SendLocalisedNpcMessageToPlayer(
|
||||
mailSendService.SendLocalisedNpcMessageToPlayer(
|
||||
sessionID,
|
||||
quest?.TraderId ?? matchingRepeatableQuest?.TraderId,
|
||||
MessageType.QuestFail,
|
||||
quest.FailMessageText,
|
||||
questRewards.ToList(),
|
||||
_timeUtil.GetHoursAsSeconds((int)GetMailItemRedeemTimeHoursForProfile(pmcData))
|
||||
timeUtil.GetHoursAsSeconds((int)GetMailItemRedeemTimeHoursForProfile(pmcData))
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -892,7 +892,7 @@ public class QuestHelper(
|
||||
/// <returns>List of Quest objects</returns>
|
||||
public List<Quest> GetQuestsFromDb()
|
||||
{
|
||||
return _databaseService.GetQuests().Values.ToList();
|
||||
return databaseService.GetQuests().Values.ToList();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -901,10 +901,10 @@ public class QuestHelper(
|
||||
/// <param name="questId">Id of quest to find</param>
|
||||
/// <param name="pmcData">Player profile</param>
|
||||
/// <returns>Found quest</returns>
|
||||
public Quest? GetQuestFromDb(string questId, PmcData pmcData)
|
||||
public Quest? GetQuestFromDb(MongoId questId, PmcData pmcData)
|
||||
{
|
||||
// Maybe a repeatable quest?
|
||||
if (_databaseService.GetQuests().TryGetValue(questId, out var quest))
|
||||
if (databaseService.GetQuests().TryGetValue(questId, out var quest))
|
||||
{
|
||||
return quest;
|
||||
}
|
||||
@@ -945,7 +945,7 @@ public class QuestHelper(
|
||||
/// <returns>Locale Id from locale db</returns>
|
||||
public string GetQuestLocaleIdFromDb(string questMessageId)
|
||||
{
|
||||
var locale = _localeService.GetLocaleDb();
|
||||
var locale = localeService.GetLocaleDb();
|
||||
return locale.GetValueOrDefault(questMessageId, null);
|
||||
}
|
||||
|
||||
@@ -955,14 +955,14 @@ public class QuestHelper(
|
||||
/// <param name="pmcData">Profile to update</param>
|
||||
/// <param name="newQuestState">New state the quest should be in</param>
|
||||
/// <param name="questId">Id of the quest to alter the status of</param>
|
||||
protected void UpdateQuestState(PmcData pmcData, QuestStatusEnum newQuestState, string questId)
|
||||
protected void UpdateQuestState(PmcData pmcData, QuestStatusEnum newQuestState, MongoId questId)
|
||||
{
|
||||
// Find quest in profile, update status to desired status
|
||||
var questToUpdate = pmcData.Quests.FirstOrDefault(quest => quest.QId == questId);
|
||||
if (questToUpdate is not null)
|
||||
{
|
||||
questToUpdate.Status = newQuestState;
|
||||
questToUpdate.StatusTimers[newQuestState] = _timeUtil.GetTimeStamp();
|
||||
questToUpdate.StatusTimers[newQuestState] = timeUtil.GetTimeStamp();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -972,12 +972,12 @@ public class QuestHelper(
|
||||
/// <param name="pmcData">Profile to update</param>
|
||||
/// <param name="newQuestState">New state the quest should be in</param>
|
||||
/// <param name="questId">Id of the quest to alter the status of</param>
|
||||
public void ResetQuestState(PmcData pmcData, QuestStatusEnum newQuestState, string questId)
|
||||
public void ResetQuestState(PmcData pmcData, QuestStatusEnum newQuestState, MongoId questId)
|
||||
{
|
||||
var questToUpdate = pmcData.Quests?.FirstOrDefault(quest => quest.QId == questId);
|
||||
if (questToUpdate is not null)
|
||||
{
|
||||
var currentTimestamp = _timeUtil.GetTimeStamp();
|
||||
var currentTimestamp = timeUtil.GetTimeStamp();
|
||||
|
||||
questToUpdate.Status = newQuestState;
|
||||
|
||||
@@ -1022,9 +1022,9 @@ public class QuestHelper(
|
||||
var questInDb = allQuests.FirstOrDefault(x => x.Id == questId);
|
||||
if (questInDb is null)
|
||||
{
|
||||
if (_logger.IsLogEnabled(LogLevel.Debug))
|
||||
if (logger.IsLogEnabled(LogLevel.Debug))
|
||||
{
|
||||
_logger.Debug(
|
||||
logger.Debug(
|
||||
$"Unable to find quest: {questId} in db, cannot get 'FindItem' condition, skipping"
|
||||
);
|
||||
}
|
||||
@@ -1055,7 +1055,7 @@ public class QuestHelper(
|
||||
public void AddAllQuestsToProfile(PmcData pmcProfile, List<QuestStatusEnum> statuses)
|
||||
{
|
||||
// Iterate over all quests in db
|
||||
var quests = _databaseService.GetQuests();
|
||||
var quests = databaseService.GetQuests();
|
||||
foreach (var (key, questData) in quests)
|
||||
{
|
||||
// Quest from db matches quests in profile, skip
|
||||
@@ -1068,13 +1068,13 @@ public class QuestHelper(
|
||||
var statusesDict = new Dictionary<QuestStatusEnum, double>();
|
||||
foreach (var status in statuses)
|
||||
{
|
||||
statusesDict.Add(status, _timeUtil.GetTimeStamp());
|
||||
statusesDict.Add(status, timeUtil.GetTimeStamp());
|
||||
}
|
||||
|
||||
var questRecordToAdd = new QuestStatus
|
||||
{
|
||||
QId = key,
|
||||
StartTime = _timeUtil.GetTimeStamp(),
|
||||
StartTime = timeUtil.GetTimeStamp(),
|
||||
Status = statuses[^1], // Get last status in list as currently active status
|
||||
StatusTimers = statusesDict,
|
||||
CompletedConditions = [],
|
||||
@@ -1102,7 +1102,7 @@ public class QuestHelper(
|
||||
/// </summary>
|
||||
/// <param name="questId">Id of quest to remove</param>
|
||||
/// <param name="quests">Collection of quests to remove id from</param>
|
||||
public void FindAndRemoveQuestFromArrayIfExists(string questId, List<QuestStatus> quests)
|
||||
public void FindAndRemoveQuestFromArrayIfExists(MongoId questId, List<QuestStatus> quests)
|
||||
{
|
||||
quests.RemoveAll(quest => quest.QId == questId);
|
||||
}
|
||||
@@ -1112,7 +1112,7 @@ public class QuestHelper(
|
||||
/// </summary>
|
||||
/// <param name="completedQuestId">quest completed id</param>
|
||||
/// <returns>Collection of Quest objects</returns>
|
||||
public List<Quest> GetQuestsFailedByCompletingQuest(string completedQuestId)
|
||||
public List<Quest> GetQuestsFailedByCompletingQuest(MongoId completedQuestId)
|
||||
{
|
||||
var questsInDb = GetQuestsFromDb();
|
||||
return questsInDb
|
||||
@@ -1163,29 +1163,29 @@ public class QuestHelper(
|
||||
public ItemEventRouterResponse CompleteQuest(
|
||||
PmcData pmcData,
|
||||
CompleteQuestRequestData request,
|
||||
string sessionID
|
||||
MongoId sessionID
|
||||
)
|
||||
{
|
||||
var completeQuestResponse = _eventOutputHolder.GetOutput(sessionID);
|
||||
var completeQuestResponse = eventOutputHolder.GetOutput(sessionID);
|
||||
if (!completeQuestResponse.ProfileChanges.TryGetValue(sessionID, out var profileChanges))
|
||||
{
|
||||
_logger.Error($"Unable to get profile changes for {sessionID}");
|
||||
logger.Error($"Unable to get profile changes for {sessionID}");
|
||||
|
||||
return completeQuestResponse;
|
||||
}
|
||||
|
||||
// Clone of players quest status prior to any changes
|
||||
var preCompleteProfileQuestsClone = _cloner.Clone(pmcData.Quests);
|
||||
var preCompleteProfileQuestsClone = cloner.Clone(pmcData.Quests);
|
||||
|
||||
// Id of quest player just completed
|
||||
var completedQuestId = request.QuestId;
|
||||
|
||||
// Keep a copy of player quest statuses from their profile (Must be gathered prior to applyQuestReward() & failQuests())
|
||||
var clientQuestsClone = _cloner.Clone(GetClientQuests(sessionID));
|
||||
var clientQuestsClone = cloner.Clone(GetClientQuests(sessionID));
|
||||
|
||||
const QuestStatusEnum newQuestState = QuestStatusEnum.Success;
|
||||
UpdateQuestState(pmcData, newQuestState, completedQuestId);
|
||||
var questRewards = _questRewardHelper.ApplyQuestReward(
|
||||
var questRewards = questRewardHelper.ApplyQuestReward(
|
||||
pmcData,
|
||||
request.QuestId,
|
||||
newQuestState,
|
||||
@@ -1250,13 +1250,13 @@ public class QuestHelper(
|
||||
/// </summary>
|
||||
/// <param name="sessionID">session/player id</param>
|
||||
/// <returns>Collection of quests</returns>
|
||||
public List<Quest> GetClientQuests(string sessionID)
|
||||
public List<Quest> GetClientQuests(MongoId sessionID)
|
||||
{
|
||||
List<Quest> questsToShowPlayer = [];
|
||||
var profile = _profileHelper.GetPmcProfile(sessionID);
|
||||
var profile = profileHelper.GetPmcProfile(sessionID);
|
||||
if (profile is null)
|
||||
{
|
||||
_logger.Error($"Profile {sessionID} not found, unable to return quests");
|
||||
logger.Error($"Profile {sessionID} not found, unable to return quests");
|
||||
|
||||
return [];
|
||||
}
|
||||
@@ -1293,9 +1293,9 @@ public class QuestHelper(
|
||||
// Player can use trader mods then remove them, leaving quests behind
|
||||
if (!profile.TradersInfo.ContainsKey(quest.TraderId))
|
||||
{
|
||||
if (_logger.IsLogEnabled(LogLevel.Debug))
|
||||
if (logger.IsLogEnabled(LogLevel.Debug))
|
||||
{
|
||||
_logger.Debug(
|
||||
logger.Debug(
|
||||
$"Unable to show quest: {quest.QuestName} as its for a trader: {quest.TraderId} that no longer exists."
|
||||
);
|
||||
}
|
||||
@@ -1358,10 +1358,10 @@ public class QuestHelper(
|
||||
out var previousQuestCompleteTime
|
||||
);
|
||||
var unlockTime = previousQuestCompleteTime + conditionToFulfil.AvailableAfter;
|
||||
if (unlockTime > _timeUtil.GetTimeStamp())
|
||||
if (unlockTime > timeUtil.GetTimeStamp())
|
||||
{
|
||||
_logger.Debug(
|
||||
$"Quest {quest.QuestName} is locked for another: {unlockTime - _timeUtil.GetTimeStamp()} seconds"
|
||||
logger.Debug(
|
||||
$"Quest {quest.QuestName} is locked for another: {unlockTime - timeUtil.GetTimeStamp()} seconds"
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -1415,7 +1415,7 @@ public class QuestHelper(
|
||||
/// <returns>Collection of Quest objects with the rewards filtered correctly for the game version</returns>
|
||||
protected List<Quest> UpdateQuestsForGameEdition(List<Quest> quests, string gameVersion)
|
||||
{
|
||||
var modifiedQuests = _cloner.Clone(quests);
|
||||
var modifiedQuests = cloner.Clone(quests);
|
||||
foreach (var quest in modifiedQuests)
|
||||
{
|
||||
// Remove any reward that doesn't pass the game edition check
|
||||
@@ -1428,7 +1428,7 @@ public class QuestHelper(
|
||||
}
|
||||
|
||||
propsAsDict[rewardType.Key] = ((List<Reward>)propsAsDict[rewardType.Key])
|
||||
.Where(reward => _rewardHelper.RewardIsForGameEdition(reward, gameVersion))
|
||||
.Where(reward => rewardHelper.RewardIsForGameEdition(reward, gameVersion))
|
||||
.ToList();
|
||||
}
|
||||
}
|
||||
@@ -1443,7 +1443,7 @@ public class QuestHelper(
|
||||
/// <param name="pmcProfile"></param>
|
||||
/// <returns>Collection of Quest objects</returns>
|
||||
protected List<Quest> GetQuestsFromProfileFailedByCompletingQuest(
|
||||
string completedQuestId,
|
||||
MongoId completedQuestId,
|
||||
PmcData pmcProfile
|
||||
)
|
||||
{
|
||||
@@ -1511,7 +1511,7 @@ public class QuestHelper(
|
||||
* @param output Client output
|
||||
*/
|
||||
protected void FailQuests(
|
||||
string sessionID,
|
||||
MongoId sessionID,
|
||||
PmcData pmcData,
|
||||
List<Quest> questsToFail,
|
||||
ItemEventRouterResponse output
|
||||
@@ -1555,11 +1555,11 @@ public class QuestHelper(
|
||||
statusTimers.Add(QuestStatusEnum.Fail, 0);
|
||||
}
|
||||
|
||||
statusTimers[QuestStatusEnum.Fail] = _timeUtil.GetTimeStamp();
|
||||
statusTimers[QuestStatusEnum.Fail] = timeUtil.GetTimeStamp();
|
||||
var questData = new QuestStatus
|
||||
{
|
||||
QId = questToFail.Id,
|
||||
StartTime = _timeUtil.GetTimeStamp(),
|
||||
StartTime = timeUtil.GetTimeStamp(),
|
||||
StatusTimers = statusTimers,
|
||||
Status = QuestStatusEnum.Fail,
|
||||
};
|
||||
@@ -1576,21 +1576,21 @@ public class QuestHelper(
|
||||
* @param questRewards Rewards given to player
|
||||
*/
|
||||
protected void SendSuccessDialogMessageOnQuestComplete(
|
||||
string sessionID,
|
||||
MongoId sessionID,
|
||||
PmcData pmcData,
|
||||
string completedQuestId,
|
||||
MongoId completedQuestId,
|
||||
List<Item> questRewards
|
||||
)
|
||||
{
|
||||
var quest = GetQuestFromDb(completedQuestId, pmcData);
|
||||
|
||||
_mailSendService.SendLocalisedNpcMessageToPlayer(
|
||||
mailSendService.SendLocalisedNpcMessageToPlayer(
|
||||
sessionID,
|
||||
quest.TraderId,
|
||||
MessageType.QuestSuccess,
|
||||
quest.SuccessMessageText,
|
||||
questRewards,
|
||||
_timeUtil.GetHoursAsSeconds((int)GetMailItemRedeemTimeHoursForProfile(pmcData))
|
||||
timeUtil.GetHoursAsSeconds((int)GetMailItemRedeemTimeHoursForProfile(pmcData))
|
||||
);
|
||||
}
|
||||
|
||||
@@ -1603,7 +1603,7 @@ public class QuestHelper(
|
||||
protected void AddTimeLockedQuestsToProfile(
|
||||
PmcData pmcData,
|
||||
List<Quest> quests,
|
||||
string completedQuestId
|
||||
MongoId completedQuestId
|
||||
)
|
||||
{
|
||||
// Iterate over quests, look for quests with right criteria
|
||||
@@ -1622,7 +1622,7 @@ public class QuestHelper(
|
||||
{
|
||||
// Now + wait time
|
||||
var availableAfterTimestamp =
|
||||
_timeUtil.GetTimeStamp() + nextQuestWaitCondition.AvailableAfter;
|
||||
timeUtil.GetTimeStamp() + nextQuestWaitCondition.AvailableAfter;
|
||||
|
||||
// Update quest in profile with status of AvailableAfter
|
||||
var existingQuestInProfile = pmcData.Quests.FirstOrDefault(x => x.QId == quest.Id);
|
||||
@@ -1644,7 +1644,7 @@ public class QuestHelper(
|
||||
Status = QuestStatusEnum.AvailableAfter,
|
||||
StatusTimers = new Dictionary<QuestStatusEnum, double>
|
||||
{
|
||||
{ QuestStatusEnum.AvailableAfter, _timeUtil.GetTimeStamp() },
|
||||
{ QuestStatusEnum.AvailableAfter, timeUtil.GetTimeStamp() },
|
||||
},
|
||||
AvailableAfter = availableAfterTimestamp,
|
||||
}
|
||||
@@ -1658,16 +1658,16 @@ public class QuestHelper(
|
||||
* @param sessionId Player id
|
||||
* @param questIdToRemove Qid of quest to remove
|
||||
*/
|
||||
protected void RemoveQuestFromScavProfile(string sessionId, string questIdToRemove)
|
||||
protected void RemoveQuestFromScavProfile(MongoId sessionId, MongoId questIdToRemove)
|
||||
{
|
||||
var fullProfile = _profileHelper.GetFullProfile(sessionId);
|
||||
var fullProfile = profileHelper.GetFullProfile(sessionId);
|
||||
var repeatableInScavProfile = fullProfile.CharacterData.ScavData.Quests?.FirstOrDefault(x =>
|
||||
x.QId == questIdToRemove
|
||||
);
|
||||
if (repeatableInScavProfile is null)
|
||||
{
|
||||
_logger.Warning(
|
||||
_serverLocalisationService.GetText(
|
||||
logger.Warning(
|
||||
serverLocalisationService.GetText(
|
||||
"quest-unable_to_remove_scav_quest_from_profile",
|
||||
new { scavQuestId = questIdToRemove, profileId = sessionId }
|
||||
)
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
using SPTarkov.Common.Extensions;
|
||||
using SPTarkov.DI.Annotations;
|
||||
using SPTarkov.Server.Core.Extensions;
|
||||
using SPTarkov.Server.Core.Models.Common;
|
||||
using SPTarkov.Server.Core.Models.Eft.Common;
|
||||
using SPTarkov.Server.Core.Models.Eft.Common.Tables;
|
||||
using SPTarkov.Server.Core.Models.Eft.ItemEvent;
|
||||
@@ -13,13 +14,13 @@ namespace SPTarkov.Server.Core.Helpers;
|
||||
|
||||
[Injectable]
|
||||
public class QuestRewardHelper(
|
||||
ISptLogger<QuestRewardHelper> _logger,
|
||||
PaymentHelper _paymentHelper,
|
||||
DatabaseService _databaseService,
|
||||
ProfileHelper _profileHelper,
|
||||
RewardHelper _rewardHelper,
|
||||
ServerLocalisationService _serverLocalisationService,
|
||||
ICloner _cloner
|
||||
ISptLogger<QuestRewardHelper> logger,
|
||||
PaymentHelper paymentHelper,
|
||||
DatabaseService databaseService,
|
||||
ProfileHelper profileHelper,
|
||||
RewardHelper rewardHelper,
|
||||
ServerLocalisationService serverLocalisationService,
|
||||
ICloner cloner
|
||||
)
|
||||
{
|
||||
/// <summary>
|
||||
@@ -27,7 +28,7 @@ public class QuestRewardHelper(
|
||||
/// Value can be modified by modders by overriding this value with new traders.
|
||||
/// Ensure to add Lightkeeper's ID (638f541a29ffd1183d187f57) and BTR Driver's ID (656f0f98d80a697f855d34b1)
|
||||
/// </summary>
|
||||
protected readonly string[] InGameTraders = [Traders.LIGHTHOUSEKEEPER, Traders.BTR];
|
||||
protected readonly MongoId[] InGameTraders = [Traders.LIGHTHOUSEKEEPER, Traders.BTR];
|
||||
|
||||
/// <summary>
|
||||
/// Give player quest rewards - Skills/exp/trader standing/items/assort unlocks - Returns reward items player earned
|
||||
@@ -41,19 +42,19 @@ public class QuestRewardHelper(
|
||||
/// <returns>Array of reward items player was given</returns>
|
||||
public IEnumerable<Item> ApplyQuestReward(
|
||||
PmcData profileData,
|
||||
string questId,
|
||||
MongoId questId,
|
||||
QuestStatusEnum state,
|
||||
string sessionId,
|
||||
MongoId sessionId,
|
||||
ItemEventRouterResponse questResponse
|
||||
)
|
||||
{
|
||||
// Repeatable quest base data is always in PMCProfile, `profileData` may be scav profile
|
||||
// TODO: Move repeatable quest data to profile-agnostic location
|
||||
var fullProfile = _profileHelper.GetFullProfile(sessionId);
|
||||
var fullProfile = profileHelper.GetFullProfile(sessionId);
|
||||
var pmcProfile = fullProfile.CharacterData.PmcData;
|
||||
if (pmcProfile is null)
|
||||
{
|
||||
_logger.Error($"Unable to get pmc profile for: {sessionId}, no rewards given");
|
||||
logger.Error($"Unable to get pmc profile for: {sessionId}, no rewards given");
|
||||
|
||||
return [];
|
||||
}
|
||||
@@ -61,8 +62,8 @@ public class QuestRewardHelper(
|
||||
var questDetails = GetQuestFromDb(questId, pmcProfile);
|
||||
if (questDetails is null)
|
||||
{
|
||||
_logger.Warning(
|
||||
_serverLocalisationService.GetText(
|
||||
logger.Warning(
|
||||
serverLocalisationService.GetText(
|
||||
"quest-unable_to_find_quest_in_db_no_quest_rewards",
|
||||
questId
|
||||
)
|
||||
@@ -74,7 +75,7 @@ public class QuestRewardHelper(
|
||||
if (IsInGameTrader(questDetails))
|
||||
{
|
||||
// Assuming in-game traders give ALL rewards
|
||||
_logger.Debug(
|
||||
logger.Debug(
|
||||
$"Skipping quest rewards for quest: {questDetails.Id}, trader: {questDetails.TraderId} in InGameRewardTrader list"
|
||||
);
|
||||
|
||||
@@ -89,7 +90,7 @@ public class QuestRewardHelper(
|
||||
|
||||
// e.g. 'Success' or 'AvailableForFinish'
|
||||
var rewards = questDetails.Rewards.GetByJsonProp<List<Reward>>(state.ToString());
|
||||
return _rewardHelper.ApplyRewards(
|
||||
return rewardHelper.ApplyRewards(
|
||||
rewards,
|
||||
CustomisationSource.UNLOCKED_IN_GAME,
|
||||
fullProfile,
|
||||
@@ -115,10 +116,10 @@ public class QuestRewardHelper(
|
||||
/// <param name="questId">Id of quest to find</param>
|
||||
/// <param name="pmcData">Player profile</param>
|
||||
/// <returns>IQuest object</returns>
|
||||
protected Quest? GetQuestFromDb(string questId, PmcData pmcData)
|
||||
protected Quest? GetQuestFromDb(MongoId questId, PmcData pmcData)
|
||||
{
|
||||
// Look for quest in db
|
||||
if (_databaseService.GetQuests().TryGetValue(questId, out var quest))
|
||||
if (databaseService.GetQuests().TryGetValue(questId, out var quest))
|
||||
{
|
||||
return quest;
|
||||
}
|
||||
@@ -170,7 +171,7 @@ public class QuestRewardHelper(
|
||||
/// <returns>Updated quest</returns>
|
||||
public Quest ApplyMoneyBoost(Quest quest, double bonusPercent, QuestStatusEnum questStatus)
|
||||
{
|
||||
var clonedQuest = _cloner.Clone(quest);
|
||||
var clonedQuest = cloner.Clone(quest);
|
||||
if (clonedQuest?.Rewards?.Success == null)
|
||||
{
|
||||
return clonedQuest;
|
||||
@@ -181,7 +182,7 @@ public class QuestRewardHelper(
|
||||
reward.Type == RewardType.Item
|
||||
&& reward.Items != null
|
||||
&& reward.Items.Count > 0
|
||||
&& _paymentHelper.IsMoneyTpl(reward.Items.FirstOrDefault().Template)
|
||||
&& paymentHelper.IsMoneyTpl(reward.Items.FirstOrDefault().Template)
|
||||
);
|
||||
|
||||
foreach (var moneyReward in moneyRewards)
|
||||
@@ -190,7 +191,7 @@ public class QuestRewardHelper(
|
||||
var rewardItem = moneyReward.Items?.FirstOrDefault();
|
||||
if (rewardItem is null)
|
||||
{
|
||||
_logger.Error(
|
||||
logger.Error(
|
||||
$"Unable to apply money reward bonus to quest: {quest.Name} as no money item found"
|
||||
);
|
||||
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
using SPTarkov.DI.Annotations;
|
||||
using SPTarkov.Server.Core.Extensions;
|
||||
using SPTarkov.Server.Core.Models.Common;
|
||||
using SPTarkov.Server.Core.Models.Eft.Common.Tables;
|
||||
using SPTarkov.Server.Core.Models.Eft.Ragfair;
|
||||
using SPTarkov.Server.Core.Models.Enums;
|
||||
@@ -27,28 +28,26 @@ public class RagfairHelper(
|
||||
/// </summary>
|
||||
/// <param name="currencyTpl">Currency tpl</param>
|
||||
/// <returns>Currency tag, e.g. RUB</returns>
|
||||
public string GetCurrencyTag(string currencyTpl)
|
||||
public string GetCurrencyTag(MongoId currencyTpl)
|
||||
{
|
||||
if (currencyTpl == Money.EUROS)
|
||||
{
|
||||
return "EUR";
|
||||
}
|
||||
else if (currencyTpl == Money.DOLLARS)
|
||||
if (currencyTpl == Money.DOLLARS)
|
||||
{
|
||||
return "USD";
|
||||
}
|
||||
else if (currencyTpl == Money.ROUBLES)
|
||||
if (currencyTpl == Money.ROUBLES)
|
||||
{
|
||||
return "RUB";
|
||||
}
|
||||
else if (currencyTpl == Money.GP)
|
||||
if (currencyTpl == Money.GP)
|
||||
{
|
||||
return "GP";
|
||||
}
|
||||
else
|
||||
{
|
||||
return "";
|
||||
}
|
||||
|
||||
return "";
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -71,9 +70,9 @@ public class RagfairHelper(
|
||||
}
|
||||
}
|
||||
|
||||
public List<string> FilterCategories(string sessionId, SearchRequestData request)
|
||||
public List<MongoId> FilterCategories(MongoId sessionId, SearchRequestData request)
|
||||
{
|
||||
var result = new List<string>();
|
||||
var result = new List<MongoId>();
|
||||
|
||||
// Case: weapon builds
|
||||
if (request.BuildCount > 0)
|
||||
@@ -98,9 +97,9 @@ public class RagfairHelper(
|
||||
return result;
|
||||
}
|
||||
|
||||
public Dictionary<string, TraderAssort> GetDisplayableAssorts(string sessionId)
|
||||
public Dictionary<MongoId, TraderAssort> GetDisplayableAssorts(MongoId sessionId)
|
||||
{
|
||||
var result = new Dictionary<string, TraderAssort>();
|
||||
var result = new Dictionary<MongoId, TraderAssort>();
|
||||
foreach (
|
||||
var traderId in databaseService
|
||||
.GetTraders()
|
||||
@@ -113,12 +112,12 @@ public class RagfairHelper(
|
||||
return result;
|
||||
}
|
||||
|
||||
protected List<string> GetCategoryList(string handbookId)
|
||||
protected List<MongoId> GetCategoryList(MongoId handbookId)
|
||||
{
|
||||
var result = new List<string>();
|
||||
var result = new List<MongoId>();
|
||||
|
||||
// if its "mods" great-parent category, do double recursive loop
|
||||
if (handbookId == "5b5f71a686f77447ed5636ab")
|
||||
if (handbookId == new MongoId("5b5f71a686f77447ed5636ab"))
|
||||
{
|
||||
foreach (var category in handbookHelper.ChildrenCategories(handbookId))
|
||||
{
|
||||
|
||||
@@ -19,31 +19,31 @@ namespace SPTarkov.Server.Core.Helpers;
|
||||
|
||||
[Injectable]
|
||||
public class RagfairOfferHelper(
|
||||
ISptLogger<RagfairOfferHelper> _logger,
|
||||
TimeUtil _timeUtil,
|
||||
BotHelper _botHelper,
|
||||
RagfairSortHelper _ragfairSortHelper,
|
||||
PresetHelper _presetHelper,
|
||||
RagfairHelper _ragfairHelper,
|
||||
PaymentHelper _paymentHelper,
|
||||
TraderHelper _traderHelper,
|
||||
QuestHelper _questHelper,
|
||||
RagfairServerHelper _ragfairServerHelper,
|
||||
ItemHelper _itemHelper,
|
||||
DatabaseService _databaseService,
|
||||
RagfairOfferService _ragfairOfferService,
|
||||
LocaleService _localeService,
|
||||
ServerLocalisationService _serverLocalisationService,
|
||||
MailSendService _mailSendService,
|
||||
RagfairRequiredItemsService _ragfairRequiredItemsService,
|
||||
ProfileHelper _profileHelper,
|
||||
EventOutputHolder _eventOutputHolder,
|
||||
ConfigServer _configServer
|
||||
ISptLogger<RagfairOfferHelper> logger,
|
||||
TimeUtil timeUtil,
|
||||
BotHelper botHelper,
|
||||
RagfairSortHelper ragfairSortHelper,
|
||||
PresetHelper presetHelper,
|
||||
RagfairHelper ragfairHelper,
|
||||
PaymentHelper paymentHelper,
|
||||
TraderHelper traderHelper,
|
||||
QuestHelper questHelper,
|
||||
RagfairServerHelper ragfairServerHelper,
|
||||
ItemHelper itemHelper,
|
||||
DatabaseService databaseService,
|
||||
RagfairOfferService ragfairOfferService,
|
||||
LocaleService localeService,
|
||||
ServerLocalisationService serverLocalisationService,
|
||||
MailSendService mailSendService,
|
||||
RagfairRequiredItemsService ragfairRequiredItemsService,
|
||||
ProfileHelper profileHelper,
|
||||
EventOutputHolder eventOutputHolder,
|
||||
ConfigServer configServer
|
||||
)
|
||||
{
|
||||
protected const string _goodSoldTemplate = "5bdabfb886f7743e152e867e 0"; // Your {soldItem} {itemCount} items were bought by {buyerNickname}.
|
||||
protected readonly BotConfig _botConfig = _configServer.GetConfig<BotConfig>();
|
||||
protected readonly RagfairConfig _ragfairConfig = _configServer.GetConfig<RagfairConfig>();
|
||||
protected readonly BotConfig _botConfig = configServer.GetConfig<BotConfig>();
|
||||
protected readonly RagfairConfig _ragfairConfig = configServer.GetConfig<RagfairConfig>();
|
||||
|
||||
/// <summary>
|
||||
/// Pass through to ragfairOfferService.getOffers(), get flea offers a player should see
|
||||
@@ -55,15 +55,15 @@ public class RagfairOfferHelper(
|
||||
/// <returns>Offers the player should see</returns>
|
||||
public List<RagfairOffer> GetValidOffers(
|
||||
SearchRequestData searchRequest,
|
||||
List<string> itemsToAdd,
|
||||
Dictionary<string, TraderAssort> traderAssorts,
|
||||
List<MongoId> itemsToAdd,
|
||||
Dictionary<MongoId, TraderAssort> traderAssorts,
|
||||
PmcData pmcData
|
||||
)
|
||||
{
|
||||
var playerIsFleaBanned = pmcData.PlayerIsFleaBanned(_timeUtil.GetTimeStamp());
|
||||
var playerIsFleaBanned = pmcData.PlayerIsFleaBanned(timeUtil.GetTimeStamp());
|
||||
var tieredFlea = _ragfairConfig.TieredFlea;
|
||||
var tieredFleaLimitTypes = tieredFlea.UnlocksType;
|
||||
return _ragfairOfferService
|
||||
return ragfairOfferService
|
||||
.GetOffers()
|
||||
.Where(offer =>
|
||||
{
|
||||
@@ -121,7 +121,7 @@ public class RagfairOfferHelper(
|
||||
// Check if offer item is ammo
|
||||
if (
|
||||
tieredFlea.AmmoTplUnlocks is not null
|
||||
&& _itemHelper.IsOfBaseclass(offerItemTpl, BaseClasses.AMMO)
|
||||
&& itemHelper.IsOfBaseclass(offerItemTpl, BaseClasses.AMMO)
|
||||
)
|
||||
{
|
||||
// Check if ammo is flagged with a level requirement
|
||||
@@ -150,7 +150,7 @@ public class RagfairOfferHelper(
|
||||
}
|
||||
|
||||
// Optimisation - Skip further checks if the item type isn't in the restricted types list
|
||||
if (!_itemHelper.IsOfBaseclasses(offerItemTpl, tieredFleaLimitTypes))
|
||||
if (!itemHelper.IsOfBaseclasses(offerItemTpl, tieredFleaLimitTypes))
|
||||
{
|
||||
return;
|
||||
}
|
||||
@@ -158,7 +158,7 @@ public class RagfairOfferHelper(
|
||||
// Check if the item belongs to any restricted type and if player level is insufficient
|
||||
if (
|
||||
tieredFleaLimitTypes
|
||||
.Where(tieredItemType => _itemHelper.IsOfBaseclass(offerItemTpl, tieredItemType))
|
||||
.Where(tieredItemType => itemHelper.IsOfBaseclass(offerItemTpl, tieredItemType))
|
||||
.Any(tieredItemType => playerLevel < tieredFlea.UnlocksType[tieredItemType])
|
||||
)
|
||||
{
|
||||
@@ -180,7 +180,7 @@ public class RagfairOfferHelper(
|
||||
)
|
||||
{
|
||||
// Get all offers that require the desired item and filter out offers from non traders if player below ragfair unlock
|
||||
var offerIDsForItem = _ragfairRequiredItemsService.GetRequiredOffersById(
|
||||
var offerIDsForItem = ragfairRequiredItemsService.GetRequiredOffersById(
|
||||
searchRequest.NeededSearchId
|
||||
);
|
||||
|
||||
@@ -190,7 +190,7 @@ public class RagfairOfferHelper(
|
||||
var result = new List<RagfairOffer>();
|
||||
foreach (
|
||||
var offer in offerIDsForItem
|
||||
.Select(_ragfairOfferService.GetOfferByOfferId)
|
||||
.Select(ragfairOfferService.GetOfferByOfferId)
|
||||
.Where(offer => PassesSearchFilterCriteria(searchRequest, offer, pmcData))
|
||||
)
|
||||
{
|
||||
@@ -220,20 +220,20 @@ public class RagfairOfferHelper(
|
||||
/// <returns>RagfairOffer array</returns>
|
||||
public List<RagfairOffer> GetOffersForBuild(
|
||||
SearchRequestData searchRequest,
|
||||
List<string> itemsToAdd,
|
||||
Dictionary<string, TraderAssort> traderAssorts,
|
||||
List<MongoId> itemsToAdd,
|
||||
Dictionary<MongoId, TraderAssort> traderAssorts,
|
||||
PmcData pmcData
|
||||
)
|
||||
{
|
||||
var offersMap = new Dictionary<string, List<RagfairOffer>>();
|
||||
var offersToReturn = new List<RagfairOffer>();
|
||||
var playerIsFleaBanned = pmcData.PlayerIsFleaBanned(_timeUtil.GetTimeStamp());
|
||||
var playerIsFleaBanned = pmcData.PlayerIsFleaBanned(timeUtil.GetTimeStamp());
|
||||
var tieredFlea = _ragfairConfig.TieredFlea;
|
||||
var tieredFleaLimitTypes = tieredFlea.UnlocksType;
|
||||
|
||||
foreach (var desiredItemTpl in searchRequest.BuildItems)
|
||||
{
|
||||
var matchingOffers = _ragfairOfferService.GetOffersOfType(desiredItemTpl.Key);
|
||||
var matchingOffers = ragfairOfferService.GetOffersOfType(desiredItemTpl.Key);
|
||||
if (matchingOffers is null)
|
||||
// No offers found for this item, skip
|
||||
{
|
||||
@@ -344,7 +344,7 @@ public class RagfairOfferHelper(
|
||||
}
|
||||
|
||||
// Sort offers by price and pick the best
|
||||
var offer = _ragfairSortHelper.SortOffers(offersToSort, RagfairSort.PRICE)[0];
|
||||
var offer = ragfairSortHelper.SortOffers(offersToSort, RagfairSort.PRICE)[0];
|
||||
offersToReturn.Add(offer);
|
||||
}
|
||||
|
||||
@@ -363,8 +363,8 @@ public class RagfairOfferHelper(
|
||||
/// <returns>True = should be shown to player</returns>
|
||||
private bool IsDisplayableOffer(
|
||||
SearchRequestData searchRequest,
|
||||
List<string> itemsToAdd,
|
||||
Dictionary<string, TraderAssort> traderAssorts,
|
||||
List<MongoId> itemsToAdd,
|
||||
Dictionary<MongoId, TraderAssort> traderAssorts,
|
||||
RagfairOffer offer,
|
||||
PmcData pmcProfile,
|
||||
bool playerIsFleaBanned = false
|
||||
@@ -374,7 +374,7 @@ public class RagfairOfferHelper(
|
||||
|
||||
// Currency offer is sold for
|
||||
var moneyTypeTpl = offer.Requirements.FirstOrDefault().Template;
|
||||
var isTraderOffer = _databaseService.GetTraders().ContainsKey(offer.User.Id);
|
||||
var isTraderOffer = databaseService.GetTraders().ContainsKey(offer.User.Id);
|
||||
|
||||
if (!isTraderOffer && playerIsFleaBanned)
|
||||
{
|
||||
@@ -404,7 +404,7 @@ public class RagfairOfferHelper(
|
||||
searchRequest.BuildItems.Count == 0
|
||||
&& // Prevent equipment loadout searches filtering out presets
|
||||
searchRequest.BuildCount.GetValueOrDefault(0) > 0
|
||||
&& _presetHelper.HasPreset(offerRootItem.Template)
|
||||
&& presetHelper.HasPreset(offerRootItem.Template)
|
||||
)
|
||||
{
|
||||
return false;
|
||||
@@ -414,7 +414,7 @@ public class RagfairOfferHelper(
|
||||
// has info.removeBartering as true, this if statement removed barter items.
|
||||
if (
|
||||
searchRequest.RemoveBartering.GetValueOrDefault(false)
|
||||
&& !_paymentHelper.IsMoneyTpl(moneyTypeTpl)
|
||||
&& !paymentHelper.IsMoneyTpl(moneyTypeTpl)
|
||||
)
|
||||
// Don't include barter offers
|
||||
{
|
||||
@@ -494,7 +494,7 @@ public class RagfairOfferHelper(
|
||||
{
|
||||
if (!pmcProfile.TradersInfo.TryGetValue(offer.User.Id, out var userTraderSettings))
|
||||
{
|
||||
_logger.Warning(
|
||||
logger.Warning(
|
||||
$"Trader: {offer.User.Id} not found in profile, assuming offer is not locked being loyalty level"
|
||||
);
|
||||
return false;
|
||||
@@ -512,7 +512,7 @@ public class RagfairOfferHelper(
|
||||
/// <returns>true if quest locked</returns>
|
||||
public bool TraderOfferItemQuestLocked(
|
||||
RagfairOffer offer,
|
||||
Dictionary<string, TraderAssort> traderAssorts
|
||||
Dictionary<MongoId, TraderAssort> traderAssorts
|
||||
)
|
||||
{
|
||||
var itemIds = offer.Items.Select(x => x.Id).ToHashSet();
|
||||
@@ -576,16 +576,16 @@ public class RagfairOfferHelper(
|
||||
/// <returns>true if restriction reached, false if no restrictions/not reached</returns>
|
||||
protected bool TraderBuyRestrictionReached(RagfairOffer offer)
|
||||
{
|
||||
var traderAssorts = _traderHelper.GetTraderAssortsByTraderId(offer.User.Id).Items;
|
||||
var traderAssorts = traderHelper.GetTraderAssortsByTraderId(offer.User.Id).Items;
|
||||
|
||||
// Find item being purchased from traders assorts
|
||||
var assortData = traderAssorts.FirstOrDefault(item => item.Id == offer.Items[0].Id);
|
||||
if (assortData is null)
|
||||
{
|
||||
// No trader assort data
|
||||
_logger.Warning(
|
||||
logger.Warning(
|
||||
$"Unable to find trader: "
|
||||
+ $"${offer.User.Nickname}assort for item: {_itemHelper.GetItemName(offer.Items[0].Template)} "
|
||||
+ $"${offer.User.Nickname}assort for item: {itemHelper.GetItemName(offer.Items[0].Template)} "
|
||||
+ $"{offer.Items[0].Template}, cannot check if buy restriction reached"
|
||||
);
|
||||
|
||||
@@ -639,9 +639,9 @@ public class RagfairOfferHelper(
|
||||
* @param sessionId Session id to process offers for
|
||||
* @returns true = complete
|
||||
*/
|
||||
public bool ProcessOffersOnProfile(string sessionId)
|
||||
public bool ProcessOffersOnProfile(MongoId sessionId)
|
||||
{
|
||||
var currentTimestamp = _timeUtil.GetTimeStamp();
|
||||
var currentTimestamp = timeUtil.GetTimeStamp();
|
||||
var profileOffers = GetProfileOffers(sessionId);
|
||||
|
||||
// No offers, don't do anything
|
||||
@@ -691,7 +691,7 @@ public class RagfairOfferHelper(
|
||||
|
||||
var ratingToAdd = offer.SummaryCost / totalItemsCount * boughtAmount;
|
||||
IncreaseProfileRagfairRating(
|
||||
_profileHelper.GetFullProfile(sessionId),
|
||||
profileHelper.GetFullProfile(sessionId),
|
||||
ratingToAdd.Value
|
||||
);
|
||||
|
||||
@@ -724,12 +724,12 @@ public class RagfairOfferHelper(
|
||||
/// <param name="amountToIncrementBy">Raw amount to add to players ragfair rating (excluding the reputation gain multiplier)</param>
|
||||
public void IncreaseProfileRagfairRating(SptProfile profile, double? amountToIncrementBy)
|
||||
{
|
||||
var ragfairGlobalsConfig = _databaseService.GetGlobals().Configuration.RagFair;
|
||||
var ragfairGlobalsConfig = databaseService.GetGlobals().Configuration.RagFair;
|
||||
|
||||
profile.CharacterData.PmcData.RagfairInfo.IsRatingGrowing = true;
|
||||
if (amountToIncrementBy is null)
|
||||
{
|
||||
_logger.Warning(
|
||||
logger.Warning(
|
||||
$"Unable to increment ragfair rating, value was not a number: {amountToIncrementBy}"
|
||||
);
|
||||
|
||||
@@ -747,9 +747,9 @@ public class RagfairOfferHelper(
|
||||
/// </summary>
|
||||
/// <param name="sessionId">Session/Player id</param>
|
||||
/// <returns>List of ragfair offers</returns>
|
||||
protected List<RagfairOffer> GetProfileOffers(string sessionId)
|
||||
protected List<RagfairOffer> GetProfileOffers(MongoId sessionId)
|
||||
{
|
||||
var profile = _profileHelper.GetPmcProfile(sessionId);
|
||||
var profile = profileHelper.GetPmcProfile(sessionId);
|
||||
|
||||
if (profile.RagfairInfo?.Offers is null)
|
||||
{
|
||||
@@ -764,13 +764,13 @@ public class RagfairOfferHelper(
|
||||
* @param sessionId Session id of profile to delete offer from
|
||||
* @param offerId Id of offer to delete
|
||||
*/
|
||||
protected void DeleteOfferById(string sessionId, string offerId)
|
||||
protected void DeleteOfferById(MongoId sessionId, string offerId)
|
||||
{
|
||||
var profileRagfairInfo = _profileHelper.GetPmcProfile(sessionId).RagfairInfo;
|
||||
var profileRagfairInfo = profileHelper.GetPmcProfile(sessionId).RagfairInfo;
|
||||
var offerIndex = profileRagfairInfo.Offers.FindIndex(o => o.Id == offerId);
|
||||
if (offerIndex == -1)
|
||||
{
|
||||
_logger.Warning(
|
||||
logger.Warning(
|
||||
$"Unable to find offer: {offerId} in profile: {sessionId}, unable to delete"
|
||||
);
|
||||
}
|
||||
@@ -781,7 +781,7 @@ public class RagfairOfferHelper(
|
||||
}
|
||||
|
||||
// Also delete from ragfair
|
||||
_ragfairOfferService.RemoveOfferById(offerId);
|
||||
ragfairOfferService.RemoveOfferById(offerId);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -792,7 +792,7 @@ public class RagfairOfferHelper(
|
||||
/// <param name="boughtAmount">Amount item was purchased for</param>
|
||||
/// <returns>ItemEventRouterResponse</returns>
|
||||
public ItemEventRouterResponse CompleteOffer(
|
||||
string offerOwnerSessionId,
|
||||
MongoId offerOwnerSessionId,
|
||||
RagfairOffer offer,
|
||||
int boughtAmount
|
||||
)
|
||||
@@ -809,7 +809,7 @@ public class RagfairOfferHelper(
|
||||
}
|
||||
|
||||
// Assemble payment to send to seller now offer was purchased
|
||||
var sellerProfile = _profileHelper.GetPmcProfile(offerOwnerSessionId);
|
||||
var sellerProfile = profileHelper.GetPmcProfile(offerOwnerSessionId);
|
||||
var rootItem = offer.Items.FirstOrDefault();
|
||||
var itemTpl = rootItem.Template;
|
||||
var offerStackCount = rootItem.Upd.StackObjectsCount;
|
||||
@@ -824,7 +824,7 @@ public class RagfairOfferHelper(
|
||||
Upd = new Upd { StackObjectsCount = requirement.Count * boughtAmount },
|
||||
};
|
||||
|
||||
var stacks = _itemHelper.SplitStack(requestedItem);
|
||||
var stacks = itemHelper.SplitStack(requestedItem);
|
||||
foreach (var item in stacks)
|
||||
{
|
||||
var outItems = new List<Item> { item };
|
||||
@@ -832,7 +832,7 @@ public class RagfairOfferHelper(
|
||||
// TODO - is this code used?, may have been when adding barters to flea was still possible for player
|
||||
if (requirement.OnlyFunctional.GetValueOrDefault(false))
|
||||
{
|
||||
var presetItems = _ragfairServerHelper.GetPresetItemsByTpl(item);
|
||||
var presetItems = ragfairServerHelper.GetPresetItemsByTpl(item);
|
||||
if (presetItems.Count > 0)
|
||||
{
|
||||
outItems.Add(presetItems[0]);
|
||||
@@ -854,10 +854,10 @@ public class RagfairOfferHelper(
|
||||
HandbookId = itemTpl,
|
||||
};
|
||||
|
||||
var storageTimeSeconds = _timeUtil.GetHoursAsSeconds(
|
||||
(int)_questHelper.GetMailItemRedeemTimeHoursForProfile(sellerProfile)
|
||||
var storageTimeSeconds = timeUtil.GetHoursAsSeconds(
|
||||
(int)questHelper.GetMailItemRedeemTimeHoursForProfile(sellerProfile)
|
||||
);
|
||||
_mailSendService.SendDirectNpcMessageToPlayer(
|
||||
mailSendService.SendDirectNpcMessageToPlayer(
|
||||
offerOwnerSessionId,
|
||||
Traders.RAGMAN,
|
||||
MessageType.FleamarketMessage,
|
||||
@@ -872,7 +872,7 @@ public class RagfairOfferHelper(
|
||||
sellerProfile.RagfairInfo.SellSum ??= 0;
|
||||
sellerProfile.RagfairInfo.SellSum += offer.SummaryCost;
|
||||
|
||||
return _eventOutputHolder.GetOutput(offerOwnerSessionId);
|
||||
return eventOutputHolder.GetOutput(offerOwnerSessionId);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -884,11 +884,11 @@ public class RagfairOfferHelper(
|
||||
protected string GetLocalisedOfferSoldMessage(MongoId itemTpl, int boughtAmount)
|
||||
{
|
||||
// Generate a message to inform that item was sold
|
||||
var globalLocales = _localeService.GetLocaleDb();
|
||||
var globalLocales = localeService.GetLocaleDb();
|
||||
if (!globalLocales.TryGetValue(_goodSoldTemplate, out var soldMessageLocaleGuid))
|
||||
{
|
||||
_logger.Error(
|
||||
_serverLocalisationService.GetText(
|
||||
logger.Error(
|
||||
serverLocalisationService.GetText(
|
||||
"ragfair-unable_to_find_locale_by_key",
|
||||
_goodSoldTemplate
|
||||
)
|
||||
@@ -902,7 +902,7 @@ public class RagfairOfferHelper(
|
||||
var tplVars = new SystemData
|
||||
{
|
||||
SoldItem = hasKey ? value : itemTpl,
|
||||
BuyerNickname = _botHelper.GetPmcNicknameOfMaxLength(_botConfig.BotNameLengthLimit),
|
||||
BuyerNickname = botHelper.GetPmcNicknameOfMaxLength(_botConfig.BotNameLengthLimit),
|
||||
ItemCount = boughtAmount,
|
||||
};
|
||||
|
||||
@@ -942,7 +942,7 @@ public class RagfairOfferHelper(
|
||||
var offerMoneyTypeTpl = offer.Requirements.FirstOrDefault().Template;
|
||||
|
||||
if (
|
||||
pmcData.Info.Level < _databaseService.GetGlobals().Configuration.RagFair.MinUserLevel
|
||||
pmcData.Info.Level < databaseService.GetGlobals().Configuration.RagFair.MinUserLevel
|
||||
&& isDefaultUserOffer
|
||||
)
|
||||
// Skip item if player is < global unlock level (default is 15) and item is from a dynamically generated source
|
||||
@@ -965,7 +965,7 @@ public class RagfairOfferHelper(
|
||||
|
||||
if (
|
||||
searchRequest.OneHourExpiration.GetValueOrDefault(false)
|
||||
&& offer.EndTime - _timeUtil.GetTimeStamp() > TimeUtil.OneHourAsSeconds
|
||||
&& offer.EndTime - timeUtil.GetTimeStamp() > TimeUtil.OneHourAsSeconds
|
||||
)
|
||||
// offer expires within an hour
|
||||
{
|
||||
@@ -1017,7 +1017,7 @@ public class RagfairOfferHelper(
|
||||
}
|
||||
else
|
||||
{
|
||||
var itemQualityPercent = _itemHelper.GetItemQualityModifierForItems(offer.Items) * 100;
|
||||
var itemQualityPercent = itemHelper.GetItemQualityModifierForItems(offer.Items) * 100;
|
||||
if (itemQualityPercent < searchRequest.ConditionFrom)
|
||||
{
|
||||
return false;
|
||||
@@ -1029,12 +1029,12 @@ public class RagfairOfferHelper(
|
||||
}
|
||||
}
|
||||
|
||||
if (searchRequest.Currency > 0 && _paymentHelper.IsMoneyTpl(offerMoneyTypeTpl))
|
||||
if (searchRequest.Currency > 0 && paymentHelper.IsMoneyTpl(offerMoneyTypeTpl))
|
||||
{
|
||||
// Only want offers with specific currency
|
||||
if (
|
||||
_ragfairHelper.GetCurrencyTag(offerMoneyTypeTpl)
|
||||
!= _ragfairHelper.GetCurrencyTag(searchRequest.Currency.GetValueOrDefault(0))
|
||||
ragfairHelper.GetCurrencyTag(offerMoneyTypeTpl)
|
||||
!= ragfairHelper.GetCurrencyTag(searchRequest.Currency.GetValueOrDefault(0))
|
||||
)
|
||||
{
|
||||
// Offer is for different currency to what search params allow, skip
|
||||
@@ -1067,15 +1067,15 @@ public class RagfairOfferHelper(
|
||||
public bool IsItemFunctional(Item offerRootItem, RagfairOffer offer)
|
||||
{
|
||||
// Non-preset weapons/armor are always functional
|
||||
if (!_presetHelper.HasPreset(offerRootItem.Template))
|
||||
if (!presetHelper.HasPreset(offerRootItem.Template))
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
// For armor items that can hold mods, make sure the item count is at least the amount of required plates
|
||||
if (_itemHelper.ArmorItemCanHoldMods(offerRootItem.Template))
|
||||
if (itemHelper.ArmorItemCanHoldMods(offerRootItem.Template))
|
||||
{
|
||||
var offerRootTemplate = _itemHelper.GetItem(offerRootItem.Template).Value;
|
||||
var offerRootTemplate = itemHelper.GetItem(offerRootItem.Template).Value;
|
||||
var requiredPlateCount = offerRootTemplate
|
||||
.Properties.Slots?.Where(item => item.Required.GetValueOrDefault(false))
|
||||
?.Count();
|
||||
@@ -1118,7 +1118,7 @@ public class RagfairOfferHelper(
|
||||
/// <returns>True if in range</returns>
|
||||
protected bool ItemQualityInRange(Item item, int min, int max)
|
||||
{
|
||||
var itemQualityPercentage = 100 * _itemHelper.GetItemQualityModifier(item);
|
||||
var itemQualityPercentage = 100 * itemHelper.GetItemQualityModifier(item);
|
||||
if (min > 0 && min > itemQualityPercentage)
|
||||
// Item condition too low
|
||||
{
|
||||
|
||||
@@ -11,14 +11,14 @@ namespace SPTarkov.Server.Core.Helpers;
|
||||
|
||||
[Injectable]
|
||||
public class RagfairSellHelper(
|
||||
ISptLogger<RagfairSellHelper> _logger,
|
||||
TimeUtil _timeUtil,
|
||||
RandomUtil _randomUtil,
|
||||
DatabaseService _databaseService,
|
||||
ConfigServer _configServer
|
||||
ISptLogger<RagfairSellHelper> logger,
|
||||
TimeUtil timeUtil,
|
||||
RandomUtil randomUtil,
|
||||
DatabaseService databaseService,
|
||||
ConfigServer configServer
|
||||
)
|
||||
{
|
||||
protected readonly RagfairConfig _ragfairConfig = _configServer.GetConfig<RagfairConfig>();
|
||||
protected readonly RagfairConfig _ragfairConfig = configServer.GetConfig<RagfairConfig>();
|
||||
|
||||
/// <summary>
|
||||
/// Get the percent chance to sell an item based on its average listed price vs player chosen listing price
|
||||
@@ -72,16 +72,14 @@ public class RagfairSellHelper(
|
||||
bool sellInOneGo = false
|
||||
)
|
||||
{
|
||||
var startTimestamp = _timeUtil.GetTimeStamp();
|
||||
var startTimestamp = timeUtil.GetTimeStamp();
|
||||
|
||||
// Get a time in future to stop simulating sell chances at
|
||||
var endTime =
|
||||
startTimestamp
|
||||
+ _timeUtil.GetHoursAsSeconds(
|
||||
+ timeUtil.GetHoursAsSeconds(
|
||||
(int)
|
||||
_databaseService
|
||||
.GetGlobals()
|
||||
.Configuration.RagFair.OfferDurationTimeInHour.Value
|
||||
databaseService.GetGlobals().Configuration.RagFair.OfferDurationTimeInHour.Value
|
||||
);
|
||||
|
||||
var sellTimestamp = startTimestamp;
|
||||
@@ -93,14 +91,14 @@ public class RagfairSellHelper(
|
||||
if (sellChancePercent is null)
|
||||
{
|
||||
effectiveSellChance = _ragfairConfig.Sell.Chance.Base;
|
||||
_logger.Warning(
|
||||
logger.Warning(
|
||||
$"Sell chance was not a number: {sellChancePercent}, defaulting to {_ragfairConfig.Sell.Chance.Base}%"
|
||||
);
|
||||
}
|
||||
|
||||
if (_logger.IsLogEnabled(LogLevel.Debug))
|
||||
if (logger.IsLogEnabled(LogLevel.Debug))
|
||||
{
|
||||
_logger.Debug(
|
||||
logger.Debug(
|
||||
$"Rolling to sell: {itemSellCount} item(s) - (chance: {effectiveSellChance}%)"
|
||||
);
|
||||
}
|
||||
@@ -113,8 +111,8 @@ public class RagfairSellHelper(
|
||||
|
||||
while (remainingCount > 0 && sellTimestamp < endTime)
|
||||
{
|
||||
var boughtAmount = sellInOneGo ? remainingCount : _randomUtil.GetInt(1, remainingCount);
|
||||
if (_randomUtil.GetChance100(effectiveSellChance))
|
||||
var boughtAmount = sellInOneGo ? remainingCount : randomUtil.GetInt(1, remainingCount);
|
||||
if (randomUtil.GetChance100(effectiveSellChance))
|
||||
{
|
||||
// Passed roll check, item will be sold
|
||||
// Weight time to sell towards selling faster based on how cheap the item sold
|
||||
@@ -140,18 +138,18 @@ public class RagfairSellHelper(
|
||||
sellTimestamp += (long)newSellTime;
|
||||
result.Add(new SellResult { SellTime = sellTimestamp, Amount = boughtAmount });
|
||||
|
||||
if (_logger.IsLogEnabled(LogLevel.Debug))
|
||||
if (logger.IsLogEnabled(LogLevel.Debug))
|
||||
{
|
||||
_logger.Debug(
|
||||
$"Offer will sell at: {_timeUtil.GetDateTimeFromTimeStamp(sellTimestamp).ToLocalTime().ToString()}, bought: {boughtAmount}"
|
||||
logger.Debug(
|
||||
$"Offer will sell at: {timeUtil.GetDateTimeFromTimeStamp(sellTimestamp).ToLocalTime().ToString()}, bought: {boughtAmount}"
|
||||
);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (_logger.IsLogEnabled(LogLevel.Debug))
|
||||
if (logger.IsLogEnabled(LogLevel.Debug))
|
||||
{
|
||||
_logger.Debug($"Offer rolled not to sell, item count: {boughtAmount}");
|
||||
logger.Debug($"Offer rolled not to sell, item count: {boughtAmount}");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -109,7 +109,7 @@ public class RagfairServerHelper(
|
||||
* @param parentId Parent Id to check is blacklisted
|
||||
* @returns true if blacklisted
|
||||
*/
|
||||
protected bool IsItemCategoryOnCustomFleaBlacklist(string itemParentId)
|
||||
protected bool IsItemCategoryOnCustomFleaBlacklist(MongoId itemParentId)
|
||||
{
|
||||
return ragfairConfig.Dynamic.Blacklist.CustomItemCategoryList.Contains(itemParentId);
|
||||
}
|
||||
@@ -119,7 +119,7 @@ public class RagfairServerHelper(
|
||||
* @param traderId
|
||||
* @returns True if id was a trader
|
||||
*/
|
||||
public bool IsTrader(string traderId)
|
||||
public bool IsTrader(MongoId traderId)
|
||||
{
|
||||
return databaseService.GetTraders().ContainsKey(traderId);
|
||||
}
|
||||
@@ -129,7 +129,7 @@ public class RagfairServerHelper(
|
||||
* @param sessionID Player to send items to
|
||||
* @param returnedItems Items to send to player
|
||||
*/
|
||||
public void ReturnItems(string sessionID, List<Item> returnedItems)
|
||||
public void ReturnItems(MongoId sessionID, List<Item> returnedItems)
|
||||
{
|
||||
mailSendService.SendLocalisedNpcMessageToPlayer(
|
||||
sessionID,
|
||||
|
||||
@@ -6,7 +6,7 @@ using SPTarkov.Server.Core.Services;
|
||||
namespace SPTarkov.Server.Core.Helpers;
|
||||
|
||||
[Injectable]
|
||||
public class RagfairSortHelper(LocaleService _localeService)
|
||||
public class RagfairSortHelper(LocaleService localeService)
|
||||
{
|
||||
/**
|
||||
* Sort a list of ragfair offers by something (id/rating/offer name/price/expiry time)
|
||||
@@ -84,7 +84,7 @@ public class RagfairSortHelper(LocaleService _localeService)
|
||||
|
||||
protected int SortOffersByName(RagfairOffer a, RagfairOffer b)
|
||||
{
|
||||
var locale = _localeService.GetLocaleDb();
|
||||
var locale = localeService.GetLocaleDb();
|
||||
|
||||
var tplA = a.Items[0].Template;
|
||||
var tplB = b.Items[0].Template;
|
||||
|
||||
@@ -13,14 +13,14 @@ namespace SPTarkov.Server.Core.Helpers;
|
||||
|
||||
[Injectable]
|
||||
public class RepairHelper(
|
||||
ISptLogger<RepairHelper> _logger,
|
||||
RandomUtil _randomUtil,
|
||||
DatabaseService _databaseService,
|
||||
ConfigServer _configServer,
|
||||
ICloner _cloner
|
||||
ISptLogger<RepairHelper> logger,
|
||||
RandomUtil randomUtil,
|
||||
DatabaseService databaseService,
|
||||
ConfigServer configServer,
|
||||
ICloner cloner
|
||||
)
|
||||
{
|
||||
protected RepairConfig _repairConfig = _configServer.GetConfig<RepairConfig>();
|
||||
protected RepairConfig _repairConfig = configServer.GetConfig<RepairConfig>();
|
||||
|
||||
/// <summary>
|
||||
/// Alter an items durability after a repair by trader/repair kit
|
||||
@@ -42,16 +42,16 @@ public class RepairHelper(
|
||||
bool applyMaxDurabilityDegradation = true
|
||||
)
|
||||
{
|
||||
if (_logger.IsLogEnabled(LogLevel.Debug))
|
||||
if (logger.IsLogEnabled(LogLevel.Debug))
|
||||
{
|
||||
_logger.Debug(
|
||||
logger.Debug(
|
||||
$"Adding {amountToRepair} to {itemToRepairDetails.Name} using kit: {useRepairKit}"
|
||||
);
|
||||
}
|
||||
|
||||
var itemMaxDurability = _cloner.Clone(itemToRepair.Upd.Repairable.MaxDurability);
|
||||
var itemCurrentDurability = _cloner.Clone(itemToRepair.Upd.Repairable.Durability);
|
||||
var itemCurrentMaxDurability = _cloner.Clone(itemToRepair.Upd.Repairable.MaxDurability);
|
||||
var itemMaxDurability = cloner.Clone(itemToRepair.Upd.Repairable.MaxDurability);
|
||||
var itemCurrentDurability = cloner.Clone(itemToRepair.Upd.Repairable.Durability);
|
||||
var itemCurrentMaxDurability = cloner.Clone(itemToRepair.Upd.Repairable.MaxDurability);
|
||||
|
||||
var newCurrentDurability = itemCurrentDurability + amountToRepair;
|
||||
var newCurrentMaxDurability = itemCurrentMaxDurability + amountToRepair;
|
||||
@@ -127,12 +127,12 @@ public class RepairHelper(
|
||||
{
|
||||
// Degradation value is based on the armor material
|
||||
if (
|
||||
!_databaseService
|
||||
!databaseService
|
||||
.GetGlobals()
|
||||
.Configuration.ArmorMaterials.TryGetValue(material, out var armorMaterialSettings)
|
||||
)
|
||||
{
|
||||
_logger.Error($"Unable to find armor with a type of: {material}");
|
||||
logger.Error($"Unable to find armor with a type of: {material}");
|
||||
}
|
||||
|
||||
var minMultiplier = isRepairKit
|
||||
@@ -143,7 +143,7 @@ public class RepairHelper(
|
||||
? armorMaterialSettings.MaxRepairKitDegradation
|
||||
: armorMaterialSettings.MaxRepairDegradation;
|
||||
|
||||
var duraLossPercent = _randomUtil.GetDouble((double)minMultiplier, (double)maxMultiplier);
|
||||
var duraLossPercent = randomUtil.GetDouble((double)minMultiplier, (double)maxMultiplier);
|
||||
var duraLossMultipliedByTraderMultiplier =
|
||||
duraLossPercent * armorMax * traderQualityMultiplier;
|
||||
|
||||
@@ -178,7 +178,7 @@ public class RepairHelper(
|
||||
maxRepairDeg = itemProps.MaxRepairDegradation;
|
||||
}
|
||||
|
||||
var duraLossPercent = _randomUtil.GetDouble((double)minRepairDeg, (double)maxRepairDeg);
|
||||
var duraLossPercent = randomUtil.GetDouble((double)minRepairDeg, (double)maxRepairDeg);
|
||||
var duraLossMultipliedByTraderMultiplier =
|
||||
duraLossPercent * weaponMax * traderQualityMultipler;
|
||||
|
||||
|
||||
@@ -62,7 +62,10 @@ public class RepeatableQuestHelper(
|
||||
/// <param name="traderId">TraderId that should provide this quest</param>
|
||||
/// <returns>Cloned quest template</returns>
|
||||
/// <exception cref="ArgumentOutOfRangeException"></exception>
|
||||
public RepeatableQuest? GetClonedQuestTemplateForType(RepeatableQuestType type, string traderId)
|
||||
public RepeatableQuest? GetClonedQuestTemplateForType(
|
||||
RepeatableQuestType type,
|
||||
MongoId traderId
|
||||
)
|
||||
{
|
||||
var quest = type switch
|
||||
{
|
||||
@@ -109,7 +112,7 @@ public class RepeatableQuestHelper(
|
||||
RepeatableQuestType type,
|
||||
MongoId traderId,
|
||||
PlayerGroup playerGroup,
|
||||
string sessionId
|
||||
MongoId sessionId
|
||||
)
|
||||
{
|
||||
var questData = GetClonedQuestTemplateForType(type, traderId);
|
||||
|
||||
@@ -16,15 +16,15 @@ namespace SPTarkov.Server.Core.Helpers;
|
||||
|
||||
[Injectable]
|
||||
public class RewardHelper(
|
||||
ISptLogger<RewardHelper> _logger,
|
||||
TimeUtil _timeUtil,
|
||||
ItemHelper _itemHelper,
|
||||
DatabaseService _databaseService,
|
||||
ProfileHelper _profileHelper,
|
||||
ServerLocalisationService _serverLocalisationService,
|
||||
TraderHelper _traderHelper,
|
||||
PresetHelper _presetHelper,
|
||||
ICloner _cloner
|
||||
ISptLogger<RewardHelper> logger,
|
||||
TimeUtil timeUtil,
|
||||
ItemHelper itemHelper,
|
||||
DatabaseService databaseService,
|
||||
ProfileHelper profileHelper,
|
||||
ServerLocalisationService serverLocalisationService,
|
||||
TraderHelper traderHelper,
|
||||
PresetHelper presetHelper,
|
||||
ICloner cloner
|
||||
)
|
||||
{
|
||||
/// <summary>
|
||||
@@ -42,7 +42,7 @@ public class RewardHelper(
|
||||
string source,
|
||||
SptProfile fullProfile,
|
||||
PmcData profileData,
|
||||
string rewardSourceId,
|
||||
MongoId rewardSourceId,
|
||||
ItemEventRouterResponse? questResponse = null
|
||||
)
|
||||
{
|
||||
@@ -50,7 +50,7 @@ public class RewardHelper(
|
||||
var pmcProfile = fullProfile?.CharacterData?.PmcData;
|
||||
if (pmcProfile is null)
|
||||
{
|
||||
_logger.Error($"Unable to get PMC profile for: {sessionId}, no rewards given");
|
||||
logger.Error($"Unable to get PMC profile for: {sessionId}, no rewards given");
|
||||
|
||||
return [];
|
||||
}
|
||||
@@ -69,27 +69,31 @@ public class RewardHelper(
|
||||
{
|
||||
case RewardType.Skill:
|
||||
// This needs to use the passed in profileData, as it could be the scav profile
|
||||
_profileHelper.AddSkillPointsToPlayer(
|
||||
profileHelper.AddSkillPointsToPlayer(
|
||||
profileData,
|
||||
Enum.Parse<SkillTypes>(reward.Target),
|
||||
reward.Value
|
||||
);
|
||||
break;
|
||||
case RewardType.Experience:
|
||||
_profileHelper.AddExperienceToPmc(
|
||||
profileHelper.AddExperienceToPmc(
|
||||
sessionId.Value,
|
||||
int.Parse(reward.Value.ToString())
|
||||
); // this must occur first as the output object needs to take the modified profile exp value
|
||||
// Recalculate level in event player leveled up
|
||||
pmcProfile.Info.Level = pmcProfile.CalculateLevel(
|
||||
_databaseService.GetGlobals().Configuration.Exp.Level.ExperienceTable
|
||||
databaseService.GetGlobals().Configuration.Exp.Level.ExperienceTable
|
||||
);
|
||||
break;
|
||||
case RewardType.TraderStanding:
|
||||
_traderHelper.AddStandingToTrader(sessionId, reward.Target, reward.Value.Value);
|
||||
traderHelper.AddStandingToTrader(
|
||||
sessionId.Value,
|
||||
reward.Target,
|
||||
reward.Value.Value
|
||||
);
|
||||
break;
|
||||
case RewardType.TraderUnlock:
|
||||
_traderHelper.SetTraderUnlockedState(reward.Target, true, sessionId);
|
||||
traderHelper.SetTraderUnlockedState(reward.Target, true, sessionId.Value);
|
||||
break;
|
||||
case RewardType.Item:
|
||||
// Item rewards are retrieved by getRewardItems() below, and returned to be handled by caller
|
||||
@@ -101,34 +105,34 @@ public class RewardHelper(
|
||||
AddAchievementToProfile(fullProfile, reward.Target);
|
||||
break;
|
||||
case RewardType.StashRows:
|
||||
_profileHelper.AddStashRowsBonusToProfile(sessionId.Value, (int)reward.Value); // Add specified stash rows from reward - requires client restart
|
||||
profileHelper.AddStashRowsBonusToProfile(sessionId.Value, (int)reward.Value); // Add specified stash rows from reward - requires client restart
|
||||
break;
|
||||
case RewardType.ProductionScheme:
|
||||
FindAndAddHideoutProductionIdToProfile(
|
||||
pmcProfile,
|
||||
reward,
|
||||
rewardSourceId,
|
||||
sessionId,
|
||||
sessionId.Value,
|
||||
questResponse
|
||||
);
|
||||
break;
|
||||
case RewardType.Pockets:
|
||||
_profileHelper.ReplaceProfilePocketTpl(pmcProfile, reward.Target);
|
||||
profileHelper.ReplaceProfilePocketTpl(pmcProfile, reward.Target);
|
||||
break;
|
||||
case RewardType.CustomizationDirect:
|
||||
_profileHelper.AddHideoutCustomisationUnlock(fullProfile, reward, source);
|
||||
profileHelper.AddHideoutCustomisationUnlock(fullProfile, reward, source);
|
||||
break;
|
||||
case RewardType.NotificationPopup:
|
||||
// TODO: Wire up to notification system
|
||||
_logger.Error("UNHANDLED: RewardType.NotificationPopup");
|
||||
logger.Error("UNHANDLED: RewardType.NotificationPopup");
|
||||
break;
|
||||
case RewardType.WebPromoCode:
|
||||
// TODO: ??? (Free arena trial from Balancing - Part 1)
|
||||
_logger.Error("UNHANDLED: RewardType.WebPromoCode");
|
||||
logger.Error("UNHANDLED: RewardType.WebPromoCode");
|
||||
break;
|
||||
default:
|
||||
_logger.Error(
|
||||
_serverLocalisationService.GetText(
|
||||
logger.Error(
|
||||
serverLocalisationService.GetText(
|
||||
"reward-type_not_handled",
|
||||
new { rewardType = reward.Type, questId = rewardSourceId }
|
||||
)
|
||||
@@ -182,16 +186,16 @@ public class RewardHelper(
|
||||
protected void FindAndAddHideoutProductionIdToProfile(
|
||||
PmcData pmcData,
|
||||
Reward craftUnlockReward,
|
||||
string questId,
|
||||
string sessionID,
|
||||
MongoId questId,
|
||||
MongoId sessionID,
|
||||
ItemEventRouterResponse response
|
||||
)
|
||||
{
|
||||
var matchingProductions = GetRewardProductionMatch(craftUnlockReward, questId);
|
||||
if (matchingProductions.Count != 1)
|
||||
{
|
||||
_logger.Error(
|
||||
_serverLocalisationService.GetText(
|
||||
logger.Error(
|
||||
serverLocalisationService.GetText(
|
||||
"reward-unable_to_find_matching_hideout_production",
|
||||
new { questId, matchCount = matchingProductions.Count }
|
||||
)
|
||||
@@ -218,11 +222,11 @@ public class RewardHelper(
|
||||
/// <returns>List of matching HideoutProduction objects.</returns>
|
||||
public List<HideoutProduction> GetRewardProductionMatch(
|
||||
Reward craftUnlockReward,
|
||||
string questId
|
||||
MongoId questId
|
||||
)
|
||||
{
|
||||
// Get hideout crafts and find those that match by areatype/required level/end product tpl - hope for just one match
|
||||
var craftingRecipes = _databaseService.GetHideout().Production.Recipes;
|
||||
var craftingRecipes = databaseService.GetHideout().Production.Recipes;
|
||||
|
||||
// Area that will be used to craft unlocked item
|
||||
var desiredHideoutAreaType = (HideoutAreas)int.Parse(craftUnlockReward.TraderId.ToString());
|
||||
@@ -283,10 +287,10 @@ public class RewardHelper(
|
||||
List<Item> mods = [];
|
||||
|
||||
// Is armor item that may need inserts / plates
|
||||
if (reward.Items.Count == 1 && _itemHelper.ArmorItemCanHoldMods(reward.Items[0].Template))
|
||||
if (reward.Items.Count == 1 && itemHelper.ArmorItemCanHoldMods(reward.Items[0].Template))
|
||||
// Only process items with slots
|
||||
{
|
||||
if (_itemHelper.ItemHasSlots(reward.Items.FirstOrDefault().Template))
|
||||
if (itemHelper.ItemHasSlots(reward.Items.FirstOrDefault().Template))
|
||||
// Attempt to pull default preset from globals and add child items to reward (clones reward.items)
|
||||
{
|
||||
GenerateArmorRewardChildSlots(reward.Items.FirstOrDefault(), reward);
|
||||
@@ -295,10 +299,10 @@ public class RewardHelper(
|
||||
|
||||
foreach (var rewardItem in reward.Items)
|
||||
{
|
||||
_itemHelper.AddUpdObjectToItem(rewardItem);
|
||||
itemHelper.AddUpdObjectToItem(rewardItem);
|
||||
|
||||
// Reward items are granted Found in Raid status
|
||||
_itemHelper.SetFoundInRaid(rewardItem);
|
||||
itemHelper.SetFoundInRaid(rewardItem);
|
||||
|
||||
// Is root item, fix stacks
|
||||
if (rewardItem.Id == reward.Target)
|
||||
@@ -317,7 +321,7 @@ public class RewardHelper(
|
||||
rewardItem.Upd.StackObjectsCount = 1;
|
||||
}
|
||||
|
||||
targets = _itemHelper.SplitStack(rewardItem);
|
||||
targets = itemHelper.SplitStack(rewardItem);
|
||||
// splitStack created new ids for the new stacks. This would destroy the relation to possible children.
|
||||
// Instead, we reset the id to preserve relations and generate a new id in the downstream loop, where we are also reparenting if required
|
||||
foreach (var target in targets)
|
||||
@@ -332,7 +336,7 @@ public class RewardHelper(
|
||||
// Propagate FiR status into child items
|
||||
{
|
||||
if (
|
||||
!_itemHelper.IsOfBaseclasses(
|
||||
!itemHelper.IsOfBaseclasses(
|
||||
rewardItem.Template,
|
||||
[BaseClasses.AMMO, BaseClasses.MONEY]
|
||||
)
|
||||
@@ -352,19 +356,19 @@ public class RewardHelper(
|
||||
foreach (var target in targets)
|
||||
{
|
||||
// This has all the original id relations since we reset the id to the original after the splitStack
|
||||
var itemsClone = new List<Item> { _cloner.Clone(target) };
|
||||
var itemsClone = new List<Item> { cloner.Clone(target) };
|
||||
// Here we generate a new id for the root item
|
||||
target.Id = new MongoId();
|
||||
|
||||
// Add cloned mods to root item array
|
||||
var clonedMods = _cloner.Clone(mods);
|
||||
var clonedMods = cloner.Clone(mods);
|
||||
foreach (var mod in clonedMods)
|
||||
{
|
||||
itemsClone.Add(mod);
|
||||
}
|
||||
|
||||
// Re-parent items + generate new ids to ensure valid ids
|
||||
var itemsToAdd = _itemHelper.ReparentItemAndChildren(target, itemsClone);
|
||||
var itemsToAdd = itemHelper.ReparentItemAndChildren(target, itemsClone);
|
||||
rewardItems.AddRange(itemsToAdd);
|
||||
}
|
||||
|
||||
@@ -379,11 +383,11 @@ public class RewardHelper(
|
||||
protected void GenerateArmorRewardChildSlots(Item originalRewardRootItem, Reward reward)
|
||||
{
|
||||
// Look for a default preset from globals for armor
|
||||
var defaultPreset = _presetHelper.GetDefaultPreset(originalRewardRootItem.Template);
|
||||
var defaultPreset = presetHelper.GetDefaultPreset(originalRewardRootItem.Template);
|
||||
if (defaultPreset is not null)
|
||||
{
|
||||
// Found preset, use mods to hydrate reward item
|
||||
var presetAndMods = _cloner.Clone(defaultPreset.Items).ReplaceIDs().ToList();
|
||||
var presetAndMods = cloner.Clone(defaultPreset.Items).ReplaceIDs().ToList();
|
||||
var newRootId = presetAndMods.RemapRootItemId();
|
||||
|
||||
reward.Items = presetAndMods;
|
||||
@@ -395,18 +399,18 @@ public class RewardHelper(
|
||||
reward.Target = rootItem.Id;
|
||||
|
||||
// Copy over stack count otherwise reward shows as missing in client
|
||||
_itemHelper.AddUpdObjectToItem(rootItem);
|
||||
itemHelper.AddUpdObjectToItem(rootItem);
|
||||
rootItem.Upd.StackObjectsCount = originalRewardRootItem.Upd.StackObjectsCount;
|
||||
return;
|
||||
}
|
||||
|
||||
_logger.Warning(
|
||||
logger.Warning(
|
||||
"Unable to find default preset for armor {originalRewardRootItem._tpl}, adding mods manually"
|
||||
);
|
||||
var itemDbData = _itemHelper.GetItem(originalRewardRootItem.Template).Value;
|
||||
var itemDbData = itemHelper.GetItem(originalRewardRootItem.Template).Value;
|
||||
|
||||
// Hydrate reward with only 'required' mods - necessary for things like helmets otherwise you end up with nvgs/visors etc
|
||||
reward.Items = _itemHelper.AddChildSlotItems(reward.Items, itemDbData, null, true);
|
||||
reward.Items = itemHelper.AddChildSlotItems(reward.Items, itemDbData, null, true);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -415,16 +419,16 @@ public class RewardHelper(
|
||||
/// </summary>
|
||||
/// <param name="fullProfile">Profile to add achievement to.</param>
|
||||
/// <param name="achievementId">Id of achievement to add.</param>
|
||||
public void AddAchievementToProfile(SptProfile fullProfile, string achievementId)
|
||||
public void AddAchievementToProfile(SptProfile fullProfile, MongoId achievementId)
|
||||
{
|
||||
// Add achievement id to profile with timestamp it was unlocked
|
||||
fullProfile.CharacterData.PmcData.Achievements.TryAdd(
|
||||
achievementId,
|
||||
_timeUtil.GetTimeStamp()
|
||||
timeUtil.GetTimeStamp()
|
||||
);
|
||||
|
||||
// Check for any customisation unlocks
|
||||
var achievementDataDb = _databaseService
|
||||
var achievementDataDb = databaseService
|
||||
.GetTemplates()
|
||||
.Achievements.FirstOrDefault(achievement => achievement.Id == achievementId);
|
||||
if (achievementDataDb is null)
|
||||
|
||||
@@ -19,19 +19,19 @@ namespace SPTarkov.Server.Core.Helpers;
|
||||
|
||||
[Injectable]
|
||||
public class TradeHelper(
|
||||
ISptLogger<TradeHelper> _logger,
|
||||
TraderHelper _traderHelper,
|
||||
ItemHelper _itemHelper,
|
||||
QuestHelper _questHelper,
|
||||
PaymentService _paymentService,
|
||||
FenceService _fenceService,
|
||||
ServerLocalisationService _serverLocalisationService,
|
||||
HttpResponseUtil _httpResponseUtil,
|
||||
InventoryHelper _inventoryHelper,
|
||||
RagfairServer _ragfairServer,
|
||||
TraderAssortHelper _traderAssortHelper,
|
||||
TraderPurchasePersisterService _traderPurchasePersisterService,
|
||||
ICloner _cloner
|
||||
ISptLogger<TradeHelper> logger,
|
||||
TraderHelper traderHelper,
|
||||
ItemHelper itemHelper,
|
||||
QuestHelper questHelper,
|
||||
PaymentService paymentService,
|
||||
FenceService fenceService,
|
||||
ServerLocalisationService serverLocalisationService,
|
||||
HttpResponseUtil httpResponseUtil,
|
||||
InventoryHelper inventoryHelper,
|
||||
RagfairServer ragfairServer,
|
||||
TraderAssortHelper traderAssortHelper,
|
||||
TraderPurchasePersisterService traderPurchasePersisterService,
|
||||
ICloner cloner
|
||||
)
|
||||
{
|
||||
protected static readonly Lock buyLock = new();
|
||||
@@ -47,7 +47,7 @@ public class TradeHelper(
|
||||
public void BuyItem(
|
||||
PmcData pmcData,
|
||||
ProcessBuyTradeRequestData buyRequestData,
|
||||
string sessionID,
|
||||
MongoId sessionID,
|
||||
bool foundInRaid,
|
||||
ItemEventRouterResponse output
|
||||
)
|
||||
@@ -68,7 +68,7 @@ public class TradeHelper(
|
||||
// Called when player purchases PMC offer from ragfair
|
||||
buyCallback = buyCount =>
|
||||
{
|
||||
var allOffers = _ragfairServer.GetOffers();
|
||||
var allOffers = ragfairServer.GetOffers();
|
||||
|
||||
// We store ragfair offerId in buyRequestData.item_id
|
||||
var offerWithItem = allOffers.FirstOrDefault(x =>
|
||||
@@ -101,7 +101,7 @@ public class TradeHelper(
|
||||
],
|
||||
TraderId = buyRequestData.TransactionId,
|
||||
};
|
||||
_traderHelper.AddTraderPurchasesToPlayerProfile(
|
||||
traderHelper.AddTraderPurchasesToPlayerProfile(
|
||||
sessionID,
|
||||
itemPurchaseDetails,
|
||||
itemPurchased
|
||||
@@ -111,8 +111,8 @@ public class TradeHelper(
|
||||
|
||||
// buyCallback = BuyCallback1;
|
||||
// Get raw offer from ragfair, clone to prevent altering offer itself
|
||||
var allOffers = _ragfairServer.GetOffers();
|
||||
var offerWithItemCloned = _cloner.Clone(
|
||||
var allOffers = ragfairServer.GetOffers();
|
||||
var offerWithItemCloned = cloner.Clone(
|
||||
allOffers.FirstOrDefault(x => x.Id == buyRequestData.ItemId)
|
||||
);
|
||||
offerItems = offerWithItemCloned.Items;
|
||||
@@ -122,7 +122,7 @@ public class TradeHelper(
|
||||
buyCallback = buyCount =>
|
||||
{
|
||||
// Update assort/flea item values
|
||||
var traderAssorts = _traderHelper
|
||||
var traderAssorts = traderHelper
|
||||
.GetTraderAssortsByTraderId(buyRequestData.TransactionId)
|
||||
.Items;
|
||||
var itemPurchased = traderAssorts.FirstOrDefault(assort =>
|
||||
@@ -132,24 +132,24 @@ public class TradeHelper(
|
||||
// Decrement trader item count
|
||||
itemPurchased.Upd.StackObjectsCount -= buyCount;
|
||||
|
||||
_fenceService.AmendOrRemoveFenceOffer(buyRequestData.ItemId, buyCount);
|
||||
fenceService.AmendOrRemoveFenceOffer(buyRequestData.ItemId, buyCount);
|
||||
};
|
||||
|
||||
var fenceItems = _fenceService.GetRawFenceAssorts().Items;
|
||||
var fenceItems = fenceService.GetRawFenceAssorts().Items;
|
||||
var rootItemIndex = fenceItems.FindIndex(item => item.Id == buyRequestData.ItemId);
|
||||
if (rootItemIndex == -1)
|
||||
{
|
||||
if (_logger.IsLogEnabled(LogLevel.Debug))
|
||||
if (logger.IsLogEnabled(LogLevel.Debug))
|
||||
{
|
||||
_logger.Debug(
|
||||
logger.Debug(
|
||||
$"Tried to buy item {buyRequestData.ItemId} from fence that no longer exists"
|
||||
);
|
||||
}
|
||||
|
||||
var message = _serverLocalisationService.GetText(
|
||||
var message = serverLocalisationService.GetText(
|
||||
"ragfair-offer_no_longer_exists"
|
||||
);
|
||||
_httpResponseUtil.AppendErrorToOutput(output, message);
|
||||
httpResponseUtil.AppendErrorToOutput(output, message);
|
||||
|
||||
return;
|
||||
}
|
||||
@@ -161,7 +161,7 @@ public class TradeHelper(
|
||||
buyCallback = buyCount =>
|
||||
{
|
||||
// Update assort/flea item values
|
||||
var traderAssorts = _traderHelper
|
||||
var traderAssorts = traderHelper
|
||||
.GetTraderAssortsByTraderId(buyRequestData.TransactionId)
|
||||
.Items;
|
||||
var itemPurchased = traderAssorts.FirstOrDefault(item =>
|
||||
@@ -208,7 +208,7 @@ public class TradeHelper(
|
||||
TraderId = buyRequestData.TransactionId,
|
||||
};
|
||||
|
||||
_traderHelper.AddTraderPurchasesToPlayerProfile(
|
||||
traderHelper.AddTraderPurchasesToPlayerProfile(
|
||||
sessionID,
|
||||
itemPurchaseDat,
|
||||
itemPurchased
|
||||
@@ -217,7 +217,7 @@ public class TradeHelper(
|
||||
};
|
||||
|
||||
// Get all trader assort items
|
||||
var traderItems = _traderAssortHelper
|
||||
var traderItems = traderAssortHelper
|
||||
.GetAssort(sessionID, buyRequestData.TransactionId)
|
||||
.Items;
|
||||
|
||||
@@ -225,7 +225,7 @@ public class TradeHelper(
|
||||
var relevantItems = traderItems.FindAndReturnChildrenAsItems(buyRequestData.ItemId);
|
||||
if (relevantItems.Count == 0)
|
||||
{
|
||||
_logger.Error(
|
||||
logger.Error(
|
||||
$"Purchased trader: {buyRequestData.TransactionId} offer: {buyRequestData.ItemId} has no items"
|
||||
);
|
||||
}
|
||||
@@ -234,7 +234,7 @@ public class TradeHelper(
|
||||
}
|
||||
|
||||
// Get item details from db
|
||||
var itemDbDetails = _itemHelper.GetItem(offerItems.FirstOrDefault().Template).Value;
|
||||
var itemDbDetails = itemHelper.GetItem(offerItems.FirstOrDefault().Template).Value;
|
||||
var itemMaxStackSize = itemDbDetails.Properties.StackMaxSize;
|
||||
var itemsToSendTotalCount = buyRequestData.Count;
|
||||
var itemsToSendRemaining = itemsToSendTotalCount;
|
||||
@@ -243,7 +243,7 @@ public class TradeHelper(
|
||||
List<List<Item>> itemsToSendToPlayer = [];
|
||||
while (itemsToSendRemaining > 0)
|
||||
{
|
||||
var offerClone = _cloner.Clone(offerItems);
|
||||
var offerClone = cloner.Clone(offerItems);
|
||||
// Handle stackable items that have a max stack size limit
|
||||
var itemCountToSend = Math.Min(itemMaxStackSize ?? 0, itemsToSendRemaining ?? 0);
|
||||
offerClone.FirstOrDefault().Upd.StackObjectsCount = itemCountToSend;
|
||||
@@ -252,7 +252,7 @@ public class TradeHelper(
|
||||
offerClone.RemapRootItemId();
|
||||
if (offerClone.Count > 1)
|
||||
{
|
||||
_itemHelper.ReparentItemAndChildren(offerClone.FirstOrDefault(), offerClone);
|
||||
itemHelper.ReparentItemAndChildren(offerClone.FirstOrDefault(), offerClone);
|
||||
}
|
||||
|
||||
itemsToSendToPlayer.Add(offerClone);
|
||||
@@ -271,19 +271,19 @@ public class TradeHelper(
|
||||
};
|
||||
|
||||
// Add items + their children to stash
|
||||
_inventoryHelper.AddItemsToStash(sessionID, request, pmcData, output);
|
||||
inventoryHelper.AddItemsToStash(sessionID, request, pmcData, output);
|
||||
if (output.Warnings?.Count > 0)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
/// Pay for purchase
|
||||
_paymentService.PayMoney(pmcData, buyRequestData, sessionID, output);
|
||||
paymentService.PayMoney(pmcData, buyRequestData, sessionID, output);
|
||||
if (output.Warnings?.Count > 0)
|
||||
{
|
||||
var errorMessage =
|
||||
$"Transaction failed: {output.Warnings.FirstOrDefault().ErrorMessage}";
|
||||
_httpResponseUtil.AppendErrorToOutput(
|
||||
httpResponseUtil.AppendErrorToOutput(
|
||||
output,
|
||||
errorMessage,
|
||||
BackendErrorCodes.UnknownTradingError
|
||||
@@ -304,12 +304,12 @@ public class TradeHelper(
|
||||
PmcData profileWithItemsToSell,
|
||||
PmcData profileToReceiveMoney,
|
||||
ProcessSellTradeRequestData sellRequest,
|
||||
string sessionID,
|
||||
MongoId sessionID,
|
||||
ItemEventRouterResponse output
|
||||
)
|
||||
{
|
||||
// Check for and increment SoldToTrader condition counters
|
||||
_questHelper.IncrementSoldToTraderCounters(
|
||||
questHelper.IncrementSoldToTraderCounters(
|
||||
profileWithItemsToSell,
|
||||
profileToReceiveMoney,
|
||||
sellRequest
|
||||
@@ -329,30 +329,30 @@ public class TradeHelper(
|
||||
{
|
||||
var errorMessage =
|
||||
$"Unable to sell item {itemToBeRemoved.Id}, cannot be found in player inventory";
|
||||
_logger.Error(errorMessage);
|
||||
logger.Error(errorMessage);
|
||||
|
||||
_httpResponseUtil.AppendErrorToOutput(output, errorMessage);
|
||||
httpResponseUtil.AppendErrorToOutput(output, errorMessage);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
if (_logger.IsLogEnabled(LogLevel.Debug))
|
||||
if (logger.IsLogEnabled(LogLevel.Debug))
|
||||
{
|
||||
_logger.Debug(
|
||||
logger.Debug(
|
||||
$"Selling: id: {matchingItemInInventory.Id} tpl: {matchingItemInInventory.Template}"
|
||||
);
|
||||
}
|
||||
|
||||
if (sellRequest.TransactionId == Traders.FENCE)
|
||||
{
|
||||
_fenceService.AddItemsToFenceAssort(
|
||||
fenceService.AddItemsToFenceAssort(
|
||||
profileWithItemsToSell.Inventory.Items,
|
||||
matchingItemInInventory
|
||||
);
|
||||
}
|
||||
|
||||
// Remove item from inventory + any child items it has
|
||||
_inventoryHelper.RemoveItem(
|
||||
inventoryHelper.RemoveItem(
|
||||
profileWithItemsToSell,
|
||||
itemToBeRemoved.Id,
|
||||
sessionID,
|
||||
@@ -361,7 +361,7 @@ public class TradeHelper(
|
||||
}
|
||||
|
||||
// Give player money for sold item(s)
|
||||
_paymentService.GiveProfileMoney(
|
||||
paymentService.GiveProfileMoney(
|
||||
profileToReceiveMoney,
|
||||
sellRequest.Price,
|
||||
sellRequest,
|
||||
@@ -380,20 +380,20 @@ public class TradeHelper(
|
||||
/// <param name="assortId">Id of assort being purchased</param>
|
||||
/// <param name="count">How many of the item are being bought</param>
|
||||
protected void CheckPurchaseIsWithinTraderItemLimit(
|
||||
string sessionId,
|
||||
MongoId sessionId,
|
||||
PmcData pmcData,
|
||||
string traderId,
|
||||
MongoId traderId,
|
||||
Item assortBeingPurchased,
|
||||
string assortId,
|
||||
MongoId assortId,
|
||||
double count
|
||||
)
|
||||
{
|
||||
var traderPurchaseData = _traderPurchasePersisterService.GetProfileTraderPurchase(
|
||||
var traderPurchaseData = traderPurchasePersisterService.GetProfileTraderPurchase(
|
||||
sessionId,
|
||||
traderId,
|
||||
assortBeingPurchased.Id
|
||||
);
|
||||
var traderItemPurchaseLimit = _traderHelper.GetAccountTypeAdjustedTraderPurchaseLimit(
|
||||
var traderItemPurchaseLimit = traderHelper.GetAccountTypeAdjustedTraderPurchaseLimit(
|
||||
(double)assortBeingPurchased.Upd?.BuyRestrictionMax,
|
||||
pmcData.Info.GameVersion
|
||||
);
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
using SPTarkov.DI.Annotations;
|
||||
using SPTarkov.Server.Core.Extensions;
|
||||
using SPTarkov.Server.Core.Models.Common;
|
||||
using SPTarkov.Server.Core.Models.Eft.Common.Tables;
|
||||
using SPTarkov.Server.Core.Models.Enums;
|
||||
using SPTarkov.Server.Core.Models.Utils;
|
||||
@@ -12,15 +13,15 @@ namespace SPTarkov.Server.Core.Helpers;
|
||||
|
||||
[Injectable(InjectionType.Singleton)]
|
||||
public class TraderAssortHelper(
|
||||
ISptLogger<TraderAssortHelper> _logger,
|
||||
TimeUtil _timeUtil,
|
||||
DatabaseService _databaseService,
|
||||
ProfileHelper _profileHelper,
|
||||
AssortHelper _assortHelper,
|
||||
TraderPurchasePersisterService _traderPurchasePersisterService,
|
||||
TraderHelper _traderHelper,
|
||||
FenceService _fenceService,
|
||||
ICloner _cloner
|
||||
ISptLogger<TraderAssortHelper> logger,
|
||||
TimeUtil timeUtil,
|
||||
DatabaseService databaseService,
|
||||
ProfileHelper profileHelper,
|
||||
AssortHelper assortHelper,
|
||||
TraderPurchasePersisterService traderPurchasePersisterService,
|
||||
TraderHelper traderHelper,
|
||||
FenceService fenceService,
|
||||
ICloner cloner
|
||||
)
|
||||
{
|
||||
private Dictionary<string, Dictionary<string, string>>? _mergedQuestAssorts;
|
||||
@@ -38,21 +39,25 @@ public class TraderAssortHelper(
|
||||
/// <param name="traderId">traders id</param>
|
||||
/// <param name="showLockedAssorts">Should assorts player hasn't unlocked be returned - default false</param>
|
||||
/// <returns>a traders' assorts</returns>
|
||||
public TraderAssort GetAssort(string sessionId, string traderId, bool showLockedAssorts = false)
|
||||
public TraderAssort GetAssort(
|
||||
MongoId sessionId,
|
||||
MongoId traderId,
|
||||
bool showLockedAssorts = false
|
||||
)
|
||||
{
|
||||
var traderClone = _cloner.Clone(_databaseService.GetTrader(traderId));
|
||||
var fullProfile = _profileHelper.GetFullProfile(sessionId);
|
||||
var traderClone = cloner.Clone(databaseService.GetTrader(traderId));
|
||||
var fullProfile = profileHelper.GetFullProfile(sessionId);
|
||||
var pmcProfile = fullProfile?.CharacterData?.PmcData;
|
||||
|
||||
if (traderId == Traders.FENCE)
|
||||
{
|
||||
return _fenceService.GetFenceAssorts(pmcProfile);
|
||||
return fenceService.GetFenceAssorts(pmcProfile);
|
||||
}
|
||||
|
||||
// Strip assorts player should not see yet
|
||||
if (!showLockedAssorts)
|
||||
{
|
||||
traderClone.Assort = _assortHelper.StripLockedLoyaltyAssort(
|
||||
traderClone.Assort = assortHelper.StripLockedLoyaltyAssort(
|
||||
pmcProfile,
|
||||
traderId,
|
||||
traderClone.Assort
|
||||
@@ -65,7 +70,7 @@ public class TraderAssortHelper(
|
||||
traderClone.Assort.NextResupply = traderClone.Base.NextResupply;
|
||||
|
||||
// Adjust displayed assort counts based on values stored in profile
|
||||
var assortPurchasesfromTrader = _traderPurchasePersisterService.GetProfileTraderPurchases(
|
||||
var assortPurchasesfromTrader = traderPurchasePersisterService.GetProfileTraderPurchases(
|
||||
sessionId,
|
||||
traderId
|
||||
);
|
||||
@@ -76,9 +81,9 @@ public class TraderAssortHelper(
|
||||
var assortToAdjust = traderClone.Assort.Items.FirstOrDefault(x => x.Id == assortId.Key);
|
||||
if (assortToAdjust is null)
|
||||
{
|
||||
if (_logger.IsLogEnabled(LogLevel.Debug))
|
||||
if (logger.IsLogEnabled(LogLevel.Debug))
|
||||
{
|
||||
_logger.Debug(
|
||||
logger.Debug(
|
||||
$"Cannot find trader: {traderClone.Base.Nickname} assort: {assortId} to adjust BuyRestrictionCurrent value, skipping"
|
||||
);
|
||||
}
|
||||
@@ -88,9 +93,9 @@ public class TraderAssortHelper(
|
||||
|
||||
if (assortToAdjust.Upd is null)
|
||||
{
|
||||
if (_logger.IsLogEnabled(LogLevel.Debug))
|
||||
if (logger.IsLogEnabled(LogLevel.Debug))
|
||||
{
|
||||
_logger.Debug(
|
||||
logger.Debug(
|
||||
$"Unable to adjust assort: {assortToAdjust.Id} item: {assortToAdjust.Template} BuyRestrictionCurrent value, assort has a null upd object"
|
||||
);
|
||||
}
|
||||
@@ -103,7 +108,7 @@ public class TraderAssortHelper(
|
||||
);
|
||||
}
|
||||
|
||||
traderClone.Assort = _assortHelper.StripLockedQuestAssort(
|
||||
traderClone.Assort = assortHelper.StripLockedQuestAssort(
|
||||
pmcProfile,
|
||||
traderId,
|
||||
traderClone.Assort,
|
||||
@@ -148,7 +153,7 @@ public class TraderAssortHelper(
|
||||
var result = new Dictionary<string, Dictionary<string, string>>();
|
||||
|
||||
// Loop every trader
|
||||
var traders = _databaseService.GetTraders();
|
||||
var traders = databaseService.GetTraders();
|
||||
foreach (var (_, trader) in traders)
|
||||
{
|
||||
if (trader?.QuestAssort is null)
|
||||
@@ -188,7 +193,7 @@ public class TraderAssortHelper(
|
||||
trader.Assort.Items = GetPristineTraderAssorts(trader.Base.Id);
|
||||
|
||||
// Update resupply value to next timestamp
|
||||
trader.Base.NextResupply = (int)_traderHelper.GetNextUpdateTimestamp(trader.Base.Id);
|
||||
trader.Base.NextResupply = (int)traderHelper.GetNextUpdateTimestamp(trader.Base.Id);
|
||||
|
||||
// Flag a refresh is needed so ragfair update() will pick it up
|
||||
trader.Base.RefreshTraderRagfairOffers = true;
|
||||
@@ -199,10 +204,10 @@ public class TraderAssortHelper(
|
||||
/// </summary>
|
||||
/// <param name="traderID">Trader to check</param>
|
||||
/// <returns>true they need refreshing</returns>
|
||||
public bool TraderAssortsHaveExpired(string traderID)
|
||||
public bool TraderAssortsHaveExpired(MongoId traderID)
|
||||
{
|
||||
var time = _timeUtil.GetTimeStamp();
|
||||
var trader = _databaseService.GetTables().Traders[traderID];
|
||||
var time = timeUtil.GetTimeStamp();
|
||||
var trader = databaseService.GetTables().Traders[traderID];
|
||||
|
||||
return trader.Base.NextResupply <= time;
|
||||
}
|
||||
@@ -212,8 +217,8 @@ public class TraderAssortHelper(
|
||||
/// </summary>
|
||||
/// <param name="traderId">trader id</param>
|
||||
/// <returns>array of Items</returns>
|
||||
protected List<Item> GetPristineTraderAssorts(string traderId)
|
||||
protected List<Item> GetPristineTraderAssorts(MongoId traderId)
|
||||
{
|
||||
return _cloner.Clone(_traderHelper.GetTraderAssortsByTraderId(traderId).Items);
|
||||
return cloner.Clone(traderHelper.GetTraderAssortsByTraderId(traderId).Items);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -16,17 +16,17 @@ namespace SPTarkov.Server.Core.Helpers;
|
||||
|
||||
[Injectable]
|
||||
public class TraderHelper(
|
||||
ISptLogger<TraderHelper> _logger,
|
||||
DatabaseService _databaseService,
|
||||
ProfileHelper _profileHelper,
|
||||
HandbookHelper _handbookHelper,
|
||||
ItemHelper _itemHelper,
|
||||
ServerLocalisationService _serverLocalisationService,
|
||||
FenceService _fenceService,
|
||||
TraderStore _traderStore,
|
||||
TimeUtil _timeUtil,
|
||||
RandomUtil _randomUtil,
|
||||
ConfigServer _configServer
|
||||
ISptLogger<TraderHelper> logger,
|
||||
DatabaseService databaseService,
|
||||
ProfileHelper profileHelper,
|
||||
HandbookHelper handbookHelper,
|
||||
ItemHelper itemHelper,
|
||||
ServerLocalisationService serverLocalisationService,
|
||||
FenceService fenceService,
|
||||
TraderStore traderStore,
|
||||
TimeUtil timeUtil,
|
||||
RandomUtil randomUtil,
|
||||
ConfigServer configServer
|
||||
)
|
||||
{
|
||||
protected readonly List<string> _gameVersions =
|
||||
@@ -35,11 +35,11 @@ public class TraderHelper(
|
||||
GameEditions.UNHEARD,
|
||||
];
|
||||
protected readonly Dictionary<string, double> _highestTraderPriceItems = new();
|
||||
protected readonly TraderConfig _traderConfig = _configServer.GetConfig<TraderConfig>();
|
||||
protected readonly TraderConfig _traderConfig = configServer.GetConfig<TraderConfig>();
|
||||
|
||||
public TraderBase? GetTraderByNickName(string traderName)
|
||||
{
|
||||
return _databaseService
|
||||
return databaseService
|
||||
.GetTraders()
|
||||
.Select(dict => dict.Value.Base)
|
||||
.FirstOrDefault(t =>
|
||||
@@ -55,18 +55,18 @@ public class TraderHelper(
|
||||
/// <param name="traderID">Traders Id to get</param>
|
||||
/// <param name="sessionID">Players id</param>
|
||||
/// <returns>Trader base</returns>
|
||||
public TraderBase? GetTrader(string traderID, string sessionID)
|
||||
public TraderBase? GetTrader(string traderID, MongoId sessionID)
|
||||
{
|
||||
if (traderID == "ragfair")
|
||||
{
|
||||
return new TraderBase { Currency = CurrencyType.RUB };
|
||||
}
|
||||
|
||||
var pmcData = _profileHelper.GetPmcProfile(sessionID);
|
||||
var pmcData = profileHelper.GetPmcProfile(sessionID);
|
||||
if (pmcData == null)
|
||||
{
|
||||
throw new Exception(
|
||||
_serverLocalisationService.GetText(
|
||||
serverLocalisationService.GetText(
|
||||
"trader-unable_to_find_profile_with_id",
|
||||
sessionID
|
||||
)
|
||||
@@ -81,11 +81,11 @@ public class TraderHelper(
|
||||
LevelUp(traderID, pmcData);
|
||||
}
|
||||
|
||||
var traderBase = _databaseService.GetTrader(traderID).Base;
|
||||
var traderBase = databaseService.GetTrader(traderID).Base;
|
||||
if (traderBase == null)
|
||||
{
|
||||
_logger.Error(
|
||||
_serverLocalisationService.GetText("trader-unable_to_find_trader_by_id", traderID)
|
||||
logger.Error(
|
||||
serverLocalisationService.GetText("trader-unable_to_find_trader_by_id", traderID)
|
||||
);
|
||||
}
|
||||
|
||||
@@ -100,8 +100,8 @@ public class TraderHelper(
|
||||
public TraderAssort GetTraderAssortsByTraderId(MongoId traderId)
|
||||
{
|
||||
return traderId == Traders.FENCE
|
||||
? _fenceService.GetRawFenceAssorts()
|
||||
: _databaseService.GetTrader(traderId).Assort;
|
||||
? fenceService.GetRawFenceAssorts()
|
||||
: databaseService.GetTrader(traderId).Assort;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -115,9 +115,9 @@ public class TraderHelper(
|
||||
var traderAssorts = GetTraderAssortsByTraderId(traderId);
|
||||
if (traderAssorts is null)
|
||||
{
|
||||
if (_logger.IsLogEnabled(LogLevel.Debug))
|
||||
if (logger.IsLogEnabled(LogLevel.Debug))
|
||||
{
|
||||
_logger.Debug($"No assorts on trader: {traderId} found");
|
||||
logger.Debug($"No assorts on trader: {traderId} found");
|
||||
}
|
||||
|
||||
return null;
|
||||
@@ -127,9 +127,9 @@ public class TraderHelper(
|
||||
var purchasedAssort = traderAssorts.Items.FirstOrDefault(item => item.Id == assortId);
|
||||
if (purchasedAssort is null)
|
||||
{
|
||||
if (_logger.IsLogEnabled(LogLevel.Debug))
|
||||
if (logger.IsLogEnabled(LogLevel.Debug))
|
||||
{
|
||||
_logger.Debug($"No assort {assortId} on trader: {traderId} found");
|
||||
logger.Debug($"No assort {assortId} on trader: {traderId} found");
|
||||
}
|
||||
|
||||
return null;
|
||||
@@ -144,22 +144,22 @@ public class TraderHelper(
|
||||
/// </summary>
|
||||
/// <param name="sessionID">session id of player</param>
|
||||
/// <param name="traderID">trader id to reset</param>
|
||||
public void ResetTrader(string sessionID, string traderID)
|
||||
public void ResetTrader(MongoId sessionID, MongoId traderID)
|
||||
{
|
||||
var profiles = _databaseService.GetProfileTemplates();
|
||||
var trader = _databaseService.GetTrader(traderID);
|
||||
var profiles = databaseService.GetProfileTemplates();
|
||||
var trader = databaseService.GetTrader(traderID);
|
||||
|
||||
var fullProfile = _profileHelper.GetFullProfile(sessionID);
|
||||
var fullProfile = profileHelper.GetFullProfile(sessionID);
|
||||
if (fullProfile is null)
|
||||
{
|
||||
throw new Exception(
|
||||
_serverLocalisationService.GetText("trader-unable_to_find_profile_by_id", sessionID)
|
||||
serverLocalisationService.GetText("trader-unable_to_find_profile_by_id", sessionID)
|
||||
);
|
||||
}
|
||||
|
||||
// Get matching profile 'type' e.g. 'standard'
|
||||
var pmcData = fullProfile.CharacterData.PmcData;
|
||||
var matchingSide = _profileHelper.GetProfileTemplateForSide(
|
||||
var matchingSide = profileHelper.GetProfileTemplateForSide(
|
||||
fullProfile.ProfileInfo.Edition,
|
||||
pmcData.Info.Side
|
||||
);
|
||||
@@ -195,7 +195,7 @@ public class TraderHelper(
|
||||
)
|
||||
{
|
||||
// Get traders clothing
|
||||
var clothing = _databaseService.GetTrader(traderID).Suits;
|
||||
var clothing = databaseService.GetTrader(traderID).Suits;
|
||||
if (clothing?.Count > 0)
|
||||
// Force suit ids into profile
|
||||
{
|
||||
@@ -206,7 +206,7 @@ public class TraderHelper(
|
||||
// Template has flea block
|
||||
if ((profileTemplateTraderData.FleaBlockedDays ?? 0) > 0)
|
||||
{
|
||||
var newBanDateTime = _timeUtil.GetTimeStampFromNowDays(
|
||||
var newBanDateTime = timeUtil.GetTimeStampFromNowDays(
|
||||
profileTemplateTraderData.FleaBlockedDays ?? 0
|
||||
);
|
||||
var existingBan = pmcData.Info.Bans?.FirstOrDefault(ban =>
|
||||
@@ -237,7 +237,10 @@ public class TraderHelper(
|
||||
/// <param name="traderId">Trader id to get standing for</param>
|
||||
/// <param name="rawProfileTemplate">Raw profile from profiles.json to look up standing from</param>
|
||||
/// <returns>Standing value</returns>
|
||||
protected double? GetStartingStanding(string traderId, ProfileTraderTemplate rawProfileTemplate)
|
||||
protected double? GetStartingStanding(
|
||||
MongoId traderId,
|
||||
ProfileTraderTemplate rawProfileTemplate
|
||||
)
|
||||
{
|
||||
if (rawProfileTemplate.InitialStanding.TryGetValue(traderId, out var standing))
|
||||
{
|
||||
@@ -259,13 +262,13 @@ public class TraderHelper(
|
||||
/// <param name="traderId">Trader to alter</param>
|
||||
/// <param name="status">New status to use</param>
|
||||
/// <param name="sessionId">Session id of player</param>
|
||||
public void SetTraderUnlockedState(string traderId, bool status, string sessionId)
|
||||
public void SetTraderUnlockedState(MongoId traderId, bool status, MongoId sessionId)
|
||||
{
|
||||
var pmcData = _profileHelper.GetPmcProfile(sessionId);
|
||||
var pmcData = profileHelper.GetPmcProfile(sessionId);
|
||||
var profileTraderData = pmcData.TradersInfo[traderId];
|
||||
if (profileTraderData is null)
|
||||
{
|
||||
_logger.Error(
|
||||
logger.Error(
|
||||
$"Unable to set trader {traderId} unlocked state to: {status} as trader cannot be found in profile"
|
||||
);
|
||||
|
||||
@@ -281,9 +284,9 @@ public class TraderHelper(
|
||||
/// <param name="sessionId">Session id of player</param>
|
||||
/// <param name="traderId">Traders id to add standing to</param>
|
||||
/// <param name="standingToAdd">Standing value to add to trader</param>
|
||||
public void AddStandingToTrader(string sessionId, string traderId, double standingToAdd)
|
||||
public void AddStandingToTrader(MongoId sessionId, MongoId traderId, double standingToAdd)
|
||||
{
|
||||
var fullProfile = _profileHelper.GetFullProfile(sessionId);
|
||||
var fullProfile = profileHelper.GetFullProfile(sessionId);
|
||||
var pmcTraderInfo = fullProfile.CharacterData.PmcData.TradersInfo[traderId];
|
||||
|
||||
// Add standing to trader
|
||||
@@ -317,10 +320,10 @@ public class TraderHelper(
|
||||
/// Iterate over a profile's traders and ensure they have the correct loyalty level for the player.
|
||||
/// </summary>
|
||||
/// <param name="sessionId">Profile to check.</param>
|
||||
public void ValidateTraderStandingsAndPlayerLevelForProfile(string sessionId)
|
||||
public void ValidateTraderStandingsAndPlayerLevelForProfile(MongoId sessionId)
|
||||
{
|
||||
var profile = _profileHelper.GetPmcProfile(sessionId);
|
||||
var traders = _databaseService.GetTraders();
|
||||
var profile = profileHelper.GetPmcProfile(sessionId);
|
||||
var traders = databaseService.GetTraders();
|
||||
foreach (var trader in traders)
|
||||
{
|
||||
LevelUp(trader.Key, profile);
|
||||
@@ -333,13 +336,13 @@ public class TraderHelper(
|
||||
/// </summary>
|
||||
/// <param name="traderID">Trader to check standing of.</param>
|
||||
/// <param name="pmcData">Profile to update trader in.</param>
|
||||
public void LevelUp(string traderID, PmcData pmcData)
|
||||
public void LevelUp(MongoId traderID, PmcData pmcData)
|
||||
{
|
||||
var loyaltyLevels = _databaseService.GetTrader(traderID).Base.LoyaltyLevels;
|
||||
var loyaltyLevels = databaseService.GetTrader(traderID).Base.LoyaltyLevels;
|
||||
|
||||
// Level up player
|
||||
pmcData.Info.Level = pmcData.CalculateLevel(
|
||||
_databaseService.GetGlobals().Configuration.Exp.Level.ExperienceTable
|
||||
databaseService.GetGlobals().Configuration.Exp.Level.ExperienceTable
|
||||
);
|
||||
|
||||
// Level up traders
|
||||
@@ -372,9 +375,9 @@ public class TraderHelper(
|
||||
/// </summary>
|
||||
/// <param name="traderID">Trader to look up update value for.</param>
|
||||
/// <returns>Future timestamp.</returns>
|
||||
public long GetNextUpdateTimestamp(string traderID)
|
||||
public long GetNextUpdateTimestamp(MongoId traderID)
|
||||
{
|
||||
var time = _timeUtil.GetTimeStamp();
|
||||
var time = timeUtil.GetTimeStamp();
|
||||
var updateSeconds = GetTraderUpdateSeconds(traderID) ?? 0;
|
||||
return time + updateSeconds;
|
||||
}
|
||||
@@ -384,13 +387,13 @@ public class TraderHelper(
|
||||
/// </summary>
|
||||
/// <param name="traderId">Trader to look up.</param>
|
||||
/// <returns>Time in seconds.</returns>
|
||||
public long? GetTraderUpdateSeconds(string traderId)
|
||||
public long? GetTraderUpdateSeconds(MongoId traderId)
|
||||
{
|
||||
var traderDetails = _traderConfig.UpdateTime.FirstOrDefault(x => x.TraderId == traderId);
|
||||
if (traderDetails?.Seconds?.Min is null || traderDetails.Seconds?.Max is null)
|
||||
{
|
||||
_logger.Warning(
|
||||
_serverLocalisationService.GetText(
|
||||
logger.Warning(
|
||||
serverLocalisationService.GetText(
|
||||
"trader-missing_trader_details_using_default_refresh_time",
|
||||
new { traderId, updateTime = _traderConfig.UpdateTimeDefault }
|
||||
)
|
||||
@@ -411,12 +414,12 @@ public class TraderHelper(
|
||||
return null;
|
||||
}
|
||||
|
||||
return _randomUtil.GetInt(traderDetails.Seconds.Min, traderDetails.Seconds.Max);
|
||||
return randomUtil.GetInt(traderDetails.Seconds.Min, traderDetails.Seconds.Max);
|
||||
}
|
||||
|
||||
public TraderLoyaltyLevel GetLoyaltyLevel(string traderID, PmcData pmcData)
|
||||
public TraderLoyaltyLevel GetLoyaltyLevel(MongoId traderID, PmcData pmcData)
|
||||
{
|
||||
var traderBase = _databaseService.GetTrader(traderID).Base;
|
||||
var traderBase = databaseService.GetTrader(traderID).Base;
|
||||
|
||||
int? loyaltyLevel = null;
|
||||
if (pmcData.TradersInfo.TryGetValue(traderID, out var traderInfo))
|
||||
@@ -443,18 +446,18 @@ public class TraderHelper(
|
||||
/// <param name="sessionID">Session id</param>
|
||||
/// <param name="newPurchaseDetails">New item assort id + count</param>
|
||||
public void AddTraderPurchasesToPlayerProfile(
|
||||
string sessionID,
|
||||
MongoId sessionID,
|
||||
PurchaseDetails newPurchaseDetails,
|
||||
Item itemPurchased
|
||||
)
|
||||
{
|
||||
var profile = _profileHelper.GetFullProfile(sessionID);
|
||||
var profile = profileHelper.GetFullProfile(sessionID);
|
||||
var traderId = newPurchaseDetails.TraderId;
|
||||
|
||||
// Iterate over assorts bought and add to profile
|
||||
foreach (var purchasedItem in newPurchaseDetails.Items)
|
||||
{
|
||||
var currentTime = _timeUtil.GetTimeStamp();
|
||||
var currentTime = timeUtil.GetTimeStamp();
|
||||
|
||||
// Nullguard traderPurchases
|
||||
profile.TraderPurchases ??=
|
||||
@@ -488,7 +491,7 @@ public class TraderHelper(
|
||||
)
|
||||
{
|
||||
throw new Exception(
|
||||
_serverLocalisationService.GetText(
|
||||
serverLocalisationService.GetText(
|
||||
"trader-unable_to_purchase_item_limit_reached",
|
||||
new { traderId, limit = itemPurchased.Upd.BuyRestrictionMax }
|
||||
)
|
||||
@@ -534,7 +537,7 @@ public class TraderHelper(
|
||||
}
|
||||
|
||||
// Init dict and fill
|
||||
foreach (var trader in _traderStore.GetAllTraders())
|
||||
foreach (var trader in traderStore.GetAllTraders())
|
||||
{
|
||||
// Skip some traders
|
||||
if (trader.Id == Traders.FENCE)
|
||||
@@ -543,7 +546,7 @@ public class TraderHelper(
|
||||
}
|
||||
|
||||
// Get assorts for trader, skip trader if no assorts found
|
||||
var traderAssorts = _databaseService.GetTrader(trader.Id).Assort;
|
||||
var traderAssorts = databaseService.GetTrader(trader.Id).Assort;
|
||||
if (traderAssorts is null)
|
||||
{
|
||||
continue;
|
||||
@@ -562,7 +565,7 @@ public class TraderHelper(
|
||||
var roubleAmount =
|
||||
barterScheme.Template == Money.ROUBLES
|
||||
? barterScheme.Count
|
||||
: _handbookHelper.InRUB(barterScheme.Count ?? 1, barterScheme.Template);
|
||||
: handbookHelper.InRUB(barterScheme.Count ?? 1, barterScheme.Template);
|
||||
|
||||
// Existing price smaller in dict than current iteration, overwrite
|
||||
if (_highestTraderPriceItems[item.Template] < roubleAmount)
|
||||
@@ -584,15 +587,15 @@ public class TraderHelper(
|
||||
{
|
||||
// Find largest trader price for item
|
||||
var highestPrice = 1d; // Default price
|
||||
foreach (var trader in _traderStore.GetAllTraders())
|
||||
foreach (var trader in traderStore.GetAllTraders())
|
||||
{
|
||||
// Get trader and check buy category allows tpl
|
||||
var traderBase = _databaseService.GetTrader(trader.Id).Base;
|
||||
var traderBase = databaseService.GetTrader(trader.Id).Base;
|
||||
|
||||
// Skip traders that don't sell this category of item
|
||||
if (
|
||||
traderBase is null
|
||||
|| !_itemHelper.IsOfBaseclasses(tpl, traderBase.ItemsBuy.Category)
|
||||
|| !itemHelper.IsOfBaseclasses(tpl, traderBase.ItemsBuy.Category)
|
||||
)
|
||||
{
|
||||
continue;
|
||||
@@ -604,8 +607,8 @@ public class TraderHelper(
|
||||
var traderBuyBackPricePercent =
|
||||
100 - traderBase.LoyaltyLevels.FirstOrDefault().BuyPriceCoefficient;
|
||||
|
||||
var itemHandbookPrice = _handbookHelper.GetTemplatePrice(tpl);
|
||||
var priceTraderBuysItemAt = _randomUtil.GetPercentOfValue(
|
||||
var itemHandbookPrice = handbookHelper.GetTemplatePrice(tpl);
|
||||
var priceTraderBuysItemAt = randomUtil.GetPercentOfValue(
|
||||
traderBuyBackPricePercent ?? 0,
|
||||
itemHandbookPrice,
|
||||
0
|
||||
@@ -626,8 +629,8 @@ public class TraderHelper(
|
||||
/// </summary>
|
||||
/// <param name="traderId">Trader id</param>
|
||||
/// <returns>True if a Trader exists with given ID</returns>
|
||||
public bool TraderExists(string traderId)
|
||||
public bool TraderExists(MongoId traderId)
|
||||
{
|
||||
return _traderStore.GetTraderById(traderId) != null;
|
||||
return traderStore.GetTraderById(traderId) != null;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -9,12 +9,12 @@ namespace SPTarkov.Server.Core.Helpers;
|
||||
|
||||
[Injectable]
|
||||
public class WeatherHelper(
|
||||
ISptLogger<WeatherHelper> _logger,
|
||||
TimeUtil _timeUtil,
|
||||
ConfigServer _configServer
|
||||
ISptLogger<WeatherHelper> logger,
|
||||
TimeUtil timeUtil,
|
||||
ConfigServer configServer
|
||||
)
|
||||
{
|
||||
protected readonly WeatherConfig _weatherConfig = _configServer.GetConfig<WeatherConfig>();
|
||||
protected readonly WeatherConfig _weatherConfig = configServer.GetConfig<WeatherConfig>();
|
||||
|
||||
/// <summary>
|
||||
/// Assumes current time
|
||||
@@ -23,7 +23,7 @@ public class WeatherHelper(
|
||||
/// <returns>Date object of current in-raid time</returns>
|
||||
public DateTime GetInRaidTime()
|
||||
{
|
||||
return GetInRaidTime(_timeUtil.GetTimeStamp());
|
||||
return GetInRaidTime(timeUtil.GetTimeStamp());
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -34,11 +34,11 @@ public class WeatherHelper(
|
||||
public DateTime GetInRaidTime(long timestamp)
|
||||
{
|
||||
// tarkov time = (real time * 7 % 24 hr) + 3 hour
|
||||
var russiaOffsetSeconds = _timeUtil.GetHoursAsSeconds(3);
|
||||
var twentyFourHoursSeconds = _timeUtil.GetHoursAsSeconds(24);
|
||||
var russiaOffsetSeconds = timeUtil.GetHoursAsSeconds(3);
|
||||
var twentyFourHoursSeconds = timeUtil.GetHoursAsSeconds(24);
|
||||
var currentTimestampSeconds = timestamp;
|
||||
|
||||
var tarkovTime = _timeUtil.GetDateTimeFromTimeStamp(
|
||||
var tarkovTime = timeUtil.GetDateTimeFromTimeStamp(
|
||||
(long)(russiaOffsetSeconds + currentTimestampSeconds * _weatherConfig.Acceleration)
|
||||
% twentyFourHoursSeconds
|
||||
);
|
||||
|
||||
@@ -9,9 +9,9 @@ namespace SPTarkov.Server.Core.Helpers;
|
||||
|
||||
[Injectable]
|
||||
public class WeightedRandomHelper(
|
||||
ISptLogger<WeightedRandomHelper> _logger,
|
||||
ISptLogger<WeightedRandomHelper> logger,
|
||||
ServerLocalisationService localisationService,
|
||||
RandomUtil _randomUtil
|
||||
RandomUtil randomUtil
|
||||
)
|
||||
{
|
||||
/// <summary>
|
||||
@@ -51,19 +51,19 @@ public class WeightedRandomHelper(
|
||||
{
|
||||
if (items.Count == 0)
|
||||
{
|
||||
_logger.Error(localisationService.GetText("weightedrandomhelper-supplied_items_empty"));
|
||||
logger.Error(localisationService.GetText("weightedrandomhelper-supplied_items_empty"));
|
||||
}
|
||||
|
||||
if (weights.Count == 0)
|
||||
{
|
||||
_logger.Error(
|
||||
logger.Error(
|
||||
localisationService.GetText("weightedrandomhelper-supplied_weights_empty")
|
||||
);
|
||||
}
|
||||
|
||||
if (items.Count != weights.Count)
|
||||
{
|
||||
_logger.Error(
|
||||
logger.Error(
|
||||
localisationService.GetText(
|
||||
"weightedrandomhelper-supplied_data_doesnt_match",
|
||||
new { itemCount = items.Count, weightCount = weights.Count }
|
||||
@@ -78,7 +78,7 @@ public class WeightedRandomHelper(
|
||||
{
|
||||
if (weights[i] < 0)
|
||||
{
|
||||
_logger.Warning($"Weight at index: {i} is negative ({weights[i]}), skipping");
|
||||
logger.Warning($"Weight at index: {i} is negative ({weights[i]}), skipping");
|
||||
continue;
|
||||
}
|
||||
|
||||
@@ -89,12 +89,12 @@ public class WeightedRandomHelper(
|
||||
if (sumOfWeights == weights.Count)
|
||||
{
|
||||
// Weights are all the same, early exit
|
||||
var randomIndex = _randomUtil.GetInt(0, items.Count - 1);
|
||||
var randomIndex = randomUtil.GetInt(0, items.Count - 1);
|
||||
return new WeightedRandomResult<T> { Item = items[randomIndex], Index = randomIndex };
|
||||
}
|
||||
|
||||
// Getting the random number in a range of [0...sum(weights)]
|
||||
var randomNumber = sumOfWeights * _randomUtil.GetDouble(0, 1);
|
||||
var randomNumber = sumOfWeights * randomUtil.GetDouble(0, 1);
|
||||
|
||||
// Picking the random item based on its weight.
|
||||
for (var itemIndex = 0; itemIndex < items.Count; itemIndex++)
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
using System.Text.Json.Serialization;
|
||||
using SPTarkov.Server.Core.Models.Common;
|
||||
|
||||
namespace SPTarkov.Server.Core.Models.Eft.Common.Tables;
|
||||
|
||||
@@ -11,7 +12,7 @@ public record Achievement
|
||||
public required int Index { get; set; }
|
||||
|
||||
[JsonPropertyName("id")]
|
||||
public required string Id { get; set; }
|
||||
public required MongoId Id { get; set; }
|
||||
|
||||
[JsonPropertyName("imageUrl")]
|
||||
public required string ImageUrl { get; set; }
|
||||
|
||||
@@ -42,7 +42,7 @@ public record Quest
|
||||
public string? Note { get; set; }
|
||||
|
||||
[JsonPropertyName("traderId")]
|
||||
public required string TraderId { get; set; }
|
||||
public required MongoId TraderId { get; set; }
|
||||
|
||||
[JsonPropertyName("location")]
|
||||
public required string Location { get; set; }
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
using System.Text.Json.Serialization;
|
||||
using SPTarkov.Server.Core.Models.Common;
|
||||
using SPTarkov.Server.Core.Models.Enums;
|
||||
using SPTarkov.Server.Core.Models.Utils;
|
||||
|
||||
@@ -70,7 +71,7 @@ public record SearchRequestData : IRequestData
|
||||
public string? NeededSearchId { get; set; }
|
||||
|
||||
[JsonPropertyName("buildItems")]
|
||||
public Dictionary<string, double>? BuildItems { get; set; }
|
||||
public Dictionary<MongoId, double>? BuildItems { get; set; }
|
||||
|
||||
[JsonPropertyName("buildCount")]
|
||||
public int? BuildCount { get; set; }
|
||||
|
||||
Reference in New Issue
Block a user