Service sessionIDs to mongoIDs (#454)
* Start updating service sessionIDs to mongoIDs * Finish service conversion + fix other small issues
This commit is contained in:
@@ -899,10 +899,9 @@ public class ItemHelper(
|
||||
)
|
||||
{
|
||||
// Find required items to take after buying (handles multiple items)
|
||||
var desiredBarterIds =
|
||||
desiredBarterItemIds.GetType() == typeof(string)
|
||||
? [(string)desiredBarterItemIds]
|
||||
: (List<string>)desiredBarterItemIds;
|
||||
var desiredBarterIds = desiredBarterItemIds is MongoId id
|
||||
? [id]
|
||||
: (List<MongoId>)desiredBarterItemIds;
|
||||
|
||||
List<Item> matchingItems = [];
|
||||
foreach (var barterId in desiredBarterIds)
|
||||
|
||||
@@ -129,7 +129,7 @@ public class PrestigeHelper
|
||||
itemsToTransfer.Add(item);
|
||||
}
|
||||
|
||||
_mailSendService.SendSystemMessageToPlayer(sessionId, "", itemsToTransfer, 31536000);
|
||||
_mailSendService.SendSystemMessageToPlayer(sessionId.Value, "", itemsToTransfer, 31536000);
|
||||
|
||||
newProfile.CharacterData.PmcData.Info.PrestigeLevel = prestige.PrestigeLevel;
|
||||
}
|
||||
|
||||
@@ -97,7 +97,7 @@ public class TraderHelper(
|
||||
/// </summary>
|
||||
/// <param name="traderId">Trader to get assorts for</param>
|
||||
/// <returns>TraderAssort</returns>
|
||||
public TraderAssort GetTraderAssortsByTraderId(string traderId)
|
||||
public TraderAssort GetTraderAssortsByTraderId(MongoId traderId)
|
||||
{
|
||||
return traderId == Traders.FENCE
|
||||
? _fenceService.GetRawFenceAssorts()
|
||||
@@ -110,7 +110,7 @@ public class TraderHelper(
|
||||
/// <param name="traderId">Trader to get assorts for</param>
|
||||
/// <param name="assortId">Id of assort to find</param>
|
||||
/// <returns>Item object</returns>
|
||||
public Item? GetTraderAssortItemByAssortId(string traderId, string assortId)
|
||||
public Item? GetTraderAssortItemByAssortId(MongoId traderId, MongoId assortId)
|
||||
{
|
||||
var traderAssorts = GetTraderAssortsByTraderId(traderId);
|
||||
if (traderAssorts is null)
|
||||
|
||||
@@ -33,7 +33,7 @@ public class BotEquipmentFilterService(
|
||||
/// <param name="botLevel">Level of the bot</param>
|
||||
/// <param name="botGenerationDetails">details on how to generate a bot</param>
|
||||
public void FilterBotEquipment(
|
||||
string sessionId,
|
||||
MongoId sessionId,
|
||||
BotType baseBotNode,
|
||||
int botLevel,
|
||||
BotGenerationDetails botGenerationDetails
|
||||
|
||||
@@ -215,7 +215,7 @@ public class BotEquipmentModPoolService(
|
||||
/// </summary>
|
||||
/// <param name="itemTpl"> Weapons tpl to look up mods for </param>
|
||||
/// <returns> Dictionary of mods (keys are mod slot names) with array of compatible mod tpls as value </returns>
|
||||
public Dictionary<string, HashSet<MongoId>>? GetRequiredModsForWeaponSlot(MongoId itemTpl)
|
||||
public Dictionary<string, HashSet<MongoId>> GetRequiredModsForWeaponSlot(MongoId itemTpl)
|
||||
{
|
||||
var result = new Dictionary<string, HashSet<MongoId>>();
|
||||
|
||||
|
||||
@@ -1,120 +0,0 @@
|
||||
using System.Collections.Concurrent;
|
||||
using SPTarkov.Common.Extensions;
|
||||
using SPTarkov.DI.Annotations;
|
||||
using SPTarkov.Server.Core.Models.Eft.Common.Tables;
|
||||
using SPTarkov.Server.Core.Models.Utils;
|
||||
|
||||
namespace SPTarkov.Server.Core.Services;
|
||||
|
||||
[Injectable(InjectionType.Singleton)]
|
||||
public class BotGenerationCacheService(
|
||||
ISptLogger<BotGenerationCacheService> _logger,
|
||||
ServerLocalisationService _serverLocalisationService
|
||||
)
|
||||
{
|
||||
protected readonly Queue<BotBase> _activeBotsInRaid = [];
|
||||
protected readonly ConcurrentDictionary<string, List<BotBase>> _storedBots = new();
|
||||
|
||||
/// <summary>
|
||||
/// Store list of bots in cache, shuffle results before storage
|
||||
/// </summary>
|
||||
/// <param name="key"> Role bot is stored as (assault/bossTagilla etc.) </param>
|
||||
/// <param name="botsToStore"> Bots we want to store in the cache </param>
|
||||
public void StoreBots(string key, List<BotBase> botsToStore)
|
||||
{
|
||||
foreach (var bot in botsToStore)
|
||||
{
|
||||
if (!_storedBots.TryAdd(key, [bot]))
|
||||
{
|
||||
_storedBots[key].Add(bot);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Find and return a bot based on its role. <br />
|
||||
/// Remove bot from internal list so it can't be retrieved again.
|
||||
/// </summary>
|
||||
/// <param name="key"> role to retrieve (assault/bossTagilla etc) </param>
|
||||
/// <returns> BotBase object </returns>
|
||||
public BotBase? GetBot(string key)
|
||||
{
|
||||
if (_storedBots.TryGetValue(key, out var bots))
|
||||
{
|
||||
if (bots.Count > 0)
|
||||
{
|
||||
try
|
||||
{
|
||||
return bots.PopLast();
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
_logger.Error(
|
||||
_serverLocalisationService.GetText(
|
||||
"bot-cache_has_zero_bots_of_requested_type",
|
||||
key
|
||||
)
|
||||
);
|
||||
_logger.Error(e.StackTrace);
|
||||
}
|
||||
}
|
||||
|
||||
_logger.Error(
|
||||
_serverLocalisationService.GetText("bot-cache_has_zero_bots_of_requested_type", key)
|
||||
);
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
_logger.Warning(_serverLocalisationService.GetText("bot-no_bot_type_in_cache", key));
|
||||
return null;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Cache a bot that has been sent to the client in memory for later use post-raid to determine if player killed a traitor scav
|
||||
/// </summary>
|
||||
/// <param name="botToStore"> Bot object to store </param>
|
||||
public void StoreUsedBot(BotBase botToStore)
|
||||
{
|
||||
_activeBotsInRaid.Enqueue(botToStore);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Get a bot by its profileId that has been generated and sent to client for current raid. <br />
|
||||
/// Cache is wiped post-raid in client/match/offline/end endOfflineRaid()
|
||||
/// </summary>
|
||||
/// <param name="profileId"> ID of bot to get </param>
|
||||
/// <returns> BotBase object </returns>
|
||||
public BotBase? GetUsedBot(string profileId)
|
||||
{
|
||||
return _activeBotsInRaid.FirstOrDefault(x => x.Id == profileId);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Remove all cached bot profiles from memory
|
||||
/// </summary>
|
||||
public void ClearStoredBots()
|
||||
{
|
||||
_storedBots.Clear();
|
||||
_activeBotsInRaid.Clear();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Does cache have a bot with requested key
|
||||
/// </summary>
|
||||
/// <returns> False if empty </returns>
|
||||
public bool CacheHasBotWithKey(string key, int size = 0)
|
||||
{
|
||||
return _storedBots.ContainsKey(key) && _storedBots[key].Count > size;
|
||||
}
|
||||
|
||||
public int GetCachedBotCount(string key)
|
||||
{
|
||||
return _storedBots.TryGetValue(key, out var bot) ? bot.Count : 0;
|
||||
}
|
||||
|
||||
public string CreateCacheKey(string? role, string? difficulty)
|
||||
{
|
||||
return $"{role?.ToLowerInvariant()}{difficulty?.ToLowerInvariant()}";
|
||||
}
|
||||
}
|
||||
@@ -13,11 +13,11 @@ namespace SPTarkov.Server.Core.Services;
|
||||
|
||||
[Injectable(InjectionType.Singleton)]
|
||||
public class BotLootCacheService(
|
||||
ISptLogger<BotLootCacheService> _logger,
|
||||
ItemHelper _itemHelper,
|
||||
PMCLootGenerator _pmcLootGenerator,
|
||||
ServerLocalisationService _serverLocalisationService,
|
||||
ICloner _cloner
|
||||
ISptLogger<BotLootCacheService> logger,
|
||||
ItemHelper itemHelper,
|
||||
PMCLootGenerator pmcLootGenerator,
|
||||
ServerLocalisationService serverLocalisationService,
|
||||
ICloner cloner
|
||||
)
|
||||
{
|
||||
protected readonly ConcurrentDictionary<string, BotLootCache> _lootCache = new();
|
||||
@@ -64,7 +64,7 @@ public class BotLootCacheService(
|
||||
|
||||
if (!_lootCache.TryGetValue(botRole, out var botRoleCache))
|
||||
{
|
||||
_logger.Error($"Unable to find: {botRole} in loot cache");
|
||||
logger.Error($"Unable to find: {botRole} in loot cache");
|
||||
return [];
|
||||
}
|
||||
|
||||
@@ -111,8 +111,8 @@ public class BotLootCacheService(
|
||||
result = botRoleCache.StimItems;
|
||||
break;
|
||||
default:
|
||||
_logger.Error(
|
||||
_serverLocalisationService.GetText(
|
||||
logger.Error(
|
||||
serverLocalisationService.GetText(
|
||||
"bot-loot_type_not_found",
|
||||
new
|
||||
{
|
||||
@@ -135,13 +135,13 @@ public class BotLootCacheService(
|
||||
if (itemPriceMinMax is null)
|
||||
{
|
||||
// No filtering requested, exit
|
||||
return _cloner.Clone(result);
|
||||
return cloner.Clone(result);
|
||||
}
|
||||
|
||||
// Filter the loot pool prior to returning
|
||||
var filteredResult = result.Where(i =>
|
||||
{
|
||||
var itemPrice = _itemHelper.GetItemPrice(i.Key);
|
||||
var itemPrice = itemHelper.GetItemPrice(i.Key);
|
||||
if (itemPriceMinMax?.Min is not null && itemPriceMinMax?.Max is not null)
|
||||
{
|
||||
return itemPrice >= itemPriceMinMax?.Min && itemPrice <= itemPriceMinMax?.Max;
|
||||
@@ -160,7 +160,7 @@ public class BotLootCacheService(
|
||||
return false;
|
||||
});
|
||||
|
||||
return _cloner.Clone(filteredResult.ToDictionary(pair => pair.Key, pair => pair.Value));
|
||||
return cloner.Clone(filteredResult.ToDictionary(pair => pair.Key, pair => pair.Value));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -185,13 +185,9 @@ public class BotLootCacheService(
|
||||
if (isPmc)
|
||||
{
|
||||
// Replace lootPool from bot json with our own generated list for PMCs
|
||||
lootPool.Backpack = _cloner.Clone(
|
||||
_pmcLootGenerator.GeneratePMCBackpackLootPool(botRole)
|
||||
);
|
||||
lootPool.Pockets = _cloner.Clone(_pmcLootGenerator.GeneratePMCPocketLootPool(botRole));
|
||||
lootPool.TacticalVest = _cloner.Clone(
|
||||
_pmcLootGenerator.GeneratePMCVestLootPool(botRole)
|
||||
);
|
||||
lootPool.Backpack = cloner.Clone(pmcLootGenerator.GeneratePMCBackpackLootPool(botRole));
|
||||
lootPool.Pockets = cloner.Clone(pmcLootGenerator.GeneratePMCPocketLootPool(botRole));
|
||||
lootPool.TacticalVest = cloner.Clone(pmcLootGenerator.GeneratePMCVestLootPool(botRole));
|
||||
}
|
||||
|
||||
// Backpack/Pockets etc
|
||||
@@ -231,7 +227,7 @@ public class BotLootCacheService(
|
||||
AddItemsToPool(backpackLootPool, itemPool);
|
||||
break;
|
||||
default:
|
||||
_logger.Warning($"How did you get here {containerType}");
|
||||
logger.Warning($"How did you get here {containerType}");
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -255,7 +251,7 @@ public class BotLootCacheService(
|
||||
// No whitelist, find and assign from combined item pool
|
||||
foreach (var itemKvP in specialLootPool)
|
||||
{
|
||||
var itemTemplate = _itemHelper.GetItem(itemKvP.Key).Value;
|
||||
var itemTemplate = itemHelper.GetItem(itemKvP.Key).Value;
|
||||
if (
|
||||
!(
|
||||
IsBulletOrGrenade(itemTemplate.Properties)
|
||||
@@ -295,7 +291,7 @@ public class BotLootCacheService(
|
||||
|
||||
foreach (var itemKvP in combinedLootPool)
|
||||
{
|
||||
var itemTemplate = _itemHelper.GetItem(itemKvP.Key).Value;
|
||||
var itemTemplate = itemHelper.GetItem(itemKvP.Key).Value;
|
||||
if (itemTemplate is null)
|
||||
{
|
||||
continue;
|
||||
@@ -333,7 +329,7 @@ public class BotLootCacheService(
|
||||
|
||||
if (addFoodItems)
|
||||
{
|
||||
if (_itemHelper.IsOfBaseclass(itemTemplate.Id, BaseClasses.FOOD))
|
||||
if (itemHelper.IsOfBaseclass(itemTemplate.Id, BaseClasses.FOOD))
|
||||
{
|
||||
lock (_foodLock)
|
||||
{
|
||||
@@ -344,7 +340,7 @@ public class BotLootCacheService(
|
||||
|
||||
if (addDrinkItems)
|
||||
{
|
||||
if (_itemHelper.IsOfBaseclass(itemTemplate.Id, BaseClasses.DRINK))
|
||||
if (itemHelper.IsOfBaseclass(itemTemplate.Id, BaseClasses.DRINK))
|
||||
{
|
||||
lock (_drinkLock)
|
||||
{
|
||||
@@ -355,7 +351,7 @@ public class BotLootCacheService(
|
||||
|
||||
if (addCurrencyItems)
|
||||
{
|
||||
if (_itemHelper.IsOfBaseclass(itemTemplate.Id, BaseClasses.MONEY))
|
||||
if (itemHelper.IsOfBaseclass(itemTemplate.Id, BaseClasses.MONEY))
|
||||
{
|
||||
lock (_currencyLock)
|
||||
{
|
||||
@@ -423,7 +419,7 @@ public class BotLootCacheService(
|
||||
var filteredVestItems = new Dictionary<MongoId, double>();
|
||||
foreach (var itemKvP in vestLootPool)
|
||||
{
|
||||
var itemResult = _itemHelper.GetItem(itemKvP.Key);
|
||||
var itemResult = itemHelper.GetItem(itemKvP.Key);
|
||||
if (itemResult.Value is null)
|
||||
{
|
||||
continue;
|
||||
@@ -455,7 +451,7 @@ public class BotLootCacheService(
|
||||
|
||||
if (!_lootCache.TryGetValue(botRole, out var cacheForRole))
|
||||
{
|
||||
_logger.Error($"Unable to get loot cache value using key: {botRole}");
|
||||
logger.Error($"Unable to get loot cache value using key: {botRole}");
|
||||
|
||||
return;
|
||||
}
|
||||
@@ -488,7 +484,7 @@ public class BotLootCacheService(
|
||||
var filteredItems = new Dictionary<MongoId, double>();
|
||||
foreach (var (itemTpl, itemWeight) in lootPool)
|
||||
{
|
||||
var (isValidItem, itemTemplate) = _itemHelper.GetItem(itemTpl);
|
||||
var (isValidItem, itemTemplate) = itemHelper.GetItem(itemTpl);
|
||||
if (!isValidItem)
|
||||
{
|
||||
continue;
|
||||
@@ -579,17 +575,17 @@ public class BotLootCacheService(
|
||||
|
||||
protected bool IsFood(MongoId tpl)
|
||||
{
|
||||
return _itemHelper.IsOfBaseclass(tpl, BaseClasses.FOOD);
|
||||
return itemHelper.IsOfBaseclass(tpl, BaseClasses.FOOD);
|
||||
}
|
||||
|
||||
protected bool IsDrink(MongoId tpl)
|
||||
{
|
||||
return _itemHelper.IsOfBaseclass(tpl, BaseClasses.DRINK);
|
||||
return itemHelper.IsOfBaseclass(tpl, BaseClasses.DRINK);
|
||||
}
|
||||
|
||||
protected bool IsCurrency(MongoId tpl)
|
||||
{
|
||||
return _itemHelper.IsOfBaseclass(tpl, BaseClasses.MONEY);
|
||||
return itemHelper.IsOfBaseclass(tpl, BaseClasses.MONEY);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
||||
@@ -12,16 +12,16 @@ namespace SPTarkov.Server.Core.Services;
|
||||
|
||||
[Injectable(InjectionType.Singleton)]
|
||||
public class BotNameService(
|
||||
ISptLogger<BotNameService> _logger,
|
||||
BotHelper _botHelper,
|
||||
RandomUtil _randomUtil,
|
||||
ServerLocalisationService _serverLocalisationService,
|
||||
DatabaseService _databaseService,
|
||||
ConfigServer _configServer
|
||||
ISptLogger<BotNameService> logger,
|
||||
BotHelper botHelper,
|
||||
RandomUtil randomUtil,
|
||||
ServerLocalisationService serverLocalisationService,
|
||||
DatabaseService databaseService,
|
||||
ConfigServer configServer
|
||||
)
|
||||
{
|
||||
protected readonly Lock _lockObject = new();
|
||||
protected readonly BotConfig _botConfig = _configServer.GetConfig<BotConfig>();
|
||||
protected readonly BotConfig _botConfig = configServer.GetConfig<BotConfig>();
|
||||
protected readonly HashSet<string> _usedNameCache = new();
|
||||
|
||||
/// <summary>
|
||||
@@ -60,11 +60,11 @@ public class BotNameService(
|
||||
{
|
||||
// Get bot name with leading/trailing whitespace removed
|
||||
var name = isPmc.GetValueOrDefault(false) // Explicit handling of PMCs, all other bots will get "first_name last_name"
|
||||
? _botHelper.GetPmcNicknameOfMaxLength(
|
||||
? botHelper.GetPmcNicknameOfMaxLength(
|
||||
_botConfig.BotNameLengthLimit,
|
||||
botGenerationDetails.Side
|
||||
)
|
||||
: $"{_randomUtil.GetArrayValue(botJsonTemplate.FirstNames)} {(botJsonTemplate.LastNames.Count > 0 ? _randomUtil.GetArrayValue(botJsonTemplate.LastNames) : "")}";
|
||||
: $"{randomUtil.GetArrayValue(botJsonTemplate.FirstNames)} {(botJsonTemplate.LastNames.Count > 0 ? randomUtil.GetArrayValue(botJsonTemplate.LastNames) : "")}";
|
||||
|
||||
name = name.Trim();
|
||||
|
||||
@@ -80,7 +80,7 @@ public class BotNameService(
|
||||
&& botGenerationDetails.AllPmcsHaveSameNameAsPlayer.GetValueOrDefault(false)
|
||||
)
|
||||
{
|
||||
var prefix = _serverLocalisationService.GetRandomTextThatMatchesPartialKey(
|
||||
var prefix = serverLocalisationService.GetRandomTextThatMatchesPartialKey(
|
||||
"pmc-name_prefix_"
|
||||
);
|
||||
name = $"{prefix} {name}";
|
||||
@@ -97,10 +97,10 @@ public class BotNameService(
|
||||
{
|
||||
// 5 attempts to generate a name, pool probably isn't big enough
|
||||
var genericName =
|
||||
$"{botGenerationDetails.Side} {_randomUtil.GetInt(100000, 999999)}";
|
||||
if (_logger.IsLogEnabled(LogLevel.Debug))
|
||||
$"{botGenerationDetails.Side} {randomUtil.GetInt(100000, 999999)}";
|
||||
if (logger.IsLogEnabled(LogLevel.Debug))
|
||||
{
|
||||
_logger.Debug(
|
||||
logger.Debug(
|
||||
$"Failed to find unique name for: {botRole} {botGenerationDetails.Side} after 5 attempts, using: {genericName}"
|
||||
);
|
||||
}
|
||||
@@ -158,12 +158,12 @@ public class BotNameService(
|
||||
/// <returns>PMC name as string</returns>
|
||||
protected string GetRandomPmcName()
|
||||
{
|
||||
var bots = _databaseService.GetBots().Types;
|
||||
var bots = databaseService.GetBots().Types;
|
||||
|
||||
var pmcNames = new List<string>();
|
||||
pmcNames.AddRange(bots["usec"].FirstNames);
|
||||
pmcNames.AddRange(bots["bear"].FirstNames);
|
||||
|
||||
return _randomUtil.GetArrayValue(pmcNames);
|
||||
return randomUtil.GetArrayValue(pmcNames);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
using SPTarkov.DI.Annotations;
|
||||
using SPTarkov.Server.Core.Helpers;
|
||||
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.Spt.Bots;
|
||||
@@ -12,12 +13,12 @@ namespace SPTarkov.Server.Core.Services;
|
||||
|
||||
[Injectable(InjectionType.Singleton)]
|
||||
public class BotWeaponModLimitService(
|
||||
ISptLogger<BotWeaponModLimitService> _logger,
|
||||
ConfigServer _configServer,
|
||||
ItemHelper _itemHelper
|
||||
ISptLogger<BotWeaponModLimitService> logger,
|
||||
ConfigServer configServer,
|
||||
ItemHelper itemHelper
|
||||
)
|
||||
{
|
||||
protected readonly BotConfig _botConfig = _configServer.GetConfig<BotConfig>();
|
||||
protected readonly BotConfig _botConfig = configServer.GetConfig<BotConfig>();
|
||||
|
||||
/// <summary>
|
||||
/// Initalise mod limits to be used when generating a weapon
|
||||
@@ -79,7 +80,7 @@ public class BotWeaponModLimitService(
|
||||
// If weapon already has a longer ranged scope on it, allow ncstar to be spawned
|
||||
if (
|
||||
weapon.Any(item =>
|
||||
_itemHelper.IsOfBaseclasses(
|
||||
itemHelper.IsOfBaseclasses(
|
||||
item.Template,
|
||||
[
|
||||
BaseClasses.ASSAULT_SCOPE,
|
||||
@@ -97,8 +98,8 @@ public class BotWeaponModLimitService(
|
||||
}
|
||||
|
||||
// Mods parent is scope and mod is scope, allow it (adds those mini-sights to the tops of sights)
|
||||
var modIsScope = _itemHelper.IsOfBaseclasses(modTemplate.Id, modLimits.ScopeBaseTypes);
|
||||
if (_itemHelper.IsOfBaseclasses(modsParent.Id, modLimits.ScopeBaseTypes) && modIsScope)
|
||||
var modIsScope = itemHelper.IsOfBaseclasses(modTemplate.Id, modLimits.ScopeBaseTypes);
|
||||
if (itemHelper.IsOfBaseclasses(modsParent.Id, modLimits.ScopeBaseTypes) && modIsScope)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
@@ -122,8 +123,8 @@ public class BotWeaponModLimitService(
|
||||
if (
|
||||
modLimits.Scope.Count >= modLimits.ScopeMax
|
||||
&& modTemplate.Properties.Slots?.Count == 1
|
||||
&& _itemHelper.IsOfBaseclass(modTemplate.Id, BaseClasses.MOUNT)
|
||||
&& !_itemHelper.IsOfBaseclass(modsParent.Id, BaseClasses.MOUNT)
|
||||
&& itemHelper.IsOfBaseclass(modTemplate.Id, BaseClasses.MOUNT)
|
||||
&& !itemHelper.IsOfBaseclass(modsParent.Id, BaseClasses.MOUNT)
|
||||
&& modTemplate.Properties.Slots.Any(slot => slot.Name == "mod_scope")
|
||||
)
|
||||
{
|
||||
@@ -131,7 +132,7 @@ public class BotWeaponModLimitService(
|
||||
}
|
||||
|
||||
// If mod is a light/laser, return if limit reached
|
||||
var modIsLightOrLaser = _itemHelper.IsOfBaseclasses(
|
||||
var modIsLightOrLaser = itemHelper.IsOfBaseclasses(
|
||||
modTemplate.Id,
|
||||
modLimits.FlashlightLaserBaseTypes
|
||||
);
|
||||
@@ -149,7 +150,7 @@ public class BotWeaponModLimitService(
|
||||
if (
|
||||
modLimits.Scope.Count >= modLimits.ScopeMax
|
||||
&& modTemplate.Properties.Slots?.Count == 1
|
||||
&& _itemHelper.IsOfBaseclass(modTemplate.Id, BaseClasses.MOUNT)
|
||||
&& itemHelper.IsOfBaseclass(modTemplate.Id, BaseClasses.MOUNT)
|
||||
&& modTemplate.Properties.Slots.Any(slot => slot.Name == "mod_flashlight")
|
||||
)
|
||||
{
|
||||
@@ -168,7 +169,7 @@ public class BotWeaponModLimitService(
|
||||
/// <param name="botRole">role of bot we're checking weapon of</param>
|
||||
/// <returns>true if limit reached</returns>
|
||||
protected bool WeaponModLimitReached(
|
||||
string modTpl,
|
||||
MongoId modTpl,
|
||||
ItemCount currentCount,
|
||||
int? maxLimit,
|
||||
string botRole
|
||||
@@ -183,9 +184,9 @@ public class BotWeaponModLimitService(
|
||||
// Has mod limit for bot type been reached
|
||||
if (currentCount.Count >= maxLimit)
|
||||
{
|
||||
if (_logger.IsLogEnabled(LogLevel.Debug))
|
||||
if (logger.IsLogEnabled(LogLevel.Debug))
|
||||
{
|
||||
_logger.Debug(
|
||||
logger.Debug(
|
||||
$"[{botRole}] scope limit reached! tried to add {modTpl} but scope count is {currentCount.Count}"
|
||||
);
|
||||
}
|
||||
|
||||
@@ -14,19 +14,19 @@ namespace SPTarkov.Server.Core.Services;
|
||||
|
||||
[Injectable(InjectionType.Singleton)]
|
||||
public class BtrDeliveryService(
|
||||
ISptLogger<BtrDeliveryService> _logger,
|
||||
DatabaseService _databaseService,
|
||||
RandomUtil _randomUtil,
|
||||
TimeUtil _timeUtil,
|
||||
SaveServer _saveServer,
|
||||
MailSendService _mailSendService,
|
||||
ConfigServer _configServer,
|
||||
ServerLocalisationService _serverLocalisationService
|
||||
ISptLogger<BtrDeliveryService> logger,
|
||||
DatabaseService databaseService,
|
||||
RandomUtil randomUtil,
|
||||
TimeUtil timeUtil,
|
||||
SaveServer saveServer,
|
||||
MailSendService mailSendService,
|
||||
ConfigServer configServer,
|
||||
ServerLocalisationService serverLocalisationService
|
||||
)
|
||||
{
|
||||
protected readonly BtrDeliveryConfig _btrDeliveryConfig =
|
||||
_configServer.GetConfig<BtrDeliveryConfig>();
|
||||
protected readonly TraderConfig _traderConfig = _configServer.GetConfig<TraderConfig>();
|
||||
configServer.GetConfig<BtrDeliveryConfig>();
|
||||
protected readonly TraderConfig _traderConfig = configServer.GetConfig<TraderConfig>();
|
||||
|
||||
protected static readonly List<string> _transferTypes = new() { "btr", "transit" };
|
||||
|
||||
@@ -35,7 +35,7 @@ public class BtrDeliveryService(
|
||||
/// </summary>
|
||||
/// <param name="sessionId"> Session ID </param>
|
||||
/// <param name="request"> End raid request from client </param>
|
||||
public void HandleItemTransferEvent(string sessionId, EndLocalRaidRequestData request)
|
||||
public void HandleItemTransferEvent(MongoId sessionId, EndLocalRaidRequestData request)
|
||||
{
|
||||
foreach (var transferType in _transferTypes)
|
||||
{
|
||||
@@ -59,9 +59,9 @@ public class BtrDeliveryService(
|
||||
}
|
||||
}
|
||||
|
||||
protected void HandleTransferItemDelivery(string sessionId, List<Item> items)
|
||||
protected void HandleTransferItemDelivery(MongoId sessionId, List<Item> items)
|
||||
{
|
||||
var serverProfile = _saveServer.GetProfile(sessionId);
|
||||
var serverProfile = saveServer.GetProfile(sessionId);
|
||||
var pmcData = serverProfile.CharacterData.PmcData;
|
||||
|
||||
// Remove any items that were returned by the item delivery, but also insured, from the player's insurance list
|
||||
@@ -71,13 +71,13 @@ public class BtrDeliveryService(
|
||||
.InsuredItems.Where(insuredItem => !deliveredItemIds.Contains(insuredItem.ItemId.Value))
|
||||
.ToList();
|
||||
|
||||
if (_saveServer.GetProfile(sessionId).BtrDeliveryList == null)
|
||||
if (saveServer.GetProfile(sessionId).BtrDeliveryList == null)
|
||||
{
|
||||
_saveServer.GetProfile(sessionId).BtrDeliveryList = new List<BtrDelivery>();
|
||||
saveServer.GetProfile(sessionId).BtrDeliveryList = new List<BtrDelivery>();
|
||||
}
|
||||
|
||||
// Store delivery to send to player later in profile
|
||||
_saveServer
|
||||
saveServer
|
||||
.GetProfile(sessionId)
|
||||
.BtrDeliveryList.Add(
|
||||
new BtrDelivery
|
||||
@@ -89,13 +89,13 @@ public class BtrDeliveryService(
|
||||
);
|
||||
}
|
||||
|
||||
public void SendBTRDelivery(string sessionId, List<Item> items)
|
||||
public void SendBTRDelivery(MongoId sessionId, List<Item> items)
|
||||
{
|
||||
var dialogueTemplates = _databaseService.GetTrader(Traders.BTR).Dialogue;
|
||||
var dialogueTemplates = databaseService.GetTrader(Traders.BTR).Dialogue;
|
||||
if (dialogueTemplates is null)
|
||||
{
|
||||
_logger.Error(
|
||||
_serverLocalisationService.GetText(
|
||||
logger.Error(
|
||||
serverLocalisationService.GetText(
|
||||
"inraid-unable_to_deliver_item_no_trader_found",
|
||||
Traders.BTR
|
||||
)
|
||||
@@ -105,8 +105,8 @@ public class BtrDeliveryService(
|
||||
|
||||
if (!dialogueTemplates.TryGetValue("itemsDelivered", out var itemsDelivered))
|
||||
{
|
||||
_logger.Error(
|
||||
_serverLocalisationService.GetText(
|
||||
logger.Error(
|
||||
serverLocalisationService.GetText(
|
||||
"btr-unable_to_find_items_in_dialog_template",
|
||||
sessionId
|
||||
)
|
||||
@@ -115,13 +115,13 @@ public class BtrDeliveryService(
|
||||
return;
|
||||
}
|
||||
|
||||
var messageId = _randomUtil.GetArrayValue(itemsDelivered);
|
||||
var messageStoreTime = _timeUtil.GetHoursAsSeconds(
|
||||
var messageId = randomUtil.GetArrayValue(itemsDelivered);
|
||||
var messageStoreTime = timeUtil.GetHoursAsSeconds(
|
||||
_traderConfig.Fence.BtrDeliveryExpireHours
|
||||
);
|
||||
|
||||
// Send the items to the player
|
||||
_mailSendService.SendLocalisedNpcMessageToPlayer(
|
||||
mailSendService.SendLocalisedNpcMessageToPlayer(
|
||||
sessionId,
|
||||
Traders.BTR,
|
||||
MessageType.BtrItemsDelivery,
|
||||
@@ -136,16 +136,16 @@ public class BtrDeliveryService(
|
||||
/// </summary>
|
||||
/// <param name="sessionId">The session ID of the profile to remove the package from.</param>
|
||||
/// <param name="delivery">The BTR delivery package to remove.</param>
|
||||
public void RemoveBTRDeliveryPackageFromProfile(string sessionId, BtrDelivery delivery)
|
||||
public void RemoveBTRDeliveryPackageFromProfile(MongoId sessionId, BtrDelivery delivery)
|
||||
{
|
||||
var profile = _saveServer.GetProfile(sessionId);
|
||||
var profile = saveServer.GetProfile(sessionId);
|
||||
profile.BtrDeliveryList = profile
|
||||
.BtrDeliveryList.Where(package => package.Id != delivery.Id)
|
||||
.ToList();
|
||||
|
||||
if (_logger.IsLogEnabled(LogLevel.Debug))
|
||||
if (logger.IsLogEnabled(LogLevel.Debug))
|
||||
{
|
||||
_logger.Debug(
|
||||
logger.Debug(
|
||||
$"Removed processed BTR delivery package. Remaining packages: {profile.BtrDeliveryList.Count}"
|
||||
);
|
||||
}
|
||||
@@ -160,16 +160,16 @@ public class BtrDeliveryService(
|
||||
// If override in config is non-zero, use that
|
||||
if (_btrDeliveryConfig.ReturnTimeOverrideSeconds > 0)
|
||||
{
|
||||
if (_logger.IsLogEnabled(LogLevel.Debug))
|
||||
if (logger.IsLogEnabled(LogLevel.Debug))
|
||||
{
|
||||
_logger.Debug(
|
||||
logger.Debug(
|
||||
$"BTR delivery override used: returning in {_btrDeliveryConfig.ReturnTimeOverrideSeconds} seconds"
|
||||
);
|
||||
}
|
||||
|
||||
return _timeUtil.GetTimeStamp() + _btrDeliveryConfig.ReturnTimeOverrideSeconds;
|
||||
return timeUtil.GetTimeStamp() + _btrDeliveryConfig.ReturnTimeOverrideSeconds;
|
||||
}
|
||||
|
||||
return _timeUtil.GetTimeStamp();
|
||||
return timeUtil.GetTimeStamp();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -5,28 +5,16 @@ using SPTarkov.Server.Core.Utils;
|
||||
namespace SPTarkov.Server.Core.Services;
|
||||
|
||||
[Injectable(InjectionType.Singleton)]
|
||||
public class BundleHashCacheService
|
||||
public class BundleHashCacheService(
|
||||
ISptLogger<BundleHashCacheService> logger,
|
||||
JsonUtil jsonUtil,
|
||||
HashUtil hashUtil,
|
||||
FileUtil fileUtil
|
||||
)
|
||||
{
|
||||
protected const string _bundleHashCachePath = "./user/cache/";
|
||||
protected const string _cacheName = "bundleHashCache.json";
|
||||
protected readonly Dictionary<string, uint> _bundleHashes = new();
|
||||
private readonly FileUtil _fileUtil;
|
||||
private readonly HashUtil _hashUtil;
|
||||
private readonly JsonUtil _jsonUtil;
|
||||
private readonly ISptLogger<BundleHashCacheService> _logger;
|
||||
|
||||
public BundleHashCacheService(
|
||||
ISptLogger<BundleHashCacheService> logger,
|
||||
JsonUtil jsonUtil,
|
||||
HashUtil hashUtil,
|
||||
FileUtil fileUtil
|
||||
)
|
||||
{
|
||||
_logger = logger;
|
||||
_jsonUtil = jsonUtil;
|
||||
_hashUtil = hashUtil;
|
||||
_fileUtil = fileUtil;
|
||||
}
|
||||
|
||||
public uint GetStoredValue(string key)
|
||||
{
|
||||
@@ -47,12 +35,12 @@ public class BundleHashCacheService
|
||||
Directory.CreateDirectory(_bundleHashCachePath);
|
||||
}
|
||||
|
||||
_fileUtil.WriteFile(
|
||||
fileUtil.WriteFile(
|
||||
Path.Join(_bundleHashCachePath, _cacheName),
|
||||
_jsonUtil.Serialize(_bundleHashes)
|
||||
jsonUtil.Serialize(_bundleHashes)
|
||||
);
|
||||
|
||||
_logger.Debug($"Bundle: {bundlePath} hash stored in: ${_bundleHashCachePath}");
|
||||
logger.Debug($"Bundle: {bundlePath} hash stored in: ${_bundleHashCachePath}");
|
||||
}
|
||||
|
||||
public bool CalculateAndMatchHash(string BundlePath)
|
||||
@@ -67,8 +55,8 @@ public class BundleHashCacheService
|
||||
|
||||
public uint CalculateHash(string BundlePath)
|
||||
{
|
||||
var fileData = _fileUtil.ReadFile(BundlePath);
|
||||
return _hashUtil.GenerateCrc32ForData(fileData);
|
||||
var fileData = fileUtil.ReadFile(BundlePath);
|
||||
return hashUtil.GenerateCrc32ForData(fileData);
|
||||
}
|
||||
|
||||
public bool MatchWithStoredHash(string BundlePath, uint hash)
|
||||
|
||||
@@ -24,27 +24,27 @@ namespace SPTarkov.Server.Core.Services;
|
||||
|
||||
[Injectable(InjectionType.Singleton)]
|
||||
public class CircleOfCultistService(
|
||||
ISptLogger<CircleOfCultistService> _logger,
|
||||
TimeUtil _timeUtil,
|
||||
ICloner _cloner,
|
||||
EventOutputHolder _eventOutputHolder,
|
||||
RandomUtil _randomUtil,
|
||||
HashUtil _hashUtil,
|
||||
ItemHelper _itemHelper,
|
||||
PresetHelper _presetHelper,
|
||||
ProfileHelper _profileHelper,
|
||||
InventoryHelper _inventoryHelper,
|
||||
HideoutHelper _hideoutHelper,
|
||||
QuestHelper _questHelper,
|
||||
DatabaseService _databaseService,
|
||||
ItemFilterService _itemFilterService,
|
||||
SeasonalEventService _seasonalEventService,
|
||||
ISptLogger<CircleOfCultistService> logger,
|
||||
TimeUtil timeUtil,
|
||||
ICloner cloner,
|
||||
EventOutputHolder eventOutputHolder,
|
||||
RandomUtil randomUtil,
|
||||
HashUtil hashUtil,
|
||||
ItemHelper itemHelper,
|
||||
PresetHelper presetHelper,
|
||||
ProfileHelper profileHelper,
|
||||
InventoryHelper inventoryHelper,
|
||||
HideoutHelper hideoutHelper,
|
||||
QuestHelper questHelper,
|
||||
DatabaseService databaseService,
|
||||
ItemFilterService itemFilterService,
|
||||
SeasonalEventService seasonalEventService,
|
||||
ServerLocalisationService localisationService,
|
||||
ConfigServer _configServer
|
||||
ConfigServer configServer
|
||||
)
|
||||
{
|
||||
protected const string CircleOfCultistSlotId = "CircleOfCultistsGrid1";
|
||||
protected readonly HideoutConfig _hideoutConfig = _configServer.GetConfig<HideoutConfig>();
|
||||
protected readonly HideoutConfig _hideoutConfig = configServer.GetConfig<HideoutConfig>();
|
||||
|
||||
/// <summary>
|
||||
/// Start a sacrifice event
|
||||
@@ -56,31 +56,31 @@ public class CircleOfCultistService(
|
||||
/// <param name="request">Client request</param>
|
||||
/// <returns>ItemEventRouterResponse</returns>
|
||||
public ItemEventRouterResponse StartSacrifice(
|
||||
string sessionId,
|
||||
MongoId sessionId,
|
||||
PmcData pmcData,
|
||||
HideoutCircleOfCultistProductionStartRequestData request
|
||||
)
|
||||
{
|
||||
var output = _eventOutputHolder.GetOutput(sessionId);
|
||||
var output = eventOutputHolder.GetOutput(sessionId);
|
||||
|
||||
var cultistCircleStashId = pmcData.Inventory?.HideoutAreaStashes?.GetValueOrDefault(
|
||||
((int)HideoutAreas.CircleOfCultists).ToString()
|
||||
);
|
||||
if (cultistCircleStashId is null)
|
||||
{
|
||||
_logger.Error(localisationService.GetText("cultistcircle-unable_to_find_stash_id"));
|
||||
logger.Error(localisationService.GetText("cultistcircle-unable_to_find_stash_id"));
|
||||
|
||||
return output;
|
||||
}
|
||||
|
||||
// `cultistRecipes` just has single recipeId
|
||||
var cultistCraftData = _databaseService
|
||||
var cultistCraftData = databaseService
|
||||
.GetHideout()
|
||||
.Production.CultistRecipes.FirstOrDefault();
|
||||
var sacrificedItems = GetSacrificedItems(pmcData);
|
||||
var sacrificedItemCostRoubles = sacrificedItems.Aggregate(
|
||||
0D,
|
||||
(sum, curr) => sum + (_itemHelper.GetItemPrice(curr.Template) ?? 0)
|
||||
(sum, curr) => sum + (itemHelper.GetItemPrice(curr.Template) ?? 0)
|
||||
);
|
||||
|
||||
var rewardAmountMultiplier = GetRewardAmountMultiplier(
|
||||
@@ -123,7 +123,7 @@ public class CircleOfCultistService(
|
||||
{
|
||||
if (item.SlotId == CircleOfCultistSlotId)
|
||||
{
|
||||
_inventoryHelper.RemoveItem(pmcData, item.Id, sessionId, output);
|
||||
inventoryHelper.RemoveItem(pmcData, item.Id, sessionId, output);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -142,12 +142,12 @@ public class CircleOfCultistService(
|
||||
);
|
||||
|
||||
// Get the container grid for cultist stash area
|
||||
var cultistStashDbItem = _itemHelper.GetItem(
|
||||
var cultistStashDbItem = itemHelper.GetItem(
|
||||
ItemTpl.HIDEOUTAREACONTAINER_CIRCLEOFCULTISTS_STASH_1
|
||||
);
|
||||
|
||||
// Ensure rewards fit into container
|
||||
var containerGrid = _inventoryHelper.GetContainerSlotMap(cultistStashDbItem.Value.Id);
|
||||
var containerGrid = inventoryHelper.GetContainerSlotMap(cultistStashDbItem.Value.Id);
|
||||
AddRewardsToCircleContainer(
|
||||
sessionId,
|
||||
pmcData,
|
||||
@@ -172,7 +172,7 @@ public class CircleOfCultistService(
|
||||
)
|
||||
{
|
||||
// Get a randomised value to multiply the sacrificed rouble cost by
|
||||
var rewardAmountMultiplier = _randomUtil.GetDouble(
|
||||
var rewardAmountMultiplier = randomUtil.GetDouble(
|
||||
cultistCircleSettings.RewardPriceMultiplierMinMax.Min,
|
||||
cultistCircleSettings.RewardPriceMultiplierMinMax.Max
|
||||
);
|
||||
@@ -196,7 +196,7 @@ public class CircleOfCultistService(
|
||||
/// <param name="sacrificedItems">Items player sacrificed</param>
|
||||
/// <param name="craftingTime">How long the ritual should take</param>
|
||||
protected void RegisterCircleOfCultistProduction(
|
||||
string sessionId,
|
||||
MongoId sessionId,
|
||||
PmcData pmcData,
|
||||
string recipeId,
|
||||
List<Item> sacrificedItems,
|
||||
@@ -204,7 +204,7 @@ public class CircleOfCultistService(
|
||||
)
|
||||
{
|
||||
// Create circle production/craft object to add to player profile
|
||||
var cultistProduction = _hideoutHelper.InitProduction(recipeId, craftingTime, false);
|
||||
var cultistProduction = hideoutHelper.InitProduction(recipeId, craftingTime, false);
|
||||
|
||||
// Flag as cultist circle for code to pick up later
|
||||
cultistProduction.SptIsCultistCircle = true;
|
||||
@@ -292,7 +292,7 @@ public class CircleOfCultistService(
|
||||
if (matchingThreshold is null)
|
||||
{
|
||||
// None found, use a default
|
||||
_logger.Warning(
|
||||
logger.Warning(
|
||||
localisationService.GetText(
|
||||
"cultistcircle-no_matching_threshhold_found",
|
||||
new { rewardAmountRoubles = rewardAmountRoubles }
|
||||
@@ -304,7 +304,7 @@ public class CircleOfCultistService(
|
||||
var craftTime =
|
||||
firstThreshold?.CraftTimeSeconds > 0
|
||||
? firstThreshold.CraftTimeSeconds
|
||||
: _timeUtil.GetHoursAsSeconds(12);
|
||||
: timeUtil.GetHoursAsSeconds(12);
|
||||
|
||||
return new CraftTimeThreshold
|
||||
{
|
||||
@@ -371,26 +371,24 @@ public class CircleOfCultistService(
|
||||
{
|
||||
if (failedAttempts > circleConfig.MaxAttemptsToPickRewardsWithinBudget)
|
||||
{
|
||||
_logger.Warning(
|
||||
$"Exiting reward generation after {failedAttempts} failed attempts"
|
||||
);
|
||||
logger.Warning($"Exiting reward generation after {failedAttempts} failed attempts");
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
// Choose a random tpl from pool
|
||||
var randomItemTplFromPool = _randomUtil.GetArrayValue(rewardItemTplPool);
|
||||
var randomItemTplFromPool = randomUtil.GetArrayValue(rewardItemTplPool);
|
||||
|
||||
// Is weapon/armor, handle differently
|
||||
if (
|
||||
_itemHelper.ArmorItemHasRemovableOrSoftInsertSlots(randomItemTplFromPool)
|
||||
|| _itemHelper.IsOfBaseclass(randomItemTplFromPool, BaseClasses.WEAPON)
|
||||
itemHelper.ArmorItemHasRemovableOrSoftInsertSlots(randomItemTplFromPool)
|
||||
|| itemHelper.IsOfBaseclass(randomItemTplFromPool, BaseClasses.WEAPON)
|
||||
)
|
||||
{
|
||||
var defaultPreset = _presetHelper.GetDefaultPreset(randomItemTplFromPool);
|
||||
var defaultPreset = presetHelper.GetDefaultPreset(randomItemTplFromPool);
|
||||
if (defaultPreset is null)
|
||||
{
|
||||
_logger.Warning(
|
||||
logger.Warning(
|
||||
$"Reward tpl: {randomItemTplFromPool} lacks a default preset, skipping reward"
|
||||
);
|
||||
failedAttempts++;
|
||||
@@ -403,10 +401,10 @@ public class CircleOfCultistService(
|
||||
presetAndMods.RemapRootItemId();
|
||||
|
||||
// Set item as FiR
|
||||
_itemHelper.SetFoundInRaid(presetAndMods);
|
||||
itemHelper.SetFoundInRaid(presetAndMods);
|
||||
|
||||
rewardItemCount++;
|
||||
totalRewardCost += (int)_itemHelper.GetItemPrice(randomItemTplFromPool);
|
||||
totalRewardCost += (int)itemHelper.GetItemPrice(randomItemTplFromPool);
|
||||
rewards.Add(presetAndMods);
|
||||
|
||||
continue;
|
||||
@@ -431,18 +429,18 @@ public class CircleOfCultistService(
|
||||
},
|
||||
];
|
||||
|
||||
_itemHelper.SetFoundInRaid(rewardItem);
|
||||
itemHelper.SetFoundInRaid(rewardItem);
|
||||
|
||||
// Edge case - item is ammo container and needs cartridges added
|
||||
if (_itemHelper.IsOfBaseclass(randomItemTplFromPool, BaseClasses.AMMO_BOX))
|
||||
if (itemHelper.IsOfBaseclass(randomItemTplFromPool, BaseClasses.AMMO_BOX))
|
||||
{
|
||||
var itemDetails = _itemHelper.GetItem(randomItemTplFromPool).Value;
|
||||
_itemHelper.AddCartridgesToAmmoBox(rewardItem, itemDetails);
|
||||
var itemDetails = itemHelper.GetItem(randomItemTplFromPool).Value;
|
||||
itemHelper.AddCartridgesToAmmoBox(rewardItem, itemDetails);
|
||||
}
|
||||
|
||||
// Increment price of rewards to give to player + add to reward array
|
||||
rewardItemCount++;
|
||||
var singleItemPrice = _itemHelper.GetItemPrice(randomItemTplFromPool);
|
||||
var singleItemPrice = itemHelper.GetItemPrice(randomItemTplFromPool);
|
||||
var itemPrice = singleItemPrice * stackSize;
|
||||
totalRewardCost += (int)itemPrice;
|
||||
|
||||
@@ -460,7 +458,7 @@ public class CircleOfCultistService(
|
||||
/// <param name="cultistCircleStashId">Id of stash item</param>
|
||||
/// <returns>The reward object</returns>
|
||||
protected List<List<Item>> GetDirectRewards(
|
||||
string sessionId,
|
||||
MongoId sessionId,
|
||||
DirectRewardSettings directReward,
|
||||
string cultistCircleStashId
|
||||
)
|
||||
@@ -471,7 +469,7 @@ public class CircleOfCultistService(
|
||||
// Handle special case of tagilla helmets - only one reward is allowed
|
||||
if (directReward.Reward.Contains(ItemTpl.FACECOVER_TAGILLAS_WELDING_MASK_GORILLA))
|
||||
{
|
||||
directReward.Reward = [_randomUtil.GetArrayValue(directReward.Reward)];
|
||||
directReward.Reward = [randomUtil.GetArrayValue(directReward.Reward)];
|
||||
}
|
||||
|
||||
// Loop because these can include multiple rewards
|
||||
@@ -479,14 +477,14 @@ public class CircleOfCultistService(
|
||||
{
|
||||
// Is weapon/armor, handle differently
|
||||
if (
|
||||
_itemHelper.ArmorItemHasRemovableOrSoftInsertSlots(rewardTpl)
|
||||
|| _itemHelper.IsOfBaseclass(rewardTpl, BaseClasses.WEAPON)
|
||||
itemHelper.ArmorItemHasRemovableOrSoftInsertSlots(rewardTpl)
|
||||
|| itemHelper.IsOfBaseclass(rewardTpl, BaseClasses.WEAPON)
|
||||
)
|
||||
{
|
||||
var defaultPreset = _presetHelper.GetDefaultPreset(rewardTpl);
|
||||
var defaultPreset = presetHelper.GetDefaultPreset(rewardTpl);
|
||||
if (defaultPreset is null)
|
||||
{
|
||||
_logger.Warning(
|
||||
logger.Warning(
|
||||
$"Reward tpl: {rewardTpl} lacks a default preset, skipping reward"
|
||||
);
|
||||
|
||||
@@ -498,7 +496,7 @@ public class CircleOfCultistService(
|
||||
presetAndMods.RemapRootItemId();
|
||||
|
||||
// Set item as FiR
|
||||
_itemHelper.SetFoundInRaid(presetAndMods);
|
||||
itemHelper.SetFoundInRaid(presetAndMods);
|
||||
|
||||
rewards.Add(presetAndMods);
|
||||
|
||||
@@ -519,13 +517,13 @@ public class CircleOfCultistService(
|
||||
},
|
||||
];
|
||||
|
||||
_itemHelper.SetFoundInRaid(rewardItem);
|
||||
itemHelper.SetFoundInRaid(rewardItem);
|
||||
|
||||
// Edge case - item is ammo container and needs cartridges added
|
||||
if (_itemHelper.IsOfBaseclass(rewardTpl, BaseClasses.AMMO_BOX))
|
||||
if (itemHelper.IsOfBaseclass(rewardTpl, BaseClasses.AMMO_BOX))
|
||||
{
|
||||
var itemDetails = _itemHelper.GetItem(rewardTpl).Value;
|
||||
_itemHelper.AddCartridgesToAmmoBox(rewardItem, itemDetails);
|
||||
var itemDetails = itemHelper.GetItem(rewardTpl).Value;
|
||||
itemHelper.AddCartridgesToAmmoBox(rewardItem, itemDetails);
|
||||
}
|
||||
|
||||
rewards.Add(rewardItem);
|
||||
@@ -547,7 +545,7 @@ public class CircleOfCultistService(
|
||||
/// <param name="sacrificedItems">Items sacrificed</param>
|
||||
/// <returns>Direct reward items to send to player</returns>
|
||||
protected DirectRewardSettings? CheckForDirectReward(
|
||||
string sessionId,
|
||||
MongoId sessionId,
|
||||
List<Item> sacrificedItems,
|
||||
Dictionary<string, DirectRewardSettings> directRewardsCache
|
||||
)
|
||||
@@ -566,7 +564,7 @@ public class CircleOfCultistService(
|
||||
return null;
|
||||
}
|
||||
|
||||
var fullProfile = _profileHelper.GetFullProfile(sessionId);
|
||||
var fullProfile = profileHelper.GetFullProfile(sessionId);
|
||||
var directRewardHash = GetDirectRewardHashKey(matchingDirectReward);
|
||||
if (fullProfile.SptData.CultistRewards?.ContainsKey(directRewardHash) ?? false)
|
||||
// Player has already received this direct reward
|
||||
@@ -592,7 +590,7 @@ public class CircleOfCultistService(
|
||||
// Key is sacrificed items separated by commas, a dash, then the rewards separated by commas
|
||||
var key = $"{{{required}-{reward}}}";
|
||||
|
||||
return _hashUtil.GenerateHashForData(HashingAlgorithm.MD5, key);
|
||||
return hashUtil.GenerateHashForData(HashingAlgorithm.MD5, key);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -602,10 +600,10 @@ public class CircleOfCultistService(
|
||||
/// <returns>stack size of item</returns>
|
||||
protected int GetDirectRewardBaseTypeStackSize(string rewardTpl)
|
||||
{
|
||||
var itemDetails = _itemHelper.GetItem(rewardTpl);
|
||||
var itemDetails = itemHelper.GetItem(rewardTpl);
|
||||
if (!itemDetails.Key)
|
||||
{
|
||||
_logger.Warning($"{rewardTpl} is not an item, setting stack size to 1");
|
||||
logger.Warning($"{rewardTpl} is not an item, setting stack size to 1");
|
||||
|
||||
return 1;
|
||||
}
|
||||
@@ -619,7 +617,7 @@ public class CircleOfCultistService(
|
||||
return 1;
|
||||
}
|
||||
|
||||
return _randomUtil.GetInt(settings.Min, settings.Max);
|
||||
return randomUtil.GetInt(settings.Min, settings.Max);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -628,14 +626,14 @@ public class CircleOfCultistService(
|
||||
/// <param name="sessionId">Session id</param>
|
||||
/// <param name="directReward">Reward sent to player</param>
|
||||
protected void FlagDirectRewardAsAcceptedInProfile(
|
||||
string sessionId,
|
||||
MongoId sessionId,
|
||||
DirectRewardSettings directReward
|
||||
)
|
||||
{
|
||||
var fullProfile = _profileHelper.GetFullProfile(sessionId);
|
||||
var fullProfile = profileHelper.GetFullProfile(sessionId);
|
||||
var dataToStoreInProfile = new AcceptedCultistReward
|
||||
{
|
||||
Timestamp = _timeUtil.GetTimeStamp(),
|
||||
Timestamp = timeUtil.GetTimeStamp(),
|
||||
SacrificeItems = directReward.RequiredItems,
|
||||
RewardItems = directReward.Reward,
|
||||
};
|
||||
@@ -653,28 +651,28 @@ public class CircleOfCultistService(
|
||||
/// <returns>Size of stack</returns>
|
||||
protected int GetRewardStackSize(MongoId itemTpl, int rewardPoolRemaining)
|
||||
{
|
||||
if (_itemHelper.IsOfBaseclass(itemTpl, BaseClasses.AMMO))
|
||||
if (itemHelper.IsOfBaseclass(itemTpl, BaseClasses.AMMO))
|
||||
{
|
||||
var ammoTemplate = _itemHelper.GetItem(itemTpl).Value;
|
||||
return _itemHelper.GetRandomisedAmmoStackSize(ammoTemplate);
|
||||
var ammoTemplate = itemHelper.GetItem(itemTpl).Value;
|
||||
return itemHelper.GetRandomisedAmmoStackSize(ammoTemplate);
|
||||
}
|
||||
|
||||
if (_itemHelper.IsOfBaseclass(itemTpl, BaseClasses.MONEY))
|
||||
if (itemHelper.IsOfBaseclass(itemTpl, BaseClasses.MONEY))
|
||||
{
|
||||
// Get currency-specific values from config
|
||||
var settings = _hideoutConfig.CultistCircle.CurrencyRewards[itemTpl];
|
||||
|
||||
// What % of the pool remaining should be rewarded as chosen currency
|
||||
var percentOfPoolToUse = _randomUtil.GetDouble(settings.Min, settings.Max);
|
||||
var percentOfPoolToUse = randomUtil.GetDouble(settings.Min, settings.Max);
|
||||
|
||||
// Rouble amount of pool we want to reward as currency
|
||||
var roubleAmountToFill = _randomUtil.GetPercentOfValue(
|
||||
var roubleAmountToFill = randomUtil.GetPercentOfValue(
|
||||
percentOfPoolToUse,
|
||||
rewardPoolRemaining
|
||||
);
|
||||
|
||||
// Convert currency to roubles
|
||||
var currencyPriceAsRouble = _itemHelper.GetItemPrice(itemTpl);
|
||||
var currencyPriceAsRouble = itemHelper.GetItemPrice(itemTpl);
|
||||
|
||||
// How many items can we fit into chosen pool
|
||||
var itemCountToReward = Math.Round(roubleAmountToFill / currencyPriceAsRouble ?? 0);
|
||||
@@ -694,27 +692,27 @@ public class CircleOfCultistService(
|
||||
/// <param name="cultistCircleConfig">Circle config</param>
|
||||
/// <returns>Array of tpls</returns>
|
||||
protected List<string> GetCultistCircleRewardPool(
|
||||
string sessionId,
|
||||
MongoId sessionId,
|
||||
PmcData pmcData,
|
||||
CircleCraftDetails craftingInfo,
|
||||
CultistCircleSettings cultistCircleConfig
|
||||
)
|
||||
{
|
||||
var rewardPool = new HashSet<string>();
|
||||
var hideoutDbData = _databaseService.GetHideout();
|
||||
var itemsDb = _databaseService.GetItems();
|
||||
var hideoutDbData = databaseService.GetHideout();
|
||||
var itemsDb = databaseService.GetItems();
|
||||
|
||||
// Get all items that match the blacklisted types and fold into item blacklist below
|
||||
var itemTypeBlacklist = _itemFilterService.GetItemRewardBaseTypeBlacklist();
|
||||
var itemTypeBlacklist = itemFilterService.GetItemRewardBaseTypeBlacklist();
|
||||
var itemsMatchingTypeBlacklist = itemsDb
|
||||
.Where(templateItem => _itemHelper.IsOfBaseclasses(templateItem.Key, itemTypeBlacklist))
|
||||
.Where(templateItem => itemHelper.IsOfBaseclasses(templateItem.Key, itemTypeBlacklist))
|
||||
.Select(templateItem => templateItem.Key);
|
||||
|
||||
// Create set of unique values to ignore
|
||||
var itemRewardBlacklist = new HashSet<MongoId>();
|
||||
itemRewardBlacklist.UnionWith(_seasonalEventService.GetInactiveSeasonalEventItems());
|
||||
itemRewardBlacklist.UnionWith(_itemFilterService.GetItemRewardBlacklist());
|
||||
itemRewardBlacklist.UnionWith(_itemFilterService.GetBlacklistedItems());
|
||||
itemRewardBlacklist.UnionWith(seasonalEventService.GetInactiveSeasonalEventItems());
|
||||
itemRewardBlacklist.UnionWith(itemFilterService.GetItemRewardBlacklist());
|
||||
itemRewardBlacklist.UnionWith(itemFilterService.GetBlacklistedItems());
|
||||
itemRewardBlacklist.UnionWith(cultistCircleConfig.RewardItemBlacklist);
|
||||
itemRewardBlacklist.UnionWith(itemsMatchingTypeBlacklist);
|
||||
|
||||
@@ -792,23 +790,21 @@ public class CircleOfCultistService(
|
||||
var activeTasks = pmcData.Quests.Where(quest => quest.Status == QuestStatusEnum.Started);
|
||||
foreach (var task in activeTasks)
|
||||
{
|
||||
var questData = _questHelper.GetQuestFromDb(task.QId, pmcData);
|
||||
var questData = questHelper.GetQuestFromDb(task.QId, pmcData);
|
||||
var handoverConditions = questData.Conditions.AvailableForFinish.Where(condition =>
|
||||
condition.ConditionType == "HandoverItem"
|
||||
);
|
||||
foreach (var condition in handoverConditions)
|
||||
foreach (var neededItem in condition.Target.List)
|
||||
{
|
||||
if (
|
||||
itemRewardBlacklist.Contains(neededItem) || !_itemHelper.IsValidItem(neededItem)
|
||||
)
|
||||
if (itemRewardBlacklist.Contains(neededItem) || !itemHelper.IsValidItem(neededItem))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
if (_logger.IsLogEnabled(LogLevel.Debug))
|
||||
if (logger.IsLogEnabled(LogLevel.Debug))
|
||||
{
|
||||
_logger.Debug($"Added Task Loot: {_itemHelper.GetItemName(neededItem)}");
|
||||
logger.Debug($"Added Task Loot: {itemHelper.GetItemName(neededItem)}");
|
||||
}
|
||||
|
||||
rewardPool.Add(neededItem);
|
||||
@@ -847,17 +843,17 @@ public class CircleOfCultistService(
|
||||
{
|
||||
if (
|
||||
itemRewardBlacklist.Contains(rewardToAdd.TemplateId)
|
||||
|| !_itemHelper.IsValidItem(rewardToAdd.TemplateId)
|
||||
|| !itemHelper.IsValidItem(rewardToAdd.TemplateId)
|
||||
)
|
||||
// Dont reward items sacrificed
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
if (_logger.IsLogEnabled(LogLevel.Debug))
|
||||
if (logger.IsLogEnabled(LogLevel.Debug))
|
||||
{
|
||||
_logger.Debug(
|
||||
$"Added Hideout Loot: {_itemHelper.GetItemName(rewardToAdd.TemplateId)}"
|
||||
logger.Debug(
|
||||
$"Added Hideout Loot: {itemHelper.GetItemName(rewardToAdd.TemplateId)}"
|
||||
);
|
||||
}
|
||||
|
||||
@@ -879,7 +875,7 @@ public class CircleOfCultistService(
|
||||
{
|
||||
if (
|
||||
area.Type == HideoutAreas.ChristmasIllumination
|
||||
&& !_seasonalEventService.ChristmasEventEnabled()
|
||||
&& !seasonalEventService.ChristmasEventEnabled()
|
||||
)
|
||||
// Christmas tree area and not Christmas, skip
|
||||
{
|
||||
@@ -904,7 +900,7 @@ public class CircleOfCultistService(
|
||||
bool itemsShouldBeHighValue
|
||||
)
|
||||
{
|
||||
var allItems = _itemHelper.GetItems();
|
||||
var allItems = itemHelper.GetItems();
|
||||
var currentItemCount = 0;
|
||||
var attempts = 0;
|
||||
// `currentItemCount` var will look for the correct number of items, `attempts` var will keep this from never stopping if the highValueThreshold is too high
|
||||
@@ -914,10 +910,10 @@ public class CircleOfCultistService(
|
||||
)
|
||||
{
|
||||
attempts++;
|
||||
var randomItem = _randomUtil.GetArrayValue(allItems);
|
||||
var randomItem = randomUtil.GetArrayValue(allItems);
|
||||
if (
|
||||
itemRewardBlacklist.Contains(randomItem.Id)
|
||||
|| !_itemHelper.IsValidItem(randomItem.Id)
|
||||
|| !itemHelper.IsValidItem(randomItem.Id)
|
||||
)
|
||||
{
|
||||
continue;
|
||||
@@ -926,16 +922,16 @@ public class CircleOfCultistService(
|
||||
// Valuable check
|
||||
if (itemsShouldBeHighValue)
|
||||
{
|
||||
var itemValue = _itemHelper.GetItemMaxPrice(randomItem.Id);
|
||||
var itemValue = itemHelper.GetItemMaxPrice(randomItem.Id);
|
||||
if (itemValue < _hideoutConfig.CultistCircle.HighValueThresholdRub)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
if (_logger.IsLogEnabled(LogLevel.Debug))
|
||||
if (logger.IsLogEnabled(LogLevel.Debug))
|
||||
{
|
||||
_logger.Debug($"Added: {_itemHelper.GetItemName(randomItem.Id)}");
|
||||
logger.Debug($"Added: {itemHelper.GetItemName(randomItem.Id)}");
|
||||
}
|
||||
|
||||
rewardPool.Add(randomItem.Id);
|
||||
@@ -973,13 +969,13 @@ public class CircleOfCultistService(
|
||||
protected string CreateSacrificeCacheKey(IEnumerable<string> requiredItems)
|
||||
{
|
||||
var concat = string.Join(",", requiredItems.OrderBy(item => item));
|
||||
return _hashUtil.GenerateHashForData(HashingAlgorithm.MD5, concat);
|
||||
return hashUtil.GenerateHashForData(HashingAlgorithm.MD5, concat);
|
||||
}
|
||||
|
||||
protected string CreateSacrificeCacheKey(IEnumerable<MongoId> requiredItems)
|
||||
{
|
||||
var concat = string.Join(",", requiredItems.OrderBy(item => item));
|
||||
return _hashUtil.GenerateHashForData(HashingAlgorithm.MD5, concat);
|
||||
return hashUtil.GenerateHashForData(HashingAlgorithm.MD5, concat);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -1011,7 +1007,7 @@ public class CircleOfCultistService(
|
||||
/// <param name="cultistCircleStashId">Stash id</param>
|
||||
/// <param name="output">Client output</param>
|
||||
protected void AddRewardsToCircleContainer(
|
||||
string sessionId,
|
||||
MongoId sessionId,
|
||||
PmcData pmcData,
|
||||
List<List<Item>> rewards,
|
||||
int[,] containerGrid,
|
||||
@@ -1022,8 +1018,8 @@ public class CircleOfCultistService(
|
||||
var canAddToContainer = false;
|
||||
while (!canAddToContainer && rewards.Count > 0)
|
||||
{
|
||||
canAddToContainer = _inventoryHelper.CanPlaceItemsInContainer(
|
||||
_cloner.Clone(containerGrid), // MUST clone grid before passing in as function modifies grid
|
||||
canAddToContainer = inventoryHelper.CanPlaceItemsInContainer(
|
||||
cloner.Clone(containerGrid), // MUST clone grid before passing in as function modifies grid
|
||||
rewards
|
||||
);
|
||||
|
||||
@@ -1036,7 +1032,7 @@ public class CircleOfCultistService(
|
||||
|
||||
foreach (var itemToAdd in rewards)
|
||||
{
|
||||
_inventoryHelper.PlaceItemInContainer(
|
||||
inventoryHelper.PlaceItemInContainer(
|
||||
containerGrid,
|
||||
itemToAdd,
|
||||
cultistCircleStashId,
|
||||
|
||||
@@ -19,30 +19,33 @@ namespace SPTarkov.Server.Core.Services;
|
||||
|
||||
[Injectable]
|
||||
public class CreateProfileService(
|
||||
ISptLogger<CreateProfileService> _logger,
|
||||
TimeUtil _timeUtil,
|
||||
DatabaseService _databaseService,
|
||||
ServerLocalisationService _serverLocalisationService,
|
||||
ProfileHelper _profileHelper,
|
||||
ItemHelper _itemHelper,
|
||||
TraderHelper _traderHelper,
|
||||
QuestHelper _questHelper,
|
||||
QuestRewardHelper _questRewardHelper,
|
||||
PrestigeHelper _prestigeHelper,
|
||||
RewardHelper _rewardHelper,
|
||||
ProfileFixerService _profileFixerService,
|
||||
SaveServer _saveServer,
|
||||
EventOutputHolder _eventOutputHolder,
|
||||
PlayerScavGenerator _playerScavGenerator,
|
||||
ICloner _cloner,
|
||||
MailSendService _mailSendService
|
||||
ISptLogger<CreateProfileService> logger,
|
||||
TimeUtil timeUtil,
|
||||
DatabaseService databaseService,
|
||||
ServerLocalisationService serverLocalisationService,
|
||||
ProfileHelper profileHelper,
|
||||
ItemHelper itemHelper,
|
||||
TraderHelper traderHelper,
|
||||
QuestHelper questHelper,
|
||||
QuestRewardHelper questRewardHelper,
|
||||
PrestigeHelper prestigeHelper,
|
||||
RewardHelper rewardHelper,
|
||||
ProfileFixerService profileFixerService,
|
||||
SaveServer saveServer,
|
||||
EventOutputHolder eventOutputHolder,
|
||||
PlayerScavGenerator playerScavGenerator,
|
||||
ICloner cloner,
|
||||
MailSendService mailSendService
|
||||
)
|
||||
{
|
||||
public async ValueTask<string> CreateProfile(string sessionId, ProfileCreateRequestData request)
|
||||
public async ValueTask<string> CreateProfile(
|
||||
MongoId sessionId,
|
||||
ProfileCreateRequestData request
|
||||
)
|
||||
{
|
||||
var account = _cloner.Clone(_saveServer.GetProfile(sessionId));
|
||||
var profileTemplateClone = _cloner.Clone(
|
||||
_profileHelper.GetProfileTemplateForSide(account.ProfileInfo.Edition, request.Side)
|
||||
var account = cloner.Clone(saveServer.GetProfile(sessionId));
|
||||
var profileTemplateClone = cloner.Clone(
|
||||
profileHelper.GetProfileTemplateForSide(account.ProfileInfo.Edition, request.Side)
|
||||
);
|
||||
|
||||
var pmcData = profileTemplateClone.Character;
|
||||
@@ -56,12 +59,12 @@ public class CreateProfileService(
|
||||
pmcData.SessionId = sessionId;
|
||||
pmcData.Info.Nickname = request.Nickname;
|
||||
pmcData.Info.LowerNickname = request.Nickname.ToLowerInvariant();
|
||||
pmcData.Info.RegistrationDate = (int)_timeUtil.GetTimeStamp();
|
||||
pmcData.Info.Voice = _databaseService.GetCustomization()[request.VoiceId].Name;
|
||||
pmcData.Stats = _profileHelper.GetDefaultCounters();
|
||||
pmcData.Info.RegistrationDate = (int)timeUtil.GetTimeStamp();
|
||||
pmcData.Info.Voice = databaseService.GetCustomization()[request.VoiceId].Name;
|
||||
pmcData.Stats = profileHelper.GetDefaultCounters();
|
||||
pmcData.Info.NeedWipeOptions = [];
|
||||
pmcData.Customization.Head = request.HeadId;
|
||||
pmcData.Health.UpdateTime = _timeUtil.GetTimeStamp();
|
||||
pmcData.Health.UpdateTime = timeUtil.GetTimeStamp();
|
||||
pmcData.Quests = [];
|
||||
pmcData.Hideout.Seed = Convert.ToHexStringLower(RandomNumberGenerator.GetBytes(16));
|
||||
pmcData.RepeatableQuests = [];
|
||||
@@ -103,7 +106,7 @@ public class CreateProfileService(
|
||||
AddMissingInternalContainersToProfile(pmcData);
|
||||
|
||||
// Change item IDs to be unique
|
||||
_itemHelper.ReplaceProfileInventoryIds(pmcData.Inventory);
|
||||
itemHelper.ReplaceProfileInventoryIds(pmcData.Inventory);
|
||||
|
||||
// Create profile
|
||||
var profileDetails = new SptProfile
|
||||
@@ -112,7 +115,7 @@ public class CreateProfileService(
|
||||
CharacterData = new Characters { PmcData = pmcData, ScavData = new PmcData() },
|
||||
UserBuildData = profileTemplateClone.UserBuilds,
|
||||
DialogueRecords = profileTemplateClone.Dialogues,
|
||||
SptData = _profileHelper.GetDefaultSptDataObject(),
|
||||
SptData = profileHelper.GetDefaultSptDataObject(),
|
||||
InraidData = new Inraid(),
|
||||
InsuranceList = [],
|
||||
BtrDeliveryList = [],
|
||||
@@ -125,11 +128,11 @@ public class CreateProfileService(
|
||||
|
||||
profileDetails.AddSuitsToProfile(profileTemplateClone.Suits);
|
||||
|
||||
_profileFixerService.CheckForAndFixPmcProfileIssues(profileDetails.CharacterData.PmcData);
|
||||
profileFixerService.CheckForAndFixPmcProfileIssues(profileDetails.CharacterData.PmcData);
|
||||
|
||||
if (profileDetails.CharacterData.PmcData.Achievements.Count > 0)
|
||||
{
|
||||
var achievementsDb = _databaseService.GetTemplates().Achievements;
|
||||
var achievementsDb = databaseService.GetTemplates().Achievements;
|
||||
var achievementRewardItemsToSend = new List<Item>();
|
||||
|
||||
foreach (var (achievementId, _) in profileDetails.CharacterData.PmcData.Achievements)
|
||||
@@ -144,7 +147,7 @@ public class CreateProfileService(
|
||||
}
|
||||
|
||||
achievementRewardItemsToSend.AddRange(
|
||||
_rewardHelper.ApplyRewards(
|
||||
rewardHelper.ApplyRewards(
|
||||
rewards,
|
||||
CustomisationSource.ACHIEVEMENT,
|
||||
profileDetails,
|
||||
@@ -156,8 +159,8 @@ public class CreateProfileService(
|
||||
|
||||
if (achievementRewardItemsToSend.Count > 0)
|
||||
{
|
||||
_mailSendService.SendLocalisedSystemMessageToPlayer(
|
||||
profileDetails.ProfileInfo.ProfileId,
|
||||
mailSendService.SendLocalisedSystemMessageToPlayer(
|
||||
profileDetails.ProfileInfo.ProfileId.Value,
|
||||
"670547bb5fa0b1a7c30d5836 0",
|
||||
achievementRewardItemsToSend,
|
||||
[],
|
||||
@@ -176,14 +179,14 @@ public class CreateProfileService(
|
||||
? account.SptData.PendingPrestige
|
||||
: new PendingPrestige { PrestigeLevel = request.SptForcePrestigeLevel };
|
||||
|
||||
_prestigeHelper.ProcessPendingPrestige(account, profileDetails, pendingPrestige);
|
||||
prestigeHelper.ProcessPendingPrestige(account, profileDetails, pendingPrestige);
|
||||
}
|
||||
|
||||
_saveServer.AddProfile(profileDetails);
|
||||
saveServer.AddProfile(profileDetails);
|
||||
|
||||
if (profileTemplateClone.Trader.SetQuestsAvailableForStart ?? false)
|
||||
{
|
||||
_questHelper.AddAllQuestsToProfile(
|
||||
questHelper.AddAllQuestsToProfile(
|
||||
profileDetails.CharacterData.PmcData,
|
||||
[QuestStatusEnum.AvailableForStart]
|
||||
);
|
||||
@@ -192,7 +195,7 @@ public class CreateProfileService(
|
||||
// Profile is flagged as wanting quests set to ready to hand in and collect rewards
|
||||
if (profileTemplateClone.Trader.SetQuestsAvailableForFinish ?? false)
|
||||
{
|
||||
_questHelper.AddAllQuestsToProfile(
|
||||
questHelper.AddAllQuestsToProfile(
|
||||
profileDetails.CharacterData.PmcData,
|
||||
[
|
||||
QuestStatusEnum.AvailableForStart,
|
||||
@@ -202,7 +205,7 @@ public class CreateProfileService(
|
||||
);
|
||||
|
||||
// Make unused response so applyQuestReward works
|
||||
var response = _eventOutputHolder.GetOutput(sessionId);
|
||||
var response = eventOutputHolder.GetOutput(sessionId);
|
||||
|
||||
// Add rewards for starting quests to profile
|
||||
GivePlayerStartingQuestRewards(profileDetails, sessionId, response);
|
||||
@@ -210,17 +213,17 @@ public class CreateProfileService(
|
||||
|
||||
ResetAllTradersInProfile(sessionId);
|
||||
|
||||
_saveServer.GetProfile(sessionId).CharacterData.ScavData = _playerScavGenerator.Generate(
|
||||
saveServer.GetProfile(sessionId).CharacterData.ScavData = playerScavGenerator.Generate(
|
||||
sessionId
|
||||
);
|
||||
|
||||
// Store minimal profile and reload it
|
||||
await _saveServer.SaveProfileAsync(sessionId);
|
||||
await _saveServer.LoadProfileAsync(sessionId);
|
||||
await saveServer.SaveProfileAsync(sessionId);
|
||||
await saveServer.LoadProfileAsync(sessionId);
|
||||
|
||||
// Completed account creation
|
||||
_saveServer.GetProfile(sessionId).ProfileInfo.IsWiped = false;
|
||||
await _saveServer.SaveProfileAsync(sessionId);
|
||||
saveServer.GetProfile(sessionId).ProfileInfo.IsWiped = false;
|
||||
await saveServer.SaveProfileAsync(sessionId);
|
||||
|
||||
return pmcData.Id;
|
||||
}
|
||||
@@ -229,16 +232,16 @@ public class CreateProfileService(
|
||||
/// Delete a profile
|
||||
/// </summary>
|
||||
/// <param name="sessionID"> ID of profile to delete </param>
|
||||
protected void DeleteProfileBySessionId(string sessionID)
|
||||
protected void DeleteProfileBySessionId(MongoId sessionID)
|
||||
{
|
||||
if (_saveServer.GetProfiles().ContainsKey(sessionID))
|
||||
if (saveServer.GetProfiles().ContainsKey(sessionID))
|
||||
{
|
||||
_saveServer.DeleteProfileById(sessionID);
|
||||
saveServer.DeleteProfileById(sessionID);
|
||||
}
|
||||
else
|
||||
{
|
||||
_logger.Warning(
|
||||
_serverLocalisationService.GetText(
|
||||
logger.Warning(
|
||||
serverLocalisationService.GetText(
|
||||
"profile-unable_to_find_profile_by_id_cannot_delete",
|
||||
sessionID
|
||||
)
|
||||
@@ -274,11 +277,11 @@ public class CreateProfileService(
|
||||
/// For each trader reset their state to what a level 1 player would see
|
||||
/// </summary>
|
||||
/// <param name="sessionId"> Session ID of profile to reset </param>
|
||||
protected void ResetAllTradersInProfile(string sessionId)
|
||||
protected void ResetAllTradersInProfile(MongoId sessionId)
|
||||
{
|
||||
foreach (var traderId in _databaseService.GetTraders().Keys)
|
||||
foreach (var traderId in databaseService.GetTraders().Keys)
|
||||
{
|
||||
_traderHelper.ResetTrader(sessionId, traderId);
|
||||
traderHelper.ResetTrader(sessionId, traderId);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -347,24 +350,24 @@ public class CreateProfileService(
|
||||
/// <param name="response"> Event router response </param>
|
||||
protected void GivePlayerStartingQuestRewards(
|
||||
SptProfile profileDetails,
|
||||
string sessionID,
|
||||
MongoId sessionID,
|
||||
ItemEventRouterResponse response
|
||||
)
|
||||
{
|
||||
foreach (var quest in profileDetails.CharacterData.PmcData.Quests)
|
||||
{
|
||||
var questFromDb = _questHelper.GetQuestFromDb(
|
||||
var questFromDb = questHelper.GetQuestFromDb(
|
||||
quest.QId,
|
||||
profileDetails.CharacterData.PmcData
|
||||
);
|
||||
|
||||
// Get messageId of text to send to player as text message in game
|
||||
// Copy of code from QuestController.acceptQuest()
|
||||
var messageId = _questHelper.GetMessageIdForQuestStart(
|
||||
var messageId = questHelper.GetMessageIdForQuestStart(
|
||||
questFromDb.StartedMessageText,
|
||||
questFromDb.Description
|
||||
);
|
||||
var itemRewards = _questRewardHelper
|
||||
var itemRewards = questRewardHelper
|
||||
.ApplyQuestReward(
|
||||
profileDetails.CharacterData.PmcData,
|
||||
quest.QId,
|
||||
@@ -374,13 +377,13 @@ public class CreateProfileService(
|
||||
)
|
||||
.ToList();
|
||||
|
||||
_mailSendService.SendLocalisedNpcMessageToPlayer(
|
||||
mailSendService.SendLocalisedNpcMessageToPlayer(
|
||||
sessionID,
|
||||
questFromDb.TraderId,
|
||||
MessageType.QuestStart,
|
||||
messageId,
|
||||
itemRewards,
|
||||
_timeUtil.GetHoursAsSeconds(100)
|
||||
timeUtil.GetHoursAsSeconds(100)
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -9,12 +9,12 @@ namespace SPTarkov.Server.Core.Services;
|
||||
|
||||
[Injectable(InjectionType.Singleton)]
|
||||
public class CustomLocationWaveService(
|
||||
ISptLogger<CustomLocationWaveService> _logger,
|
||||
DatabaseService _databaseService,
|
||||
ConfigServer _configServer
|
||||
ISptLogger<CustomLocationWaveService> logger,
|
||||
DatabaseService databaseService,
|
||||
ConfigServer configServer
|
||||
)
|
||||
{
|
||||
protected readonly LocationConfig _locationConfig = _configServer.GetConfig<LocationConfig>();
|
||||
protected readonly LocationConfig _locationConfig = configServer.GetConfig<LocationConfig>();
|
||||
|
||||
/// <summary>
|
||||
/// Add a boss wave to a map
|
||||
@@ -64,10 +64,10 @@ public class CustomLocationWaveService(
|
||||
|
||||
foreach (var mapKvP in bossWavesToApply)
|
||||
{
|
||||
var locationBase = _databaseService.GetLocation(mapKvP.Key).Base;
|
||||
var locationBase = databaseService.GetLocation(mapKvP.Key).Base;
|
||||
if (locationBase is null)
|
||||
{
|
||||
_logger.Warning(
|
||||
logger.Warning(
|
||||
$"Unable to add custom boss wave to location: {mapKvP}, location not found"
|
||||
);
|
||||
|
||||
@@ -83,9 +83,9 @@ public class CustomLocationWaveService(
|
||||
}
|
||||
|
||||
locationBase.BossLocationSpawn.Add(bossWave);
|
||||
if (_logger.IsLogEnabled(LogLevel.Debug))
|
||||
if (logger.IsLogEnabled(LogLevel.Debug))
|
||||
{
|
||||
_logger.Debug(
|
||||
logger.Debug(
|
||||
$"Added custom boss wave to {mapKvP.Key} of type {bossWave.BossName}, time: {bossWave.Time}, chance: {bossWave.BossChance}, zone: {(string.IsNullOrEmpty(bossWave.BossZone) ? "Global" : bossWave.BossZone)}"
|
||||
);
|
||||
}
|
||||
@@ -94,10 +94,10 @@ public class CustomLocationWaveService(
|
||||
|
||||
foreach (var mapKvP in normalWavesToApply)
|
||||
{
|
||||
var locationBase = _databaseService.GetLocation(mapKvP.Key).Base;
|
||||
var locationBase = databaseService.GetLocation(mapKvP.Key).Base;
|
||||
if (locationBase is null)
|
||||
{
|
||||
_logger.Warning(
|
||||
logger.Warning(
|
||||
$"Unable to add custom wave to location: {mapKvP}, location not found"
|
||||
);
|
||||
|
||||
|
||||
@@ -21,9 +21,9 @@ namespace SPTarkov.Server.Core.Services;
|
||||
/// </summary>
|
||||
[Injectable(InjectionType.Singleton)]
|
||||
public class DatabaseService(
|
||||
ISptLogger<DatabaseService> _logger,
|
||||
DatabaseServer _databaseServer,
|
||||
ServerLocalisationService _serverLocalisationService
|
||||
ISptLogger<DatabaseService> logger,
|
||||
DatabaseServer databaseServer,
|
||||
ServerLocalisationService serverLocalisationService
|
||||
)
|
||||
{
|
||||
private bool _isDataValid = true;
|
||||
@@ -31,87 +31,87 @@ public class DatabaseService(
|
||||
/// <returns> assets/database/ </returns>
|
||||
public DatabaseTables GetTables()
|
||||
{
|
||||
return _databaseServer.GetTables();
|
||||
return databaseServer.GetTables();
|
||||
}
|
||||
|
||||
/// <returns> assets/database/bots/ </returns>
|
||||
public Bots GetBots()
|
||||
{
|
||||
if (_databaseServer.GetTables().Bots == null)
|
||||
if (databaseServer.GetTables().Bots == null)
|
||||
{
|
||||
throw new Exception(
|
||||
_serverLocalisationService.GetText(
|
||||
serverLocalisationService.GetText(
|
||||
"database-data_at_path_missing",
|
||||
"assets/database/bots"
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
return _databaseServer.GetTables().Bots!;
|
||||
return databaseServer.GetTables().Bots!;
|
||||
}
|
||||
|
||||
/// <returns> assets/database/globals.json </returns>
|
||||
public Globals GetGlobals()
|
||||
{
|
||||
if (_databaseServer.GetTables().Globals == null)
|
||||
if (databaseServer.GetTables().Globals == null)
|
||||
{
|
||||
throw new Exception(
|
||||
_serverLocalisationService.GetText(
|
||||
serverLocalisationService.GetText(
|
||||
"database-data_at_path_missing",
|
||||
"assets/database/globals.json"
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
return _databaseServer.GetTables().Globals!;
|
||||
return databaseServer.GetTables().Globals!;
|
||||
}
|
||||
|
||||
/// <returns> assets/database/hideout/ </returns>
|
||||
public Hideout GetHideout()
|
||||
{
|
||||
if (_databaseServer.GetTables().Hideout == null)
|
||||
if (databaseServer.GetTables().Hideout == null)
|
||||
{
|
||||
throw new Exception(
|
||||
_serverLocalisationService.GetText(
|
||||
serverLocalisationService.GetText(
|
||||
"database-data_at_path_missing",
|
||||
"assets/database/hideout"
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
return _databaseServer.GetTables().Hideout!;
|
||||
return databaseServer.GetTables().Hideout!;
|
||||
}
|
||||
|
||||
/// <returns> assets/database/locales/ </returns>
|
||||
public LocaleBase GetLocales()
|
||||
{
|
||||
if (_databaseServer.GetTables().Locales == null)
|
||||
if (databaseServer.GetTables().Locales == null)
|
||||
{
|
||||
throw new Exception(
|
||||
_serverLocalisationService.GetText(
|
||||
serverLocalisationService.GetText(
|
||||
"database-data_at_path_missing",
|
||||
"assets/database/locales"
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
return _databaseServer.GetTables().Locales!;
|
||||
return databaseServer.GetTables().Locales!;
|
||||
}
|
||||
|
||||
/// <returns> assets/database/locations </returns>
|
||||
public Locations GetLocations()
|
||||
{
|
||||
if (_databaseServer.GetTables().Locations == null)
|
||||
if (databaseServer.GetTables().Locations == null)
|
||||
{
|
||||
throw new Exception(
|
||||
_serverLocalisationService.GetText(
|
||||
serverLocalisationService.GetText(
|
||||
"database-data_at_path_missing",
|
||||
"assets/database/locations"
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
return _databaseServer.GetTables().Locations!;
|
||||
return databaseServer.GetTables().Locations!;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -125,8 +125,8 @@ public class DatabaseService(
|
||||
?.GetByJsonProp<Location>(locationId.ToLowerInvariant());
|
||||
if (desiredLocation == null)
|
||||
{
|
||||
_logger.Error(
|
||||
_serverLocalisationService.GetText("database-no_location_found_with_id", locationId)
|
||||
logger.Error(
|
||||
serverLocalisationService.GetText("database-no_location_found_with_id", locationId)
|
||||
);
|
||||
|
||||
return null;
|
||||
@@ -138,209 +138,209 @@ public class DatabaseService(
|
||||
/// <returns> assets/database/match/ </returns>
|
||||
public Match GetMatch()
|
||||
{
|
||||
if (_databaseServer.GetTables().Match == null)
|
||||
if (databaseServer.GetTables().Match == null)
|
||||
{
|
||||
throw new Exception(
|
||||
_serverLocalisationService.GetText(
|
||||
serverLocalisationService.GetText(
|
||||
"database-data_at_path_missing",
|
||||
"assets/database/locales"
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
return _databaseServer.GetTables().Match!;
|
||||
return databaseServer.GetTables().Match!;
|
||||
}
|
||||
|
||||
/// <returns> assets/database/server.json </returns>
|
||||
public ServerBase GetServer()
|
||||
{
|
||||
if (_databaseServer.GetTables().Server == null)
|
||||
if (databaseServer.GetTables().Server == null)
|
||||
{
|
||||
throw new Exception(
|
||||
_serverLocalisationService.GetText(
|
||||
serverLocalisationService.GetText(
|
||||
"database-data_at_path_missing",
|
||||
"assets/database/server.json"
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
return _databaseServer.GetTables().Server!;
|
||||
return databaseServer.GetTables().Server!;
|
||||
}
|
||||
|
||||
/// <returns> assets/database/settings.json </returns>
|
||||
public SettingsBase GetSettings()
|
||||
{
|
||||
if (_databaseServer.GetTables().Settings == null)
|
||||
if (databaseServer.GetTables().Settings == null)
|
||||
{
|
||||
throw new Exception(
|
||||
_serverLocalisationService.GetText(
|
||||
serverLocalisationService.GetText(
|
||||
"database-data_at_path_missing",
|
||||
"assets/database/settings.json"
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
return _databaseServer.GetTables().Settings!;
|
||||
return databaseServer.GetTables().Settings!;
|
||||
}
|
||||
|
||||
/// <returns> assets/database/templates/ </returns>
|
||||
public Templates GetTemplates()
|
||||
{
|
||||
if (_databaseServer.GetTables().Templates == null)
|
||||
if (databaseServer.GetTables().Templates == null)
|
||||
{
|
||||
throw new Exception(
|
||||
_serverLocalisationService.GetText(
|
||||
serverLocalisationService.GetText(
|
||||
"database-data_at_path_missing",
|
||||
"assets/database/templates"
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
return _databaseServer.GetTables().Templates!;
|
||||
return databaseServer.GetTables().Templates!;
|
||||
}
|
||||
|
||||
/// <returns> assets/database/templates/achievements.json </returns>
|
||||
public List<Achievement> GetAchievements()
|
||||
{
|
||||
if (_databaseServer.GetTables().Templates?.Achievements == null)
|
||||
if (databaseServer.GetTables().Templates?.Achievements == null)
|
||||
{
|
||||
throw new Exception(
|
||||
_serverLocalisationService.GetText(
|
||||
serverLocalisationService.GetText(
|
||||
"database-data_at_path_missing",
|
||||
"assets/database/templates/achievements.json"
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
return _databaseServer.GetTables().Templates?.Achievements!;
|
||||
return databaseServer.GetTables().Templates?.Achievements!;
|
||||
}
|
||||
|
||||
/// <returns> assets/database/templates/customAchievements.json </returns>
|
||||
public List<Achievement> GetCustomAchievements()
|
||||
{
|
||||
if (_databaseServer.GetTables().Templates?.Achievements == null)
|
||||
if (databaseServer.GetTables().Templates?.Achievements == null)
|
||||
{
|
||||
throw new Exception(
|
||||
_serverLocalisationService.GetText(
|
||||
serverLocalisationService.GetText(
|
||||
"database-data_at_path_missing",
|
||||
"assets/database/templates/customAchievements.json"
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
return _databaseServer.GetTables().Templates?.CustomAchievements!;
|
||||
return databaseServer.GetTables().Templates?.CustomAchievements!;
|
||||
}
|
||||
|
||||
/// <returns> assets/database/templates/customisation.json </returns>
|
||||
public Dictionary<string, CustomizationItem?> GetCustomization()
|
||||
{
|
||||
if (_databaseServer.GetTables().Templates?.Customization == null)
|
||||
if (databaseServer.GetTables().Templates?.Customization == null)
|
||||
{
|
||||
throw new Exception(
|
||||
_serverLocalisationService.GetText(
|
||||
serverLocalisationService.GetText(
|
||||
"database-data_at_path_missing",
|
||||
"assets/database/templates/customization.json"
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
return _databaseServer.GetTables().Templates?.Customization!;
|
||||
return databaseServer.GetTables().Templates?.Customization!;
|
||||
}
|
||||
|
||||
/// <returns> assets/database/templates/handbook.json </returns>
|
||||
public HandbookBase GetHandbook()
|
||||
{
|
||||
if (_databaseServer.GetTables().Templates?.Handbook == null)
|
||||
if (databaseServer.GetTables().Templates?.Handbook == null)
|
||||
{
|
||||
throw new Exception(
|
||||
_serverLocalisationService.GetText(
|
||||
serverLocalisationService.GetText(
|
||||
"database-data_at_path_missing",
|
||||
"assets/database/templates/handbook.json"
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
return _databaseServer.GetTables().Templates?.Handbook!;
|
||||
return databaseServer.GetTables().Templates?.Handbook!;
|
||||
}
|
||||
|
||||
/// <returns> assets/database/templates/items.json </returns>
|
||||
public Dictionary<MongoId, TemplateItem> GetItems()
|
||||
{
|
||||
if (_databaseServer.GetTables().Templates?.Items == null)
|
||||
if (databaseServer.GetTables().Templates?.Items == null)
|
||||
{
|
||||
throw new Exception(
|
||||
_serverLocalisationService.GetText(
|
||||
serverLocalisationService.GetText(
|
||||
"database-data_at_path_missing",
|
||||
"assets/database/templates/items.json"
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
return _databaseServer.GetTables().Templates?.Items!;
|
||||
return databaseServer.GetTables().Templates?.Items!;
|
||||
}
|
||||
|
||||
/// <returns> assets/database/templates/prices.json </returns>
|
||||
public Dictionary<MongoId, double> GetPrices()
|
||||
{
|
||||
if (_databaseServer.GetTables().Templates?.Prices == null)
|
||||
if (databaseServer.GetTables().Templates?.Prices == null)
|
||||
{
|
||||
throw new Exception(
|
||||
_serverLocalisationService.GetText(
|
||||
serverLocalisationService.GetText(
|
||||
"database-data_at_path_missing",
|
||||
"assets/database/templates/prices.json"
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
return _databaseServer.GetTables().Templates?.Prices!;
|
||||
return databaseServer.GetTables().Templates?.Prices!;
|
||||
}
|
||||
|
||||
/// <returns> assets/database/templates/profiles.json </returns>
|
||||
public Dictionary<string, ProfileSides> GetProfileTemplates()
|
||||
{
|
||||
if (_databaseServer.GetTables().Templates?.Profiles == null)
|
||||
if (databaseServer.GetTables().Templates?.Profiles == null)
|
||||
{
|
||||
throw new Exception(
|
||||
_serverLocalisationService.GetText(
|
||||
serverLocalisationService.GetText(
|
||||
"database-data_at_path_missing",
|
||||
"assets/database/templates/profiles.json"
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
return _databaseServer.GetTables().Templates?.Profiles!;
|
||||
return databaseServer.GetTables().Templates?.Profiles!;
|
||||
}
|
||||
|
||||
/// <returns> assets/database/templates/quests.json </returns>
|
||||
public Dictionary<string, Quest> GetQuests()
|
||||
{
|
||||
if (_databaseServer.GetTables().Templates?.Quests == null)
|
||||
if (databaseServer.GetTables().Templates?.Quests == null)
|
||||
{
|
||||
throw new Exception(
|
||||
_serverLocalisationService.GetText(
|
||||
serverLocalisationService.GetText(
|
||||
"database-data_at_path_missing",
|
||||
"assets/database/templates/quests.json"
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
return _databaseServer.GetTables().Templates?.Quests!;
|
||||
return databaseServer.GetTables().Templates?.Quests!;
|
||||
}
|
||||
|
||||
/// <returns> assets/database/traders/ </returns>
|
||||
public Dictionary<MongoId, Trader> GetTraders()
|
||||
{
|
||||
if (_databaseServer.GetTables().Traders == null)
|
||||
if (databaseServer.GetTables().Traders == null)
|
||||
{
|
||||
throw new Exception(
|
||||
_serverLocalisationService.GetText(
|
||||
serverLocalisationService.GetText(
|
||||
"database-data_at_path_missing",
|
||||
"assets/database/traders"
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
return _databaseServer.GetTables().Traders!;
|
||||
return databaseServer.GetTables().Traders!;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -348,13 +348,13 @@ public class DatabaseService(
|
||||
/// </summary>
|
||||
/// <param name="traderId"> Desired trader ID </param>
|
||||
/// <returns> assets/database/traders/ </returns>
|
||||
public Trader? GetTrader(string traderId)
|
||||
public Trader? GetTrader(MongoId traderId)
|
||||
{
|
||||
var traders = GetTraders();
|
||||
if (!traders.TryGetValue(traderId, out var desiredTrader))
|
||||
{
|
||||
_logger.Error(
|
||||
_serverLocalisationService.GetText("database-no_trader_found_with_id", traderId)
|
||||
logger.Error(
|
||||
serverLocalisationService.GetText("database-no_trader_found_with_id", traderId)
|
||||
);
|
||||
|
||||
return null;
|
||||
@@ -366,17 +366,17 @@ public class DatabaseService(
|
||||
/// <returns> assets/database/locationServices/ </returns>
|
||||
public LocationServices GetLocationServices()
|
||||
{
|
||||
if (_databaseServer.GetTables().Templates?.LocationServices == null)
|
||||
if (databaseServer.GetTables().Templates?.LocationServices == null)
|
||||
{
|
||||
throw new Exception(
|
||||
_serverLocalisationService.GetText(
|
||||
serverLocalisationService.GetText(
|
||||
"database-data_at_path_missing",
|
||||
"assets/database/locationServices.json"
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
return _databaseServer.GetTables().Templates?.LocationServices!;
|
||||
return databaseServer.GetTables().Templates?.LocationServices!;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -394,13 +394,13 @@ public class DatabaseService(
|
||||
|
||||
if (!_isDataValid)
|
||||
{
|
||||
_logger.Error(_serverLocalisationService.GetText("database-invalid_data"));
|
||||
logger.Error(serverLocalisationService.GetText("database-invalid_data"));
|
||||
}
|
||||
|
||||
start.Stop();
|
||||
if (_logger.IsLogEnabled(LogLevel.Debug))
|
||||
if (logger.IsLogEnabled(LogLevel.Debug))
|
||||
{
|
||||
_logger.Debug($"ID validation took: {start.ElapsedMilliseconds}ms");
|
||||
logger.Debug($"ID validation took: {start.ElapsedMilliseconds}ms");
|
||||
}
|
||||
}
|
||||
|
||||
@@ -416,7 +416,7 @@ public class DatabaseService(
|
||||
{
|
||||
if (!keyValuePair.Key.IsValidMongoId())
|
||||
{
|
||||
_logger.Error($"Invalid {tableType} ID: '{keyValuePair.Key}'");
|
||||
logger.Error($"Invalid {tableType} ID: '{keyValuePair.Key}'");
|
||||
return false;
|
||||
}
|
||||
}
|
||||
@@ -430,7 +430,7 @@ public class DatabaseService(
|
||||
{
|
||||
if (!keyValuePair.Key.IsValidMongoId())
|
||||
{
|
||||
_logger.Error($"Invalid {tableType} ID: '{keyValuePair.Key}'");
|
||||
logger.Error($"Invalid {tableType} ID: '{keyValuePair.Key}'");
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
using SPTarkov.DI.Annotations;
|
||||
using SPTarkov.Server.Core.Helpers;
|
||||
using SPTarkov.Server.Core.Models.Common;
|
||||
using SPTarkov.Server.Core.Models.Eft.Profile;
|
||||
using SPTarkov.Server.Core.Models.Enums;
|
||||
using SPTarkov.Server.Core.Models.Spt.Config;
|
||||
@@ -13,15 +14,15 @@ namespace SPTarkov.Server.Core.Services;
|
||||
|
||||
[Injectable(InjectionType.Singleton)]
|
||||
public class GiftService(
|
||||
ISptLogger<GiftService> _logger,
|
||||
MailSendService _mailSendService,
|
||||
ServerLocalisationService _serverLocalisationService,
|
||||
TimeUtil _timeUtil,
|
||||
ProfileHelper _profileHelper,
|
||||
ConfigServer _configServer
|
||||
ISptLogger<GiftService> logger,
|
||||
MailSendService mailSendService,
|
||||
ServerLocalisationService serverLocalisationService,
|
||||
TimeUtil timeUtil,
|
||||
ProfileHelper profileHelper,
|
||||
ConfigServer configServer
|
||||
)
|
||||
{
|
||||
protected readonly GiftsConfig _giftConfig = _configServer.GetConfig<GiftsConfig>();
|
||||
protected readonly GiftsConfig _giftConfig = configServer.GetConfig<GiftsConfig>();
|
||||
|
||||
/// <summary>
|
||||
/// Does a gift with a specific ID exist in db
|
||||
@@ -74,11 +75,11 @@ public class GiftService(
|
||||
|
||||
var maxGiftsToSendCount = giftData.MaxToSendPlayer ?? 1;
|
||||
|
||||
if (_profileHelper.PlayerHasReceivedMaxNumberOfGift(playerId, giftId, maxGiftsToSendCount))
|
||||
if (profileHelper.PlayerHasReceivedMaxNumberOfGift(playerId, giftId, maxGiftsToSendCount))
|
||||
{
|
||||
if (_logger.IsLogEnabled(LogLevel.Debug))
|
||||
if (logger.IsLogEnabled(LogLevel.Debug))
|
||||
{
|
||||
_logger.Debug($"Player already received gift: {giftId}");
|
||||
logger.Debug($"Player already received gift: {giftId}");
|
||||
}
|
||||
|
||||
return GiftSentResult.FAILED_GIFT_ALREADY_RECEIVED;
|
||||
@@ -86,7 +87,7 @@ public class GiftService(
|
||||
|
||||
if (giftData.Items?.Count > 0 && giftData.CollectionTimeHours is null)
|
||||
{
|
||||
_logger.Warning(
|
||||
logger.Warning(
|
||||
$"Gift {giftId} has items but no collection time limit, defaulting to 48 hours"
|
||||
);
|
||||
}
|
||||
@@ -97,21 +98,21 @@ public class GiftService(
|
||||
// Has a localisable text id to send to player
|
||||
if (giftData.LocaleTextId is not null)
|
||||
{
|
||||
_mailSendService.SendLocalisedSystemMessageToPlayer(
|
||||
mailSendService.SendLocalisedSystemMessageToPlayer(
|
||||
playerId,
|
||||
giftData.LocaleTextId,
|
||||
giftData.Items,
|
||||
giftData.ProfileChangeEvents,
|
||||
_timeUtil.GetHoursAsSeconds(giftData.CollectionTimeHours ?? 1)
|
||||
timeUtil.GetHoursAsSeconds(giftData.CollectionTimeHours ?? 1)
|
||||
);
|
||||
}
|
||||
else
|
||||
{
|
||||
_mailSendService.SendSystemMessageToPlayer(
|
||||
mailSendService.SendSystemMessageToPlayer(
|
||||
playerId,
|
||||
giftData.MessageText,
|
||||
giftData.Items,
|
||||
_timeUtil.GetHoursAsSeconds(giftData.CollectionTimeHours ?? 1),
|
||||
timeUtil.GetHoursAsSeconds(giftData.CollectionTimeHours ?? 1),
|
||||
giftData.ProfileChangeEvents
|
||||
);
|
||||
}
|
||||
@@ -119,36 +120,36 @@ public class GiftService(
|
||||
// Handle user messages
|
||||
else if (giftData.Sender == GiftSenderType.User)
|
||||
{
|
||||
_mailSendService.SendUserMessageToPlayer(
|
||||
mailSendService.SendUserMessageToPlayer(
|
||||
playerId,
|
||||
giftData.SenderDetails,
|
||||
giftData.MessageText,
|
||||
giftData.Items,
|
||||
_timeUtil.GetHoursAsSeconds(giftData.CollectionTimeHours ?? 1)
|
||||
timeUtil.GetHoursAsSeconds(giftData.CollectionTimeHours ?? 1)
|
||||
);
|
||||
}
|
||||
else if (giftData.Sender == GiftSenderType.Trader)
|
||||
{
|
||||
if (giftData.LocaleTextId is not null)
|
||||
{
|
||||
_mailSendService.SendLocalisedNpcMessageToPlayer(
|
||||
mailSendService.SendLocalisedNpcMessageToPlayer(
|
||||
playerId,
|
||||
giftData.Trader,
|
||||
MessageType.MessageWithItems,
|
||||
giftData.LocaleTextId,
|
||||
giftData.Items,
|
||||
_timeUtil.GetHoursAsSeconds(giftData.CollectionTimeHours ?? 1)
|
||||
timeUtil.GetHoursAsSeconds(giftData.CollectionTimeHours ?? 1)
|
||||
);
|
||||
}
|
||||
else
|
||||
{
|
||||
_mailSendService.SendLocalisedNpcMessageToPlayer(
|
||||
mailSendService.SendLocalisedNpcMessageToPlayer(
|
||||
playerId,
|
||||
giftData.Trader,
|
||||
MessageType.MessageWithItems,
|
||||
giftData.MessageText,
|
||||
giftData.Items,
|
||||
_timeUtil.GetHoursAsSeconds(giftData.CollectionTimeHours ?? 1)
|
||||
timeUtil.GetHoursAsSeconds(giftData.CollectionTimeHours ?? 1)
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -168,7 +169,7 @@ public class GiftService(
|
||||
},
|
||||
MessageText = giftData.MessageText,
|
||||
Items = giftData.Items,
|
||||
ItemsMaxStorageLifetimeSeconds = _timeUtil.GetHoursAsSeconds(
|
||||
ItemsMaxStorageLifetimeSeconds = timeUtil.GetHoursAsSeconds(
|
||||
giftData.CollectionTimeHours ?? 0
|
||||
),
|
||||
};
|
||||
@@ -178,10 +179,10 @@ public class GiftService(
|
||||
details.Trader = giftData.Trader;
|
||||
}
|
||||
|
||||
_mailSendService.SendMessageToPlayer(details);
|
||||
mailSendService.SendMessageToPlayer(details);
|
||||
}
|
||||
|
||||
_profileHelper.FlagGiftReceivedInProfile(playerId, giftId, maxGiftsToSendCount);
|
||||
profileHelper.FlagGiftReceivedInProfile(playerId, giftId, maxGiftsToSendCount);
|
||||
|
||||
return GiftSentResult.SUCCESS;
|
||||
}
|
||||
@@ -222,8 +223,8 @@ public class GiftService(
|
||||
case GiftSenderType.User:
|
||||
return MessageType.UserMessage;
|
||||
default:
|
||||
_logger.Error(
|
||||
_serverLocalisationService.GetText(
|
||||
logger.Error(
|
||||
serverLocalisationService.GetText(
|
||||
"gift-unable_to_handle_message_type_command",
|
||||
giftData.Sender
|
||||
)
|
||||
@@ -237,7 +238,7 @@ public class GiftService(
|
||||
/// </summary>
|
||||
/// <param name="sessionId"> Player ID </param>
|
||||
/// <param name="day"> What day to give gift for </param>
|
||||
public void SendPraporStartingGift(string sessionId, int day)
|
||||
public void SendPraporStartingGift(MongoId sessionId, int day)
|
||||
{
|
||||
var giftId = day switch
|
||||
{
|
||||
@@ -248,7 +249,7 @@ public class GiftService(
|
||||
|
||||
if (giftId is not null)
|
||||
{
|
||||
if (!_profileHelper.PlayerHasReceivedMaxNumberOfGift(sessionId, giftId, 1))
|
||||
if (!profileHelper.PlayerHasReceivedMaxNumberOfGift(sessionId, giftId, 1))
|
||||
{
|
||||
SendGiftToPlayer(sessionId, giftId);
|
||||
}
|
||||
@@ -261,9 +262,9 @@ public class GiftService(
|
||||
/// <param name="giftId"> ID of gift to send </param>
|
||||
/// <param name="sessionId"> Session ID of player to send to </param>
|
||||
/// <param name="giftCount"> Optional, how many to send </param>
|
||||
public void SendGiftWithSilentReceivedCheck(string giftId, string? sessionId, int giftCount)
|
||||
public void SendGiftWithSilentReceivedCheck(string giftId, MongoId? sessionId, int giftCount)
|
||||
{
|
||||
if (!_profileHelper.PlayerHasReceivedMaxNumberOfGift(sessionId, giftId, giftCount))
|
||||
if (!profileHelper.PlayerHasReceivedMaxNumberOfGift(sessionId.Value, giftId, giftCount))
|
||||
{
|
||||
SendGiftToPlayer(sessionId, giftId);
|
||||
}
|
||||
|
||||
@@ -4,7 +4,7 @@ using SPTarkov.Server.Core.Utils.Cloners;
|
||||
namespace SPTarkov.Server.Core.Services;
|
||||
|
||||
[Injectable(InjectionType.Singleton)]
|
||||
public class InMemoryCacheService(ICloner _cloner)
|
||||
public class InMemoryCacheService(ICloner cloner)
|
||||
{
|
||||
protected readonly Dictionary<string, object?> _cacheData = new();
|
||||
|
||||
@@ -15,7 +15,7 @@ public class InMemoryCacheService(ICloner _cloner)
|
||||
/// <param name="dataToCache"> Data to store in cache </param>
|
||||
public void StoreByKey<T>(string key, T dataToCache)
|
||||
{
|
||||
_cacheData[key] = _cloner.Clone(dataToCache);
|
||||
_cacheData[key] = cloner.Clone(dataToCache);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
using SPTarkov.DI.Annotations;
|
||||
using SPTarkov.Server.Core.Extensions;
|
||||
using SPTarkov.Server.Core.Helpers;
|
||||
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.Profile;
|
||||
@@ -17,28 +18,27 @@ namespace SPTarkov.Server.Core.Services;
|
||||
|
||||
[Injectable(InjectionType.Singleton)]
|
||||
public class InsuranceService(
|
||||
ISptLogger<InsuranceService> _logger,
|
||||
DatabaseService _databaseService,
|
||||
RandomUtil _randomUtil,
|
||||
ItemHelper _itemHelper,
|
||||
TimeUtil _timeUtil,
|
||||
SaveServer _saveServer,
|
||||
TraderHelper _traderHelper,
|
||||
ServerLocalisationService _serverLocalisationService,
|
||||
MailSendService _mailSendService,
|
||||
ConfigServer _configServer
|
||||
ISptLogger<InsuranceService> logger,
|
||||
DatabaseService databaseService,
|
||||
RandomUtil randomUtil,
|
||||
ItemHelper itemHelper,
|
||||
TimeUtil timeUtil,
|
||||
SaveServer saveServer,
|
||||
TraderHelper traderHelper,
|
||||
ServerLocalisationService serverLocalisationService,
|
||||
MailSendService mailSendService,
|
||||
ConfigServer configServer
|
||||
)
|
||||
{
|
||||
protected readonly InsuranceConfig _insuranceConfig =
|
||||
_configServer.GetConfig<InsuranceConfig>();
|
||||
protected readonly Dictionary<string, Dictionary<string, List<Item>>?> _insured = new();
|
||||
protected readonly InsuranceConfig _insuranceConfig = configServer.GetConfig<InsuranceConfig>();
|
||||
protected readonly Dictionary<MongoId, Dictionary<MongoId, List<Item>>?> _insured = new();
|
||||
|
||||
/// <summary>
|
||||
/// Does player have insurance dictionary exists
|
||||
/// </summary>
|
||||
/// <param name="sessionId">Player id</param>
|
||||
/// <returns>True if exists</returns>
|
||||
public bool InsuranceDictionaryExists(string sessionId)
|
||||
public bool InsuranceDictionaryExists(MongoId sessionId)
|
||||
{
|
||||
return _insured.TryGetValue(sessionId, out _);
|
||||
}
|
||||
@@ -48,16 +48,16 @@ public class InsuranceService(
|
||||
/// </summary>
|
||||
/// <param name="sessionId">Profile id (session id)</param>
|
||||
/// <returns>Item list</returns>
|
||||
public Dictionary<string, List<Item>>? GetInsurance(string sessionId)
|
||||
public Dictionary<MongoId, List<Item>>? GetInsurance(MongoId sessionId)
|
||||
{
|
||||
return _insured[sessionId];
|
||||
}
|
||||
|
||||
public void ResetInsurance(string sessionId)
|
||||
public void ResetInsurance(MongoId sessionId)
|
||||
{
|
||||
if (!_insured.TryAdd(sessionId, new Dictionary<string, List<Item>>()))
|
||||
if (!_insured.TryAdd(sessionId, new Dictionary<MongoId, List<Item>>()))
|
||||
{
|
||||
_insured[sessionId] = new Dictionary<string, List<Item>>();
|
||||
_insured[sessionId] = new Dictionary<MongoId, List<Item>>();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -68,17 +68,17 @@ public class InsuranceService(
|
||||
/// <param name="pmcData">Profile to send insured items to</param>
|
||||
/// <param name="sessionID">SessionId of current player</param>
|
||||
/// <param name="mapId">Id of the location player died/exited that caused the insurance to be issued on</param>
|
||||
public void StartPostRaidInsuranceLostProcess(PmcData pmcData, string sessionID, string mapId)
|
||||
public void StartPostRaidInsuranceLostProcess(PmcData pmcData, MongoId sessionID, string mapId)
|
||||
{
|
||||
// Get insurance items for each trader
|
||||
var globals = _databaseService.GetGlobals();
|
||||
var globals = databaseService.GetGlobals();
|
||||
foreach (var traderKvP in GetInsurance(sessionID))
|
||||
{
|
||||
var traderBase = _traderHelper.GetTrader(traderKvP.Key, sessionID);
|
||||
var traderBase = traderHelper.GetTrader(traderKvP.Key, sessionID);
|
||||
if (traderBase is null)
|
||||
{
|
||||
_logger.Error(
|
||||
_serverLocalisationService.GetText(
|
||||
logger.Error(
|
||||
serverLocalisationService.GetText(
|
||||
"insurance-unable_to_find_trader_by_id",
|
||||
traderKvP.Key
|
||||
)
|
||||
@@ -87,11 +87,11 @@ public class InsuranceService(
|
||||
continue;
|
||||
}
|
||||
|
||||
var dialogueTemplates = _databaseService.GetTrader(traderKvP.Key).Dialogue;
|
||||
var dialogueTemplates = databaseService.GetTrader(traderKvP.Key).Dialogue;
|
||||
if (dialogueTemplates is null)
|
||||
{
|
||||
_logger.Error(
|
||||
_serverLocalisationService.GetText(
|
||||
logger.Error(
|
||||
serverLocalisationService.GetText(
|
||||
"insurance-trader_lacks_dialogue_property",
|
||||
traderKvP.Key
|
||||
)
|
||||
@@ -102,21 +102,21 @@ public class InsuranceService(
|
||||
|
||||
var systemData = new SystemData
|
||||
{
|
||||
Date = _timeUtil.GetBsgDateMailFormat(),
|
||||
Time = _timeUtil.GetBsgTimeMailFormat(),
|
||||
Date = timeUtil.GetBsgDateMailFormat(),
|
||||
Time = timeUtil.GetBsgTimeMailFormat(),
|
||||
Location = mapId,
|
||||
};
|
||||
|
||||
// Send "i will go look for your stuff" message from trader to player
|
||||
_mailSendService.SendLocalisedNpcMessageToPlayer(
|
||||
mailSendService.SendLocalisedNpcMessageToPlayer(
|
||||
sessionID,
|
||||
traderKvP.Key,
|
||||
MessageType.NpcTraderMessage,
|
||||
_randomUtil.GetArrayValue(
|
||||
randomUtil.GetArrayValue(
|
||||
dialogueTemplates["insuranceStart"] ?? ["INSURANCE START MESSAGE MISSING"]
|
||||
),
|
||||
null,
|
||||
_timeUtil.GetHoursAsSeconds(
|
||||
timeUtil.GetHoursAsSeconds(
|
||||
(int)globals.Configuration?.Insurance?.MaxStorageTimeInHour
|
||||
),
|
||||
systemData
|
||||
@@ -124,7 +124,7 @@ public class InsuranceService(
|
||||
|
||||
// Store insurance to send to player later in profile
|
||||
// Store insurance return details in profile + "hey i found your stuff, here you go!" message details to send to player at a later date
|
||||
_saveServer
|
||||
saveServer
|
||||
.GetProfile(sessionID)
|
||||
.InsuranceList.Add(
|
||||
new Insurance
|
||||
@@ -134,7 +134,7 @@ public class InsuranceService(
|
||||
MaxStorageTime = (int)GetMaxInsuranceStorageTime(traderBase),
|
||||
SystemData = systemData,
|
||||
MessageType = MessageType.InsuranceReturn,
|
||||
MessageTemplateId = _randomUtil.GetArrayValue(
|
||||
MessageTemplateId = randomUtil.GetArrayValue(
|
||||
dialogueTemplates["insuranceFound"]
|
||||
),
|
||||
Items = GetInsurance(sessionID)[traderKvP.Key],
|
||||
@@ -157,14 +157,14 @@ public class InsuranceService(
|
||||
// If override in config is non-zero, use that instead of trader values
|
||||
if (_insuranceConfig.ReturnTimeOverrideSeconds > 0)
|
||||
{
|
||||
if (_logger.IsLogEnabled(LogLevel.Debug))
|
||||
if (logger.IsLogEnabled(LogLevel.Debug))
|
||||
{
|
||||
_logger.Debug(
|
||||
logger.Debug(
|
||||
$"Insurance override used: returning in {_insuranceConfig.ReturnTimeOverrideSeconds} seconds"
|
||||
);
|
||||
}
|
||||
|
||||
return _timeUtil.GetTimeStamp() + _insuranceConfig.ReturnTimeOverrideSeconds;
|
||||
return timeUtil.GetTimeStamp() + _insuranceConfig.ReturnTimeOverrideSeconds;
|
||||
}
|
||||
|
||||
var insuranceReturnTimeBonusSum = pmcData.GetBonusValueFromProfile(
|
||||
@@ -176,14 +176,14 @@ public class InsuranceService(
|
||||
|
||||
var traderMinReturnAsSeconds = trader.Insurance.MinReturnHour * TimeUtil.OneHourAsSeconds;
|
||||
var traderMaxReturnAsSeconds = trader.Insurance.MaxReturnHour * TimeUtil.OneHourAsSeconds;
|
||||
var randomisedReturnTimeSeconds = _randomUtil.GetDouble(
|
||||
var randomisedReturnTimeSeconds = randomUtil.GetDouble(
|
||||
traderMinReturnAsSeconds.Value,
|
||||
traderMaxReturnAsSeconds.Value
|
||||
);
|
||||
|
||||
// Check for Mark of The Unheard in players special slots (only slot item can fit)
|
||||
var globals = _databaseService.GetGlobals();
|
||||
var hasMarkOfUnheard = _itemHelper.HasItemWithTpl(
|
||||
var globals = databaseService.GetGlobals();
|
||||
var hasMarkOfUnheard = itemHelper.HasItemWithTpl(
|
||||
pmcData.Inventory.Items,
|
||||
ItemTpl.MARKOFUNKNOWN_MARK_OF_THE_UNHEARD,
|
||||
"SpecialSlot"
|
||||
@@ -212,7 +212,7 @@ public class InsuranceService(
|
||||
// Calculate the final return time based on our bonus percent
|
||||
var finalReturnTimeSeconds =
|
||||
randomisedReturnTimeSeconds * (1d - insuranceReturnTimeBonusPercent);
|
||||
return _timeUtil.GetTimeStamp() + finalReturnTimeSeconds;
|
||||
return timeUtil.GetTimeStamp() + finalReturnTimeSeconds;
|
||||
}
|
||||
|
||||
protected double GetMaxInsuranceStorageTime(TraderBase traderBase)
|
||||
@@ -223,7 +223,7 @@ public class InsuranceService(
|
||||
return _insuranceConfig.StorageTimeOverrideSeconds;
|
||||
}
|
||||
|
||||
return _timeUtil.GetHoursAsSeconds((int)traderBase.Insurance.MaxStorageTime);
|
||||
return timeUtil.GetHoursAsSeconds((int)traderBase.Insurance.MaxStorageTime);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -231,7 +231,7 @@ public class InsuranceService(
|
||||
/// </summary>
|
||||
/// <param name="equipmentPkg">Gear to store - generated by GetGearLostInRaid()</param>
|
||||
public void StoreGearLostInRaidToSendLater(
|
||||
string sessionID,
|
||||
MongoId sessionID,
|
||||
List<InsuranceEquipmentPkg> equipmentPkg
|
||||
)
|
||||
{
|
||||
@@ -250,7 +250,7 @@ public class InsuranceService(
|
||||
/// <param name="pmcProfile">Player profile</param>
|
||||
/// <returns>InsuranceEquipmentPkg list</returns>
|
||||
public List<InsuranceEquipmentPkg> MapInsuredItemsToTrader(
|
||||
string sessionId,
|
||||
MongoId sessionId,
|
||||
List<Item> lostInsuredItems,
|
||||
PmcData pmcProfile
|
||||
)
|
||||
@@ -264,7 +264,7 @@ public class InsuranceService(
|
||||
);
|
||||
if (insuranceDetails is null)
|
||||
{
|
||||
_logger.Error(
|
||||
logger.Error(
|
||||
$"unable to find insurance details for item id: {lostItem.Id} with tpl: {lostItem.Template}"
|
||||
);
|
||||
|
||||
@@ -353,7 +353,7 @@ public class InsuranceService(
|
||||
/// <param name="sessionId">Player id (session id)</param>
|
||||
/// <param name="traderId">Trader items insured with</param>
|
||||
/// <returns>True if exists</returns>
|
||||
protected bool InsuranceTraderArrayExists(string sessionId, string traderId)
|
||||
protected bool InsuranceTraderArrayExists(MongoId sessionId, MongoId traderId)
|
||||
{
|
||||
return _insured[sessionId].GetValueOrDefault(traderId) is not null;
|
||||
}
|
||||
@@ -363,7 +363,7 @@ public class InsuranceService(
|
||||
/// </summary>
|
||||
/// <param name="sessionId">Player id (session id)</param>
|
||||
/// <param name="traderId">Trader items insured with</param>
|
||||
public void ResetInsuranceTraderArray(string sessionId, string traderId)
|
||||
public void ResetInsuranceTraderArray(MongoId sessionId, MongoId traderId)
|
||||
{
|
||||
_insured[sessionId][traderId] = [];
|
||||
}
|
||||
@@ -374,7 +374,7 @@ public class InsuranceService(
|
||||
/// <param name="sessionId">Player id (session id)</param>
|
||||
/// <param name="traderId">Trader item insured with</param>
|
||||
/// <param name="itemToAdd">Insured item (with children)</param>
|
||||
public void AddInsuranceItemToArray(string sessionId, string traderId, Item itemToAdd)
|
||||
public void AddInsuranceItemToArray(MongoId sessionId, MongoId traderId, Item itemToAdd)
|
||||
{
|
||||
_insured[sessionId][traderId].Add(itemToAdd);
|
||||
}
|
||||
@@ -389,12 +389,12 @@ public class InsuranceService(
|
||||
public double GetRoublePriceToInsureItemWithTrader(
|
||||
PmcData? pmcData,
|
||||
Item inventoryItem,
|
||||
string traderId
|
||||
MongoId traderId
|
||||
)
|
||||
{
|
||||
var price =
|
||||
_itemHelper.GetStaticItemPrice(inventoryItem.Template)
|
||||
* (_traderHelper.GetLoyaltyLevel(traderId, pmcData).InsurancePriceCoefficient / 100);
|
||||
itemHelper.GetStaticItemPrice(inventoryItem.Template)
|
||||
* (traderHelper.GetLoyaltyLevel(traderId, pmcData).InsurancePriceCoefficient / 100);
|
||||
|
||||
return Math.Ceiling(price ?? 1);
|
||||
}
|
||||
|
||||
@@ -11,9 +11,9 @@ namespace SPTarkov.Server.Core.Services;
|
||||
/// </summary>
|
||||
[Injectable(InjectionType.Singleton)]
|
||||
public class ItemBaseClassService(
|
||||
ISptLogger<ItemBaseClassService> _logger,
|
||||
DatabaseService _databaseService,
|
||||
ServerLocalisationService _serverLocalisationService
|
||||
ISptLogger<ItemBaseClassService> logger,
|
||||
DatabaseService databaseService,
|
||||
ServerLocalisationService serverLocalisationService
|
||||
)
|
||||
{
|
||||
private bool _cacheGenerated;
|
||||
@@ -28,7 +28,7 @@ public class ItemBaseClassService(
|
||||
// Clear existing cache
|
||||
_itemBaseClassesCache = new Dictionary<MongoId, HashSet<MongoId>>();
|
||||
|
||||
var items = _databaseService.GetItems();
|
||||
var items = databaseService.GetItems();
|
||||
var filteredDbItems = items.Where(x =>
|
||||
string.Equals(x.Value.Type, "Item", StringComparison.OrdinalIgnoreCase)
|
||||
);
|
||||
@@ -54,7 +54,7 @@ public class ItemBaseClassService(
|
||||
protected void AddBaseItems(MongoId itemIdToUpdate, TemplateItem item)
|
||||
{
|
||||
_itemBaseClassesCache[itemIdToUpdate].Add(item.Parent);
|
||||
_databaseService.GetItems().TryGetValue(item.Parent, out var parent);
|
||||
databaseService.GetItems().TryGetValue(item.Parent, out var parent);
|
||||
|
||||
if (parent is not null && !parent.Parent.IsEmpty())
|
||||
{
|
||||
@@ -77,7 +77,7 @@ public class ItemBaseClassService(
|
||||
|
||||
if (itemTpl.IsEmpty())
|
||||
{
|
||||
_logger.Warning("Unable to check itemTpl base class as value passed is null");
|
||||
logger.Warning("Unable to check itemTpl base class as value passed is null");
|
||||
|
||||
return false;
|
||||
}
|
||||
@@ -94,9 +94,9 @@ public class ItemBaseClassService(
|
||||
return baseClassList.Overlaps(baseClasses);
|
||||
}
|
||||
|
||||
if (_logger.IsLogEnabled(LogLevel.Debug))
|
||||
if (logger.IsLogEnabled(LogLevel.Debug))
|
||||
{
|
||||
_logger.Debug(_serverLocalisationService.GetText("baseclass-item_not_found", itemTpl));
|
||||
logger.Debug(serverLocalisationService.GetText("baseclass-item_not_found", itemTpl));
|
||||
}
|
||||
|
||||
// Not found in cache, Hydrate again - some mods add items late
|
||||
@@ -108,8 +108,8 @@ public class ItemBaseClassService(
|
||||
return value.Any(baseClasses.Contains);
|
||||
}
|
||||
|
||||
_logger.Warning(
|
||||
_serverLocalisationService.GetText("baseclass-item_not_found_failed", itemTpl)
|
||||
logger.Warning(
|
||||
serverLocalisationService.GetText("baseclass-item_not_found_failed", itemTpl)
|
||||
);
|
||||
|
||||
return false;
|
||||
@@ -123,7 +123,7 @@ public class ItemBaseClassService(
|
||||
private bool CachedItemIsOfItemType(MongoId itemTemplateId)
|
||||
{
|
||||
return string.Equals(
|
||||
_databaseService.GetItems()[itemTemplateId]?.Type,
|
||||
databaseService.GetItems()[itemTemplateId]?.Type,
|
||||
"Item",
|
||||
StringComparison.OrdinalIgnoreCase
|
||||
);
|
||||
|
||||
@@ -12,13 +12,13 @@ namespace SPTarkov.Server.Core.Services;
|
||||
/// </summary>
|
||||
[Injectable(InjectionType.Singleton)]
|
||||
public class ItemFilterService(
|
||||
ISptLogger<ItemFilterService> _logger,
|
||||
ICloner _cloner,
|
||||
ConfigServer _configServer
|
||||
ISptLogger<ItemFilterService> logger,
|
||||
ICloner cloner,
|
||||
ConfigServer configServer
|
||||
)
|
||||
{
|
||||
protected readonly HashSet<MongoId>? _itemBlacklistCache = [];
|
||||
protected readonly ItemConfig _itemConfig = _configServer.GetConfig<ItemConfig>();
|
||||
protected readonly ItemConfig _itemConfig = configServer.GetConfig<ItemConfig>();
|
||||
|
||||
protected readonly HashSet<MongoId>? _lootableItemBlacklistCache = [];
|
||||
|
||||
@@ -53,7 +53,7 @@ public class ItemFilterService(
|
||||
/// <returns> HashSet of item tpls </returns>
|
||||
public HashSet<MongoId> GetItemRewardBlacklist()
|
||||
{
|
||||
return _cloner.Clone(_itemConfig.RewardItemBlacklist);
|
||||
return cloner.Clone(_itemConfig.RewardItemBlacklist);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -62,7 +62,7 @@ public class ItemFilterService(
|
||||
/// <returns> HashSet of item base ids </returns>
|
||||
public HashSet<MongoId> GetItemRewardBaseTypeBlacklist()
|
||||
{
|
||||
return _cloner.Clone(_itemConfig.RewardItemTypeBlacklist);
|
||||
return cloner.Clone(_itemConfig.RewardItemTypeBlacklist);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -71,7 +71,7 @@ public class ItemFilterService(
|
||||
/// <returns> HashSet of blacklisted template ids </returns>
|
||||
public HashSet<MongoId> GetBlacklistedItems()
|
||||
{
|
||||
return _cloner.Clone(_itemConfig.Blacklist);
|
||||
return cloner.Clone(_itemConfig.Blacklist);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -80,7 +80,7 @@ public class ItemFilterService(
|
||||
/// <returns> HashSet of blacklisted template ids </returns>
|
||||
public HashSet<MongoId> GetBlacklistedLootableItems()
|
||||
{
|
||||
return _cloner.Clone(_itemConfig.LootableItemBlacklist);
|
||||
return cloner.Clone(_itemConfig.LootableItemBlacklist);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -99,7 +99,7 @@ public class ItemFilterService(
|
||||
/// <returns> HashSet of boss item template ids </returns>
|
||||
public HashSet<MongoId> GetBossItems()
|
||||
{
|
||||
return _cloner.Clone(_itemConfig.BossItems).ToHashSet();
|
||||
return cloner.Clone(_itemConfig.BossItems).ToHashSet();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
||||
@@ -8,12 +8,12 @@ namespace SPTarkov.Server.Core.Services;
|
||||
|
||||
[Injectable(InjectionType.Singleton)]
|
||||
public class LocaleService(
|
||||
ISptLogger<LocaleService> _logger,
|
||||
DatabaseServer _databaseServer,
|
||||
ConfigServer _configServer
|
||||
ISptLogger<LocaleService> logger,
|
||||
DatabaseServer databaseServer,
|
||||
ConfigServer configServer
|
||||
)
|
||||
{
|
||||
protected readonly LocaleConfig _localeConfig = _configServer.GetConfig<LocaleConfig>();
|
||||
protected readonly LocaleConfig _localeConfig = configServer.GetConfig<LocaleConfig>();
|
||||
private string _chosenServerLocale = string.Empty;
|
||||
private string _chosenClientLocale = string.Empty;
|
||||
|
||||
@@ -50,7 +50,7 @@ public class LocaleService(
|
||||
{
|
||||
localeToReturn = null;
|
||||
if (
|
||||
!_databaseServer
|
||||
!databaseServer
|
||||
.GetTables()
|
||||
.Locales.Global.TryGetValue(languageKey, out var keyedLocales)
|
||||
)
|
||||
@@ -132,7 +132,7 @@ public class LocaleService(
|
||||
var platformLocale = GetPlatformLocale();
|
||||
if (platformLocale == null)
|
||||
{
|
||||
_logger.Warning("System language not found, falling back to english");
|
||||
logger.Warning("System language not found, falling back to english");
|
||||
return "en";
|
||||
}
|
||||
|
||||
@@ -162,7 +162,7 @@ public class LocaleService(
|
||||
return "pt-pt";
|
||||
}
|
||||
|
||||
_logger.Debug(
|
||||
logger.Debug(
|
||||
$"Unsupported system language found: {baseNameCode}, langCode: {languageCode} falling back to english for server locale"
|
||||
);
|
||||
|
||||
@@ -178,11 +178,11 @@ public class LocaleService(
|
||||
var platformLocale = GetPlatformLocale();
|
||||
if (platformLocale == null)
|
||||
{
|
||||
_logger.Warning("System language not found, falling back to english");
|
||||
logger.Warning("System language not found, falling back to english");
|
||||
return "en";
|
||||
}
|
||||
|
||||
var locales = _databaseServer.GetTables().Locales;
|
||||
var locales = databaseServer.GetTables().Locales;
|
||||
var baseNameCode = platformLocale.TwoLetterISOLanguageName.ToLowerInvariant();
|
||||
if (locales.Global.ContainsKey(baseNameCode))
|
||||
{
|
||||
@@ -218,7 +218,7 @@ public class LocaleService(
|
||||
return "cn";
|
||||
}
|
||||
|
||||
_logger.Debug(
|
||||
logger.Debug(
|
||||
$"Unsupported system language found: {languageCode} baseLocale: {baseNameCode}, falling back to english for client locale"
|
||||
);
|
||||
return "en";
|
||||
|
||||
@@ -19,126 +19,54 @@ using LogLevel = SPTarkov.Server.Core.Models.Spt.Logging.LogLevel;
|
||||
namespace SPTarkov.Server.Core.Services;
|
||||
|
||||
[Injectable(InjectionType.Singleton)]
|
||||
public class LocationLifecycleService
|
||||
public class LocationLifecycleService(
|
||||
ISptLogger<LocationLifecycleService> logger,
|
||||
RewardHelper rewardHelper,
|
||||
ConfigServer configServer,
|
||||
TimeUtil timeUtil,
|
||||
DatabaseService databaseService,
|
||||
ProfileHelper profileHelper,
|
||||
ProfileActivityService profileActivityService,
|
||||
BotNameService botNameService,
|
||||
ICloner cloner,
|
||||
RaidTimeAdjustmentService raidTimeAdjustmentService,
|
||||
LocationLootGenerator locationLootGenerator,
|
||||
ServerLocalisationService serverLocalisationService,
|
||||
BotLootCacheService botLootCacheService,
|
||||
LootGenerator lootGenerator,
|
||||
MailSendService mailSendService,
|
||||
TraderHelper traderHelper,
|
||||
RandomUtil randomUtil,
|
||||
InRaidHelper inRaidHelper,
|
||||
PlayerScavGenerator playerScavGenerator,
|
||||
SaveServer saveServer,
|
||||
HealthHelper healthHelper,
|
||||
PmcChatResponseService pmcChatResponseService,
|
||||
PmcWaveGenerator pmcWaveGenerator,
|
||||
QuestHelper questHelper,
|
||||
InsuranceService insuranceService,
|
||||
MatchBotDetailsCacheService matchBotDetailsCacheService,
|
||||
BtrDeliveryService btrDeliveryService
|
||||
)
|
||||
{
|
||||
protected ProfileActivityService _profileActivityService;
|
||||
protected BotGenerationCacheService _botGenerationCacheService;
|
||||
protected BotLootCacheService _botLootCacheService;
|
||||
protected BotNameService _botNameService;
|
||||
protected ICloner _cloner;
|
||||
protected ConfigServer _configServer;
|
||||
protected DatabaseService _databaseService;
|
||||
protected HealthHelper _healthHelper;
|
||||
protected HideoutConfig _hideoutConfig;
|
||||
protected InRaidConfig _inRaidConfig;
|
||||
protected InRaidHelper _inRaidHelper;
|
||||
protected InsuranceService _insuranceService;
|
||||
protected ServerLocalisationService _serverLocalisationService;
|
||||
protected LocationConfig _locationConfig;
|
||||
protected LocationLootGenerator _locationLootGenerator;
|
||||
protected ISptLogger<LocationLifecycleService> _logger;
|
||||
protected LootGenerator _lootGenerator;
|
||||
protected MailSendService _mailSendService;
|
||||
protected MatchBotDetailsCacheService _matchBotDetailsCacheService;
|
||||
protected PlayerScavGenerator _playerScavGenerator;
|
||||
protected PmcChatResponseService _pmcChatResponseService;
|
||||
protected PmcConfig _pmcConfig;
|
||||
protected PmcWaveGenerator _pmcWaveGenerator;
|
||||
protected ProfileHelper _profileHelper;
|
||||
protected QuestHelper _questHelper;
|
||||
protected RagfairConfig _ragfairConfig;
|
||||
protected RaidTimeAdjustmentService _raidTimeAdjustmentService;
|
||||
protected RandomUtil _randomUtil;
|
||||
protected RewardHelper _rewardHelper;
|
||||
protected SaveServer _saveServer;
|
||||
protected TimeUtil _timeUtil;
|
||||
protected TraderConfig _traderConfig;
|
||||
protected TraderHelper _traderHelper;
|
||||
protected BtrDeliveryService _btrDeliveryService;
|
||||
private readonly CounterTrackerHelper _counterTrackerHelper;
|
||||
|
||||
public LocationLifecycleService(
|
||||
ISptLogger<LocationLifecycleService> logger,
|
||||
RewardHelper rewardHelper,
|
||||
ConfigServer configServer,
|
||||
TimeUtil timeUtil,
|
||||
DatabaseService databaseService,
|
||||
ProfileHelper profileHelper,
|
||||
HashUtil hashUtil,
|
||||
ProfileActivityService profileActivityService,
|
||||
BotGenerationCacheService botGenerationCacheService,
|
||||
BotNameService botNameService,
|
||||
ICloner cloner,
|
||||
RaidTimeAdjustmentService raidTimeAdjustmentService,
|
||||
LocationLootGenerator locationLootGenerator,
|
||||
ServerLocalisationService localisationService,
|
||||
BotLootCacheService botLootCacheService,
|
||||
LootGenerator lootGenerator,
|
||||
MailSendService mailSendService,
|
||||
TraderHelper traderHelper,
|
||||
RandomUtil randomUtil,
|
||||
InRaidHelper inRaidHelper,
|
||||
PlayerScavGenerator playerScavGenerator,
|
||||
SaveServer saveServer,
|
||||
HealthHelper healthHelper,
|
||||
PmcChatResponseService pmcChatResponseService,
|
||||
PmcWaveGenerator pmcWaveGenerator,
|
||||
QuestHelper questHelper,
|
||||
InsuranceService insuranceService,
|
||||
MatchBotDetailsCacheService matchBotDetailsCacheService,
|
||||
BtrDeliveryService btrDeliveryService,
|
||||
CounterTrackerHelper counterTrackerHelper
|
||||
)
|
||||
{
|
||||
_logger = logger;
|
||||
_rewardHelper = rewardHelper;
|
||||
_configServer = configServer;
|
||||
_timeUtil = timeUtil;
|
||||
_databaseService = databaseService;
|
||||
_profileHelper = profileHelper;
|
||||
_profileActivityService = profileActivityService;
|
||||
_botGenerationCacheService = botGenerationCacheService;
|
||||
_botNameService = botNameService;
|
||||
_cloner = cloner;
|
||||
_raidTimeAdjustmentService = raidTimeAdjustmentService;
|
||||
_locationLootGenerator = locationLootGenerator;
|
||||
_serverLocalisationService = localisationService;
|
||||
_botLootCacheService = botLootCacheService;
|
||||
_lootGenerator = lootGenerator;
|
||||
_mailSendService = mailSendService;
|
||||
_traderHelper = traderHelper;
|
||||
_randomUtil = randomUtil;
|
||||
_inRaidHelper = inRaidHelper;
|
||||
_playerScavGenerator = playerScavGenerator;
|
||||
_saveServer = saveServer;
|
||||
_healthHelper = healthHelper;
|
||||
_pmcChatResponseService = pmcChatResponseService;
|
||||
_pmcWaveGenerator = pmcWaveGenerator;
|
||||
_questHelper = questHelper;
|
||||
_insuranceService = insuranceService;
|
||||
_matchBotDetailsCacheService = matchBotDetailsCacheService;
|
||||
_btrDeliveryService = btrDeliveryService;
|
||||
_counterTrackerHelper = counterTrackerHelper;
|
||||
|
||||
_locationConfig = _configServer.GetConfig<LocationConfig>();
|
||||
_inRaidConfig = _configServer.GetConfig<InRaidConfig>();
|
||||
_traderConfig = _configServer.GetConfig<TraderConfig>();
|
||||
_ragfairConfig = _configServer.GetConfig<RagfairConfig>();
|
||||
_hideoutConfig = _configServer.GetConfig<HideoutConfig>();
|
||||
_pmcConfig = _configServer.GetConfig<PmcConfig>();
|
||||
}
|
||||
protected LocationConfig _locationConfig = configServer.GetConfig<LocationConfig>();
|
||||
protected InRaidConfig _inRaidConfig = configServer.GetConfig<InRaidConfig>();
|
||||
protected TraderConfig _traderConfig = configServer.GetConfig<TraderConfig>();
|
||||
protected RagfairConfig _ragfairConfig = configServer.GetConfig<RagfairConfig>();
|
||||
protected HideoutConfig _hideoutConfig = configServer.GetConfig<HideoutConfig>();
|
||||
protected PmcConfig _pmcConfig = configServer.GetConfig<PmcConfig>();
|
||||
|
||||
/// <summary>
|
||||
/// Handle client/match/local/start
|
||||
/// </summary>
|
||||
public virtual StartLocalRaidResponseData StartLocalRaid(
|
||||
string sessionId,
|
||||
MongoId sessionId,
|
||||
StartLocalRaidRequestData request
|
||||
)
|
||||
{
|
||||
_logger.Debug($"Starting: {request.Location}");
|
||||
logger.Debug($"Starting: {request.Location}");
|
||||
|
||||
var playerProfile = _profileHelper.GetFullProfile(sessionId);
|
||||
var playerProfile = profileHelper.GetFullProfile(sessionId);
|
||||
|
||||
// Remove skill fatigue values
|
||||
ResetSkillPointsEarnedDuringRaid(
|
||||
@@ -154,8 +82,8 @@ public class LocationLifecycleService
|
||||
var result = new StartLocalRaidResponseData
|
||||
{
|
||||
// PVE_OFFLINE_xxxxxxxx_27_06_2025_20_20_44
|
||||
ServerId = $"{request.Location}.{request.PlayerSide} {_timeUtil.GetTimeStamp()}", // Only used for metrics in client
|
||||
ServerSettings = _databaseService.GetLocationServices(), // TODO - is this per map or global?
|
||||
ServerId = $"{request.Location}.{request.PlayerSide} {timeUtil.GetTimeStamp()}", // Only used for metrics in client
|
||||
ServerSettings = databaseService.GetLocationServices(), // TODO - is this per map or global?
|
||||
Profile = new ProfileInsuredItems
|
||||
{
|
||||
InsuredItems = playerProfile.CharacterData.PmcData.InsuredItems,
|
||||
@@ -184,13 +112,13 @@ public class LocationLifecycleService
|
||||
}
|
||||
|
||||
// Get data stored at end of previous raid (if any)
|
||||
var transitionData = _profileActivityService
|
||||
var transitionData = profileActivityService
|
||||
.GetProfileActivityRaidData(sessionId)
|
||||
?.LocationTransit;
|
||||
|
||||
if (transitionData is not null)
|
||||
{
|
||||
_logger.Success($"Player: {sessionId} is in transit to {request.Location}");
|
||||
logger.Success($"Player: {sessionId} is in transit to {request.Location}");
|
||||
result.Transition.TransitionType = TransitionType.COMMON;
|
||||
result.Transition.TransitionRaidId = transitionData.TransitionRaidId;
|
||||
result.Transition.TransitionCount += 1;
|
||||
@@ -199,7 +127,7 @@ public class LocationLifecycleService
|
||||
result.Transition.VisitedLocations.Add(transitionData.SptLastVisitedLocation);
|
||||
|
||||
// Complete, clean up as no longer needed
|
||||
_profileActivityService.GetProfileActivityRaidData(sessionId).LocationTransit = null;
|
||||
profileActivityService.GetProfileActivityRaidData(sessionId).LocationTransit = null;
|
||||
}
|
||||
|
||||
// Apply changes from pmcConfig to bot hostility values
|
||||
@@ -208,8 +136,7 @@ public class LocationLifecycleService
|
||||
AdjustExtracts(request.PlayerSide, request.Location, result.LocationLoot);
|
||||
|
||||
// Clear bot cache ready for bot generation call that occurs after this
|
||||
_botGenerationCacheService.ClearStoredBots();
|
||||
_botNameService.ClearNameCache();
|
||||
botNameService.ClearNameCache();
|
||||
|
||||
GC.Collect(GC.MaxGeneration, GCCollectionMode.Aggressive, true, true);
|
||||
|
||||
@@ -231,10 +158,10 @@ public class LocationLifecycleService
|
||||
}
|
||||
|
||||
// Get relevant extract data for map
|
||||
var mapExtracts = _databaseService.GetLocation(location)?.AllExtracts;
|
||||
var mapExtracts = databaseService.GetLocation(location)?.AllExtracts;
|
||||
if (mapExtracts is null)
|
||||
{
|
||||
_logger.Warning($"Unable to find map: {location} extract data, no adjustments made");
|
||||
logger.Warning($"Unable to find map: {location} extract data, no adjustments made");
|
||||
|
||||
return;
|
||||
}
|
||||
@@ -274,7 +201,7 @@ public class LocationLifecycleService
|
||||
// No matching bot in config, skip
|
||||
if (locationBotHostilityDetails is null)
|
||||
{
|
||||
_logger.Warning(
|
||||
logger.Warning(
|
||||
$"No bot: {botId} hostility values found on: {location.Id}, can only edit existing. Skipping"
|
||||
);
|
||||
|
||||
@@ -367,16 +294,16 @@ public class LocationLifecycleService
|
||||
/// <param name="generateLoot"> OPTIONAL - Should loot be generated for the map before being returned </param>
|
||||
/// <returns>LocationBase with loot</returns>
|
||||
public virtual LocationBase GenerateLocationAndLoot(
|
||||
string sessionId,
|
||||
MongoId sessionId,
|
||||
string name,
|
||||
bool generateLoot = true
|
||||
)
|
||||
{
|
||||
var location = _databaseService.GetLocation(name);
|
||||
var locationBaseClone = _cloner.Clone(location.Base);
|
||||
var location = databaseService.GetLocation(name);
|
||||
var locationBaseClone = cloner.Clone(location.Base);
|
||||
|
||||
// Update datetime property to now
|
||||
locationBaseClone.UnixDateTime = _timeUtil.GetTimeStamp();
|
||||
locationBaseClone.UnixDateTime = timeUtil.GetTimeStamp();
|
||||
|
||||
// Don't generate loot for hideout
|
||||
if (string.Equals(name, "hideout", StringComparison.OrdinalIgnoreCase))
|
||||
@@ -391,30 +318,30 @@ public class LocationLifecycleService
|
||||
}
|
||||
|
||||
// Add custom PMCs to map every time its run
|
||||
_pmcWaveGenerator.ApplyWaveChangesToMap(locationBaseClone);
|
||||
pmcWaveGenerator.ApplyWaveChangesToMap(locationBaseClone);
|
||||
|
||||
// Adjust raid values based raid type (e.g. Scav or PMC)
|
||||
LocationConfig? locationConfigClone = null;
|
||||
var raidAdjustments = _profileActivityService
|
||||
var raidAdjustments = profileActivityService
|
||||
.GetProfileActivityRaidData(sessionId)
|
||||
?.RaidAdjustments;
|
||||
if (raidAdjustments is not null)
|
||||
{
|
||||
locationConfigClone = _cloner.Clone(_locationConfig); // Clone values so they can be used to reset originals later
|
||||
_raidTimeAdjustmentService.MakeAdjustmentsToMap(raidAdjustments, locationBaseClone);
|
||||
locationConfigClone = cloner.Clone(_locationConfig); // Clone values so they can be used to reset originals later
|
||||
raidTimeAdjustmentService.MakeAdjustmentsToMap(raidAdjustments, locationBaseClone);
|
||||
}
|
||||
|
||||
// Generate loot for location
|
||||
locationBaseClone.Loot = _locationLootGenerator.GenerateLocationLoot(name);
|
||||
locationBaseClone.Loot = locationLootGenerator.GenerateLocationLoot(name);
|
||||
|
||||
// Reset loot multipliers back to original values
|
||||
if (raidAdjustments is not null && locationConfigClone is not null)
|
||||
{
|
||||
_logger.Debug("Resetting loot multipliers back to their original values");
|
||||
logger.Debug("Resetting loot multipliers back to their original values");
|
||||
_locationConfig.StaticLootMultiplier = locationConfigClone.StaticLootMultiplier;
|
||||
_locationConfig.LooseLootMultiplier = locationConfigClone.LooseLootMultiplier;
|
||||
|
||||
_profileActivityService.GetProfileActivityRaidData(sessionId).RaidAdjustments = null;
|
||||
profileActivityService.GetProfileActivityRaidData(sessionId).RaidAdjustments = null;
|
||||
}
|
||||
|
||||
return locationBaseClone;
|
||||
@@ -423,18 +350,18 @@ public class LocationLifecycleService
|
||||
/// <summary>
|
||||
/// Handle client/match/local/end
|
||||
/// </summary>
|
||||
public virtual void EndLocalRaid(string sessionId, EndLocalRaidRequestData request)
|
||||
public virtual void EndLocalRaid(MongoId sessionId, EndLocalRaidRequestData request)
|
||||
{
|
||||
// Clear bot loot cache
|
||||
_botLootCacheService.ClearCache();
|
||||
botLootCacheService.ClearCache();
|
||||
|
||||
var fullProfile = _profileHelper.GetFullProfile(sessionId);
|
||||
var fullProfile = profileHelper.GetFullProfile(sessionId);
|
||||
var pmcProfile = fullProfile.CharacterData.PmcData;
|
||||
var scavProfile = fullProfile.CharacterData.ScavData;
|
||||
|
||||
if (_logger.IsLogEnabled(LogLevel.Debug))
|
||||
if (logger.IsLogEnabled(LogLevel.Debug))
|
||||
{
|
||||
_logger.Debug($"Raid: {request.ServerId} outcome: {request.Results.Result}");
|
||||
logger.Debug($"Raid: {request.ServerId} outcome: {request.Results.Result}");
|
||||
}
|
||||
|
||||
// Reset flea interval time to out-of-raid value
|
||||
@@ -451,7 +378,7 @@ public class LocationLifecycleService
|
||||
var isSurvived = IsPlayerSurvived(request.Results);
|
||||
|
||||
// Handle items transferred via BTR or transit to player mailbox
|
||||
_btrDeliveryService.HandleItemTransferEvent(sessionId, request);
|
||||
btrDeliveryService.HandleItemTransferEvent(sessionId, request);
|
||||
|
||||
// Player is moving between maps
|
||||
if (isTransfer && request.LocationTransit is not null)
|
||||
@@ -461,7 +388,7 @@ public class LocationLifecycleService
|
||||
// TODO - Persist each players last visited location history over multiple transits, e.g. using InMemoryCacheService, need to take care to not let data get stored forever
|
||||
// Store transfer data for later use in `startLocalRaid()` when next raid starts
|
||||
request.LocationTransit.SptExitName = request.Results.ExitName;
|
||||
_profileActivityService.GetProfileActivityRaidData(sessionId).LocationTransit =
|
||||
profileActivityService.GetProfileActivityRaidData(sessionId).LocationTransit =
|
||||
request.LocationTransit;
|
||||
}
|
||||
|
||||
@@ -513,10 +440,10 @@ public class LocationLifecycleService
|
||||
/// After taking a COOP extract, send player a gift via mail
|
||||
/// </summary>
|
||||
/// <param name="sessionId">Player/Session id</param>
|
||||
protected void SendCoopTakenFenceMessage(string sessionId)
|
||||
protected void SendCoopTakenFenceMessage(MongoId sessionId)
|
||||
{
|
||||
// Generate randomised reward for taking coop extract
|
||||
var loot = _lootGenerator.CreateRandomLoot(_traderConfig.Fence.CoopExtractGift);
|
||||
var loot = lootGenerator.CreateRandomLoot(_traderConfig.Fence.CoopExtractGift);
|
||||
|
||||
var parentId = new MongoId();
|
||||
foreach (var itemAndChildren in loot)
|
||||
@@ -529,13 +456,13 @@ public class LocationLifecycleService
|
||||
List<Item> mailableLoot = [.. loot.SelectMany(x => x)];
|
||||
|
||||
// Send message from fence giving player reward generated above
|
||||
_mailSendService.SendLocalisedNpcMessageToPlayer(
|
||||
mailSendService.SendLocalisedNpcMessageToPlayer(
|
||||
sessionId,
|
||||
Traders.FENCE,
|
||||
MessageType.MessageWithItems,
|
||||
_randomUtil.GetArrayValue(_traderConfig.Fence.CoopExtractGift.MessageLocaleIds),
|
||||
randomUtil.GetArrayValue(_traderConfig.Fence.CoopExtractGift.MessageLocaleIds),
|
||||
mailableLoot,
|
||||
_timeUtil.GetHoursAsSeconds(_traderConfig.Fence.CoopExtractGift.GiftExpiryHours)
|
||||
timeUtil.GetHoursAsSeconds(_traderConfig.Fence.CoopExtractGift.GiftExpiryHours)
|
||||
);
|
||||
}
|
||||
|
||||
@@ -566,7 +493,7 @@ public class LocationLifecycleService
|
||||
/// <param name="extractName"> Name of the extract used </param>
|
||||
/// <param name="pmcData"> Player profile </param>
|
||||
/// <param name="sessionId"> Session ID </param>
|
||||
protected void HandleCarExtract(string extractName, PmcData pmcData, string sessionId)
|
||||
protected void HandleCarExtract(string extractName, PmcData pmcData, MongoId sessionId)
|
||||
{
|
||||
pmcData.CarExtractCounts?.TryAdd(extractName, 0);
|
||||
|
||||
@@ -583,18 +510,18 @@ public class LocationLifecycleService
|
||||
pmcData.TradersInfo[fenceId].Standing = newFenceStanding;
|
||||
|
||||
// Check if new standing has leveled up trader
|
||||
_traderHelper.LevelUp(fenceId, pmcData);
|
||||
traderHelper.LevelUp(fenceId, pmcData);
|
||||
pmcData.TradersInfo[fenceId].LoyaltyLevel = Math.Max(
|
||||
(int)pmcData.TradersInfo[fenceId].LoyaltyLevel,
|
||||
1
|
||||
);
|
||||
|
||||
_logger.Debug(
|
||||
logger.Debug(
|
||||
$"Car extract: {extractName} used, total times taken: {pmcData.CarExtractCounts[extractName]}"
|
||||
);
|
||||
|
||||
// Copy updated fence rep values into scav profile to ensure consistency
|
||||
var scavData = _profileHelper.GetScavProfile(sessionId);
|
||||
var scavData = profileHelper.GetScavProfile(sessionId);
|
||||
scavData.TradersInfo[fenceId].Standing = pmcData.TradersInfo[fenceId].Standing;
|
||||
scavData.TradersInfo[fenceId].LoyaltyLevel = pmcData.TradersInfo[fenceId].LoyaltyLevel;
|
||||
}
|
||||
@@ -605,7 +532,7 @@ public class LocationLifecycleService
|
||||
/// <param name="sessionId"> Session/player id </param>
|
||||
/// <param name="pmcData"> Player profile </param>
|
||||
/// <param name="extractName"> Name of extract taken </param>
|
||||
protected void HandleCoopExtract(string sessionId, PmcData pmcData, string extractName)
|
||||
protected void HandleCoopExtract(MongoId sessionId, PmcData pmcData, string extractName)
|
||||
{
|
||||
pmcData.CoopExtractCounts?.TryAdd(extractName, 0);
|
||||
|
||||
@@ -621,16 +548,16 @@ public class LocationLifecycleService
|
||||
pmcData.TradersInfo[fenceId].Standing = newFenceStanding;
|
||||
|
||||
// Check if new standing has leveled up trader
|
||||
_traderHelper.LevelUp(fenceId, pmcData);
|
||||
traderHelper.LevelUp(fenceId, pmcData);
|
||||
pmcData.TradersInfo[fenceId].LoyaltyLevel = Math.Max(
|
||||
(int)pmcData.TradersInfo[fenceId].LoyaltyLevel,
|
||||
1
|
||||
);
|
||||
|
||||
_logger.Debug($"COOP extract: {extractName} used");
|
||||
logger.Debug($"COOP extract: {extractName} used");
|
||||
|
||||
// Copy updated fence rep values into scav profile to ensure consistency
|
||||
var scavData = _profileHelper.GetScavProfile(sessionId);
|
||||
var scavData = profileHelper.GetScavProfile(sessionId);
|
||||
scavData.TradersInfo[fenceId].Standing = pmcData.TradersInfo[fenceId].Standing;
|
||||
scavData.TradersInfo[fenceId].LoyaltyLevel = pmcData.TradersInfo[fenceId].LoyaltyLevel;
|
||||
}
|
||||
@@ -656,7 +583,7 @@ public class LocationLifecycleService
|
||||
|
||||
// Ensure fence loyalty level is not above/below the range -7 to 15
|
||||
var newFenceStanding = Math.Min(Math.Max((double)fenceStanding, -7), 15);
|
||||
_logger.Debug(
|
||||
logger.Debug(
|
||||
$"Old vs new fence standing: {pmcData.TradersInfo[fenceId].Standing}, {newFenceStanding}"
|
||||
);
|
||||
|
||||
@@ -690,7 +617,7 @@ public class LocationLifecycleService
|
||||
/// <param name="isSurvived">DId player get 'survived' exit status</param>
|
||||
/// <param name="request">End raid request</param>
|
||||
protected void HandlePostRaidPlayerScav(
|
||||
string sessionId,
|
||||
MongoId sessionId,
|
||||
PmcData pmcProfile,
|
||||
PmcData scavProfile,
|
||||
bool isDead,
|
||||
@@ -711,7 +638,7 @@ public class LocationLifecycleService
|
||||
|
||||
// We want scav inventory to persist into next raid when pscav is moving between maps
|
||||
// Also adjust FiR status when exit was runthrough
|
||||
_inRaidHelper.SetInventory(
|
||||
inRaidHelper.SetInventory(
|
||||
sessionId,
|
||||
scavProfile,
|
||||
postRaidProfile,
|
||||
@@ -742,7 +669,7 @@ public class LocationLifecycleService
|
||||
var fenceMin = _traderConfig.Fence.PlayerRepMin; //-7
|
||||
if (!postRaidProfile.TradersInfo.TryGetValue(Traders.FENCE, out var postRaidFenceData))
|
||||
{
|
||||
_logger.Error($"post raid fence data not found for: {sessionId}");
|
||||
logger.Error($"post raid fence data not found for: {sessionId}");
|
||||
}
|
||||
|
||||
scavProfile.TradersInfo[Traders.FENCE].Standing = Math.Min(
|
||||
@@ -775,14 +702,14 @@ public class LocationLifecycleService
|
||||
// Scav died, regen scav loadout and reset timer
|
||||
if (isDead)
|
||||
{
|
||||
_playerScavGenerator.Generate(sessionId);
|
||||
playerScavGenerator.Generate(sessionId);
|
||||
}
|
||||
|
||||
// Update last played property
|
||||
pmcProfile.Info.LastTimePlayedAsSavage = _timeUtil.GetTimeStamp();
|
||||
pmcProfile.Info.LastTimePlayedAsSavage = timeUtil.GetTimeStamp();
|
||||
|
||||
// Force a profile save
|
||||
_saveServer.SaveProfileAsync(sessionId);
|
||||
saveServer.SaveProfileAsync(sessionId);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -797,8 +724,8 @@ public class LocationLifecycleService
|
||||
var pmcQuest = pmcProfile.Quests.FirstOrDefault(quest => quest.QId == scavQuest.QId);
|
||||
if (pmcQuest is null)
|
||||
{
|
||||
_logger.Warning(
|
||||
_serverLocalisationService.GetText(
|
||||
logger.Warning(
|
||||
serverLocalisationService.GetText(
|
||||
"inraid-unable_to_migrate_pmc_quest_not_found_in_profile",
|
||||
scavQuest.QId
|
||||
)
|
||||
@@ -838,7 +765,7 @@ public class LocationLifecycleService
|
||||
var transitSettings = _locationConfig.TransitSettings;
|
||||
if (transitSettings == null)
|
||||
{
|
||||
_logger.Warning("Unable to find: _locationConfig.TransitSettings");
|
||||
logger.Warning("Unable to find: _locationConfig.TransitSettings");
|
||||
|
||||
return;
|
||||
}
|
||||
@@ -852,7 +779,7 @@ public class LocationLifecycleService
|
||||
)
|
||||
{
|
||||
// Limb has been destroyed, reset
|
||||
hpValues.Health.Current = _randomUtil.GetPercentOfValue(
|
||||
hpValues.Health.Current = randomUtil.GetPercentOfValue(
|
||||
transitSettings.LimbHealPercent.GetValueOrDefault(30),
|
||||
hpValues.Health.Maximum.Value
|
||||
);
|
||||
@@ -888,7 +815,7 @@ public class LocationLifecycleService
|
||||
/// <param name="request"> Client request data </param>
|
||||
/// <param name="locationName"> Current finished Raid location </param>
|
||||
protected void HandlePostRaidPmc(
|
||||
string sessionId,
|
||||
MongoId sessionId,
|
||||
SptProfile fullServerProfile,
|
||||
PmcData scavProfile,
|
||||
bool isDead,
|
||||
@@ -900,14 +827,14 @@ public class LocationLifecycleService
|
||||
{
|
||||
var serverPmcProfile = fullServerProfile.CharacterData.PmcData;
|
||||
var postRaidProfile = request.Results.Profile;
|
||||
var preRaidProfileQuestDataClone = _cloner.Clone(serverPmcProfile.Quests);
|
||||
var preRaidProfileQuestDataClone = cloner.Clone(serverPmcProfile.Quests);
|
||||
|
||||
// MUST occur BEFORE inventory actions (setInventory()) occur
|
||||
// Player died, get quest items they lost for use later
|
||||
var lostQuestItems = postRaidProfile.GetQuestItemsInProfile();
|
||||
|
||||
// Update inventory
|
||||
_inRaidHelper.SetInventory(
|
||||
inRaidHelper.SetInventory(
|
||||
sessionId,
|
||||
serverPmcProfile,
|
||||
postRaidProfile,
|
||||
@@ -961,7 +888,7 @@ public class LocationLifecycleService
|
||||
MergePmcAndScavEncyclopedias(serverPmcProfile, scavProfile);
|
||||
|
||||
// Handle temp, hydration, limb hp/effects
|
||||
_healthHelper.ApplyHealthChangesToProfile(
|
||||
healthHelper.ApplyHealthChangesToProfile(
|
||||
sessionId,
|
||||
serverPmcProfile,
|
||||
postRaidProfile.Health,
|
||||
@@ -994,16 +921,16 @@ public class LocationLifecycleService
|
||||
{
|
||||
// get the aggressor ID from the client request body
|
||||
postRaidProfile.Stats.Eft.Aggressor.ProfileId = request.Results.KillerId;
|
||||
_pmcChatResponseService.SendKillerResponse(
|
||||
pmcChatResponseService.SendKillerResponse(
|
||||
sessionId,
|
||||
serverPmcProfile,
|
||||
postRaidProfile.Stats.Eft.Aggressor
|
||||
);
|
||||
}
|
||||
|
||||
_inRaidHelper.DeleteInventory(serverPmcProfile, sessionId);
|
||||
inRaidHelper.DeleteInventory(serverPmcProfile, sessionId);
|
||||
|
||||
_inRaidHelper.RemoveFiRStatusFromItemsInContainer(
|
||||
inRaidHelper.RemoveFiRStatusFromItemsInContainer(
|
||||
sessionId,
|
||||
serverPmcProfile,
|
||||
"SecuredContainer"
|
||||
@@ -1011,7 +938,7 @@ public class LocationLifecycleService
|
||||
}
|
||||
|
||||
// Must occur AFTER killer messages have been sent
|
||||
_matchBotDetailsCacheService.ClearCache();
|
||||
matchBotDetailsCacheService.ClearCache();
|
||||
|
||||
var roles = new List<string> { "pmcbear", "pmcusec" };
|
||||
|
||||
@@ -1021,7 +948,7 @@ public class LocationLifecycleService
|
||||
if (victims?.Count > 0)
|
||||
// Player killed PMCs, send some mail responses to them
|
||||
{
|
||||
_pmcChatResponseService.SendVictimResponse(sessionId, victims, serverPmcProfile);
|
||||
pmcChatResponseService.SendVictimResponse(sessionId, victims, serverPmcProfile);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1033,7 +960,7 @@ public class LocationLifecycleService
|
||||
/// <param name="lostQuestItems"> Quest items lost on player death </param>
|
||||
/// <param name="profileQuests"> Quest status data from player profile </param>
|
||||
protected void CheckForAndFixPickupQuestsAfterDeath(
|
||||
string sessionId,
|
||||
MongoId sessionId,
|
||||
List<Item> lostQuestItems,
|
||||
List<QuestStatus> profileQuests
|
||||
)
|
||||
@@ -1048,7 +975,7 @@ public class LocationLifecycleService
|
||||
.Select(status => status.QId);
|
||||
|
||||
// Get db details of quests we found above
|
||||
var questDb = _databaseService
|
||||
var questDb = databaseService
|
||||
.GetQuests()
|
||||
.Values.Where(quest => activeQuestIdsInProfile.Contains(quest.Id));
|
||||
|
||||
@@ -1083,7 +1010,7 @@ public class LocationLifecycleService
|
||||
// Fail if multiple were found
|
||||
if (matchingQuests.Count != 1)
|
||||
{
|
||||
_logger.Error(
|
||||
logger.Error(
|
||||
$"Unable to fix quest item: {lostItem}, {matchingQuests.Count} matching quests found, expected 1"
|
||||
);
|
||||
|
||||
@@ -1118,7 +1045,7 @@ public class LocationLifecycleService
|
||||
/// <param name="preRaidQuests"> Quest statuses pre-raid </param>
|
||||
/// <param name="pmcProfile"> Players profile </param>
|
||||
protected void LightkeeperQuestWorkaround(
|
||||
string sessionId,
|
||||
MongoId sessionId,
|
||||
List<QuestStatus> postRaidQuests,
|
||||
List<QuestStatus> preRaidQuests,
|
||||
PmcData pmcProfile
|
||||
@@ -1135,7 +1062,7 @@ public class LocationLifecycleService
|
||||
preRaidQuest.Status != QuestStatusEnum.Success
|
||||
)
|
||||
&& // Completed quest was not completed before raid started
|
||||
_databaseService.GetQuests().TryGetValue(postRaidQuest.QId, out var quest)
|
||||
databaseService.GetQuests().TryGetValue(postRaidQuest.QId, out var quest)
|
||||
&& quest?.TraderId == Traders.LIGHTHOUSEKEEPER
|
||||
) // Quest is from LK
|
||||
.ToList();
|
||||
@@ -1143,7 +1070,7 @@ public class LocationLifecycleService
|
||||
// Run server complete quest process to ensure player gets rewards
|
||||
foreach (var questToComplete in newlyCompletedLightkeeperQuests)
|
||||
{
|
||||
_questHelper.CompleteQuest(
|
||||
questHelper.CompleteQuest(
|
||||
pmcProfile,
|
||||
new CompleteQuestRequestData
|
||||
{
|
||||
@@ -1169,7 +1096,7 @@ public class LocationLifecycleService
|
||||
);
|
||||
foreach (var failedQuest in failedQuests)
|
||||
{
|
||||
var dbQuest = _databaseService.GetQuests()[failedQuest.QId];
|
||||
var dbQuest = databaseService.GetQuests()[failedQuest.QId];
|
||||
if (dbQuest is null)
|
||||
{
|
||||
continue;
|
||||
@@ -1216,7 +1143,7 @@ public class LocationLifecycleService
|
||||
}
|
||||
|
||||
protected void HandleInsuredItemLostEvent(
|
||||
string sessionId,
|
||||
MongoId sessionId,
|
||||
PmcData preRaidPmcProfile,
|
||||
EndLocalRaidRequestData request,
|
||||
string locationName
|
||||
@@ -1224,7 +1151,7 @@ public class LocationLifecycleService
|
||||
{
|
||||
if (request.LostInsuredItems?.Count > 0)
|
||||
{
|
||||
var mappedItems = _insuranceService.MapInsuredItemsToTrader(
|
||||
var mappedItems = insuranceService.MapInsuredItemsToTrader(
|
||||
sessionId,
|
||||
request.LostInsuredItems,
|
||||
preRaidPmcProfile
|
||||
@@ -1236,9 +1163,9 @@ public class LocationLifecycleService
|
||||
return;
|
||||
}
|
||||
|
||||
_insuranceService.StoreGearLostInRaidToSendLater(sessionId, mappedItems);
|
||||
insuranceService.StoreGearLostInRaidToSendLater(sessionId, mappedItems);
|
||||
|
||||
_insuranceService.StartPostRaidInsuranceLostProcess(
|
||||
insuranceService.StartPostRaidInsuranceLostProcess(
|
||||
preRaidPmcProfile,
|
||||
sessionId,
|
||||
locationName
|
||||
@@ -1330,7 +1257,7 @@ public class LocationLifecycleService
|
||||
);
|
||||
|
||||
// Get achievement data from db
|
||||
var achievementsDb = _databaseService.GetTemplates().Achievements;
|
||||
var achievementsDb = databaseService.GetTemplates().Achievements;
|
||||
|
||||
// Map the achievement ids player obtained in raid with matching achievement data from db
|
||||
var achievements = achievementIdsAcquiredThisRaid.Select(achievementId =>
|
||||
@@ -1344,7 +1271,7 @@ public class LocationLifecycleService
|
||||
|
||||
foreach (var achievement in achievements)
|
||||
{
|
||||
var rewardItems = _rewardHelper.ApplyRewards(
|
||||
var rewardItems = rewardHelper.ApplyRewards(
|
||||
achievement.Rewards,
|
||||
CustomisationSource.ACHIEVEMENT,
|
||||
fullProfile,
|
||||
@@ -1354,12 +1281,12 @@ public class LocationLifecycleService
|
||||
|
||||
if (rewardItems?.Count > 0)
|
||||
{
|
||||
_mailSendService.SendLocalisedSystemMessageToPlayer(
|
||||
sessionId,
|
||||
mailSendService.SendLocalisedSystemMessageToPlayer(
|
||||
sessionId.Value,
|
||||
"670547bb5fa0b1a7c30d5836 0",
|
||||
rewardItems,
|
||||
[],
|
||||
_timeUtil.GetHoursAsSeconds(24 * 7)
|
||||
timeUtil.GetHoursAsSeconds(24 * 7)
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -16,16 +16,16 @@ namespace SPTarkov.Server.Core.Services;
|
||||
|
||||
[Injectable]
|
||||
public class MailSendService(
|
||||
ISptLogger<MailSendService> _logger,
|
||||
TimeUtil _timeUtil,
|
||||
SaveServer _saveServer,
|
||||
DatabaseService _databaseService,
|
||||
NotifierHelper _notifierHelper,
|
||||
DialogueHelper _dialogueHelper,
|
||||
NotificationSendHelper _notificationSendHelper,
|
||||
ServerLocalisationService _serverLocalisationService,
|
||||
ItemHelper _itemHelper,
|
||||
ICloner _cloner
|
||||
ISptLogger<MailSendService> logger,
|
||||
TimeUtil timeUtil,
|
||||
SaveServer saveServer,
|
||||
DatabaseService databaseService,
|
||||
NotifierHelper notifierHelper,
|
||||
DialogueHelper dialogueHelper,
|
||||
NotificationSendHelper notificationSendHelper,
|
||||
ServerLocalisationService serverLocalisationService,
|
||||
ItemHelper itemHelper,
|
||||
ICloner cloner
|
||||
)
|
||||
{
|
||||
private const string _systemSenderId = "59e7125688a45068a6249071";
|
||||
@@ -48,7 +48,7 @@ public class MailSendService(
|
||||
/// <param name="systemData"> </param>
|
||||
/// <param name="ragfair"> </param>
|
||||
public void SendDirectNpcMessageToPlayer(
|
||||
string sessionId,
|
||||
MongoId sessionId,
|
||||
string? trader,
|
||||
MessageType messageType,
|
||||
string message,
|
||||
@@ -60,8 +60,8 @@ public class MailSendService(
|
||||
{
|
||||
if (trader is null)
|
||||
{
|
||||
_logger.Error(
|
||||
_serverLocalisationService.GetText(
|
||||
logger.Error(
|
||||
serverLocalisationService.GetText(
|
||||
"mailsend-missing_trader",
|
||||
new { messageType, sessionId }
|
||||
)
|
||||
@@ -112,7 +112,7 @@ public class MailSendService(
|
||||
/// <param name="systemData"></param>
|
||||
/// <param name="ragfair"></param>
|
||||
public void SendLocalisedNpcMessageToPlayer(
|
||||
string sessionId,
|
||||
MongoId sessionId,
|
||||
string? trader,
|
||||
MessageType messageType,
|
||||
string messageLocaleId,
|
||||
@@ -124,8 +124,8 @@ public class MailSendService(
|
||||
{
|
||||
if (trader is null)
|
||||
{
|
||||
_logger.Error(
|
||||
_serverLocalisationService.GetText(
|
||||
logger.Error(
|
||||
serverLocalisationService.GetText(
|
||||
"mailsend-missing_trader",
|
||||
new { messageType, sessionId }
|
||||
)
|
||||
@@ -175,7 +175,7 @@ public class MailSendService(
|
||||
/// <param name="maxStorageTimeSeconds"> Optional time to collect items before they expire </param>
|
||||
/// <param name="profileChangeEvents"></param>
|
||||
public void SendSystemMessageToPlayer(
|
||||
string sessionId,
|
||||
MongoId sessionId,
|
||||
string message,
|
||||
List<Item>? items,
|
||||
long? maxStorageTimeSeconds = 172800,
|
||||
@@ -216,7 +216,7 @@ public class MailSendService(
|
||||
/// <param name="profileChangeEvents"></param>
|
||||
/// <param name="maxStorageTimeSeconds"> Optional time to collect items before they expire </param>
|
||||
public void SendLocalisedSystemMessageToPlayer(
|
||||
string sessionId,
|
||||
MongoId sessionId,
|
||||
string messageLocaleId,
|
||||
List<Item>? items,
|
||||
List<ProfileChangeEvent>? profileChangeEvents,
|
||||
@@ -255,7 +255,7 @@ public class MailSendService(
|
||||
/// <param name="items"> Optional items to send to player </param>
|
||||
/// <param name="maxStorageTimeSeconds"> Optional time to collect items before they expire </param>
|
||||
public void SendUserMessageToPlayer(
|
||||
string sessionId,
|
||||
MongoId sessionId,
|
||||
UserDialogInfo senderDetails,
|
||||
string message,
|
||||
List<Item>? items = null,
|
||||
@@ -329,17 +329,17 @@ public class MailSendService(
|
||||
&& messageDetails?.RagfairDetails is not null
|
||||
)
|
||||
{
|
||||
var offerSoldMessage = _notifierHelper.CreateRagfairOfferSoldNotification(
|
||||
var offerSoldMessage = notifierHelper.CreateRagfairOfferSoldNotification(
|
||||
message,
|
||||
messageDetails.RagfairDetails
|
||||
);
|
||||
_notificationSendHelper.SendMessage(messageDetails.RecipientId, offerSoldMessage);
|
||||
notificationSendHelper.SendMessage(messageDetails.RecipientId, offerSoldMessage);
|
||||
message.MessageType = MessageType.MessageWithItems; // Should prevent getting the same notification popup twice
|
||||
}
|
||||
|
||||
// Send message off to player so they get it in client
|
||||
var notificationMessage = _notifierHelper.CreateNewMessageNotification(message);
|
||||
_notificationSendHelper.SendMessage(messageDetails.RecipientId, notificationMessage);
|
||||
var notificationMessage = notifierHelper.CreateNewMessageNotification(message);
|
||||
notificationSendHelper.SendMessage(messageDetails.RecipientId, notificationMessage);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -348,16 +348,16 @@ public class MailSendService(
|
||||
/// <param name="sessionId"> Session ID </param>
|
||||
/// <param name="targetNpcId"> NPC message is sent to </param>
|
||||
/// <param name="message"> Text to send to NPC </param>
|
||||
public void SendPlayerMessageToNpc(string sessionId, string targetNpcId, string message)
|
||||
public void SendPlayerMessageToNpc(MongoId sessionId, string targetNpcId, string message)
|
||||
{
|
||||
var playerProfile = _saveServer.GetProfile(sessionId);
|
||||
var playerProfile = saveServer.GetProfile(sessionId);
|
||||
if (
|
||||
playerProfile.DialogueRecords is null
|
||||
|| !playerProfile.DialogueRecords.TryGetValue(targetNpcId, out var dialogWithNpc)
|
||||
)
|
||||
{
|
||||
_logger.Error(
|
||||
_serverLocalisationService.GetText("mailsend-missing_npc_dialog", targetNpcId)
|
||||
logger.Error(
|
||||
serverLocalisationService.GetText("mailsend-missing_npc_dialog", targetNpcId)
|
||||
);
|
||||
return;
|
||||
}
|
||||
@@ -366,7 +366,7 @@ public class MailSendService(
|
||||
new Message
|
||||
{
|
||||
Id = new MongoId(),
|
||||
DateTime = _timeUtil.GetTimeStamp(),
|
||||
DateTime = timeUtil.GetTimeStamp(),
|
||||
HasRewards = false,
|
||||
UserId = playerProfile.CharacterData.PmcData.Id,
|
||||
MessageType = MessageType.UserMessage,
|
||||
@@ -389,7 +389,7 @@ public class MailSendService(
|
||||
Id = new MongoId(),
|
||||
UserId = dialogId,
|
||||
MessageType = messageDetails.Sender,
|
||||
DateTime = _timeUtil.GetTimeStamp(),
|
||||
DateTime = timeUtil.GetTimeStamp(),
|
||||
Text = messageDetails.TemplateId is not null ? "" : messageDetails.MessageText,
|
||||
TemplateId = messageDetails.TemplateId,
|
||||
HasRewards = false,
|
||||
@@ -427,11 +427,11 @@ public class MailSendService(
|
||||
/// <returns> A new instance with data from the found message, otherwise undefined </returns>
|
||||
protected ReplyTo? GetMessageToReplyTo(string recipientId, string replyToId, string dialogueId)
|
||||
{
|
||||
var currentDialogue = _dialogueHelper.GetDialogueFromProfile(recipientId, dialogueId);
|
||||
var currentDialogue = dialogueHelper.GetDialogueFromProfile(recipientId, dialogueId);
|
||||
|
||||
if (currentDialogue is null)
|
||||
{
|
||||
_logger.Warning($"Unable to find dialogue: {dialogueId} from sender");
|
||||
logger.Warning($"Unable to find dialogue: {dialogueId} from sender");
|
||||
return null;
|
||||
}
|
||||
|
||||
@@ -485,7 +485,7 @@ public class MailSendService(
|
||||
SendMessageDetails messageDetails
|
||||
)
|
||||
{
|
||||
var items = _databaseService.GetItems();
|
||||
var items = databaseService.GetItems();
|
||||
|
||||
MessageItems itemsToSendToPlayer = new();
|
||||
if ((messageDetails.Items?.Count ?? 0) > 0)
|
||||
@@ -494,7 +494,7 @@ public class MailSendService(
|
||||
var parentItem = GetBaseItemFromRewards(messageDetails.Items);
|
||||
if (parentItem is null)
|
||||
{
|
||||
_serverLocalisationService.GetText(
|
||||
serverLocalisationService.GetText(
|
||||
"mailsend-missing_parent",
|
||||
new { traderId = messageDetails.Trader, sender = messageDetails.Sender }
|
||||
);
|
||||
@@ -516,7 +516,7 @@ public class MailSendService(
|
||||
};
|
||||
|
||||
// Ensure Ids are unique and cont collide with items in player inventory later
|
||||
messageDetails.Items = _cloner.Clone(messageDetails.Items).ReplaceIDs().ToList();
|
||||
messageDetails.Items = cloner.Clone(messageDetails.Items).ReplaceIDs().ToList();
|
||||
|
||||
// Ensure item exits in items db
|
||||
foreach (var reward in messageDetails.Items)
|
||||
@@ -524,8 +524,8 @@ public class MailSendService(
|
||||
var itemTemplate = items[reward.Template];
|
||||
if (itemTemplate is null)
|
||||
{
|
||||
_logger.Error(
|
||||
_serverLocalisationService.GetText(
|
||||
logger.Error(
|
||||
serverLocalisationService.GetText(
|
||||
"dialog-missing_item_template",
|
||||
new { tpl = reward.Template, type = dialogType }
|
||||
)
|
||||
@@ -547,7 +547,7 @@ public class MailSendService(
|
||||
}
|
||||
|
||||
// Boxes can contain sub-items
|
||||
if (_itemHelper.IsOfBaseclass(itemTemplate.Id, BaseClasses.AMMO_BOX))
|
||||
if (itemHelper.IsOfBaseclass(itemTemplate.Id, BaseClasses.AMMO_BOX))
|
||||
{
|
||||
// look for child cartridge objects
|
||||
var childItems = messageDetails.Items?.Where(x => x.ParentId == reward.Id);
|
||||
@@ -555,7 +555,7 @@ public class MailSendService(
|
||||
{
|
||||
// No cartridges found, generate and add to rewards
|
||||
var boxAndCartridges = new List<Item> { reward };
|
||||
_itemHelper.AddCartridgesToAmmoBox(boxAndCartridges, itemTemplate);
|
||||
itemHelper.AddCartridgesToAmmoBox(boxAndCartridges, itemTemplate);
|
||||
|
||||
// Push box + cartridge children into array
|
||||
itemsToSendToPlayer.Data.AddRange(boxAndCartridges);
|
||||
@@ -570,8 +570,8 @@ public class MailSendService(
|
||||
{
|
||||
if (itemTemplate.Properties.StackSlots is not null)
|
||||
{
|
||||
_logger.Error(
|
||||
_serverLocalisationService.GetText(
|
||||
logger.Error(
|
||||
serverLocalisationService.GetText(
|
||||
"mail-unable_to_give_gift_not_handled",
|
||||
itemTemplate.Id
|
||||
)
|
||||
@@ -636,14 +636,14 @@ public class MailSendService(
|
||||
if (senderId is null)
|
||||
{
|
||||
throw new Exception(
|
||||
_serverLocalisationService.GetText(
|
||||
serverLocalisationService.GetText(
|
||||
"mail-unable_to_find_message_sender_by_id",
|
||||
messageDetails.Sender
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
var dialogsInProfile = _dialogueHelper.GetDialogsForProfile(messageDetails.RecipientId);
|
||||
var dialogsInProfile = dialogueHelper.GetDialogsForProfile(messageDetails.RecipientId);
|
||||
|
||||
// Does dialog exist
|
||||
if (!dialogsInProfile.ContainsKey(senderId))
|
||||
@@ -680,9 +680,9 @@ public class MailSendService(
|
||||
|| messageDetails.DialogType == MessageType.NpcTraderMessage
|
||||
)
|
||||
{
|
||||
if (messageDetails.Trader == null && _logger.IsLogEnabled(LogLevel.Debug))
|
||||
if (messageDetails.Trader == null && logger.IsLogEnabled(LogLevel.Debug))
|
||||
{
|
||||
_logger.Debug($"Trader was null for {messageDetails.TemplateId}");
|
||||
logger.Debug($"Trader was null for {messageDetails.TemplateId}");
|
||||
}
|
||||
|
||||
return messageDetails.Trader;
|
||||
@@ -703,7 +703,7 @@ public class MailSendService(
|
||||
return messageDetails.Trader;
|
||||
}
|
||||
|
||||
_logger.Warning($"Unable to handle message of type: {messageDetails.Sender}");
|
||||
logger.Warning($"Unable to handle message of type: {messageDetails.Sender}");
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -8,7 +8,7 @@ using SPTarkov.Server.Core.Models.Utils;
|
||||
namespace SPTarkov.Server.Core.Services;
|
||||
|
||||
[Injectable]
|
||||
public class MapMarkerService(ISptLogger<MapMarkerService> _logger)
|
||||
public class MapMarkerService(ISptLogger<MapMarkerService> logger)
|
||||
{
|
||||
/// <summary>
|
||||
/// Add note to a map item in player inventory
|
||||
@@ -74,7 +74,7 @@ public class MapMarkerService(ISptLogger<MapMarkerService> _logger)
|
||||
|
||||
if (markerToRemove is null)
|
||||
{
|
||||
_logger.Warning($"No marker found for item {request.Item}");
|
||||
logger.Warning($"No marker found for item {request.Item}");
|
||||
return null;
|
||||
}
|
||||
|
||||
|
||||
@@ -12,7 +12,7 @@ namespace SPTarkov.Server.Core.Services;
|
||||
/// Cache bots in a dictionary, keyed by the bots ID
|
||||
/// </summary>
|
||||
[Injectable(InjectionType.Singleton)]
|
||||
public class MatchBotDetailsCacheService(ISptLogger<MatchBotDetailsCacheService> _logger)
|
||||
public class MatchBotDetailsCacheService(ISptLogger<MatchBotDetailsCacheService> logger)
|
||||
{
|
||||
private static readonly HashSet<string> _sidesToCache = [Sides.PmcUsec, Sides.PmcBear];
|
||||
|
||||
@@ -32,7 +32,7 @@ public class MatchBotDetailsCacheService(ISptLogger<MatchBotDetailsCacheService>
|
||||
|
||||
if (botToCache.Info?.Nickname is null)
|
||||
{
|
||||
_logger.Warning(
|
||||
logger.Warning(
|
||||
$"Unable to cache: {botToCache.Info?.Settings?.Role} bot with id: {botToCache.Id} as it lacks a nickname"
|
||||
);
|
||||
return;
|
||||
@@ -83,7 +83,7 @@ public class MatchBotDetailsCacheService(ISptLogger<MatchBotDetailsCacheService>
|
||||
var botInCache = BotDetailsCache.GetValueOrDefault(id, null);
|
||||
if (botInCache is null)
|
||||
{
|
||||
_logger.Warning($"Bot not found in match bot cache: {id}");
|
||||
logger.Warning($"Bot not found in match bot cache: {id}");
|
||||
return null;
|
||||
}
|
||||
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
using SPTarkov.DI.Annotations;
|
||||
using SPTarkov.Server.Core.Models.Common;
|
||||
using SPTarkov.Server.Core.Models.Eft.Ws;
|
||||
|
||||
namespace SPTarkov.Server.Core.Services;
|
||||
@@ -6,19 +7,19 @@ namespace SPTarkov.Server.Core.Services;
|
||||
[Injectable(InjectionType.Singleton)]
|
||||
public class NotificationService
|
||||
{
|
||||
protected readonly Dictionary<string, List<WsNotificationEvent>> _messageQueue = new();
|
||||
protected readonly Dictionary<MongoId, List<WsNotificationEvent>> _messageQueue = new();
|
||||
|
||||
public Dictionary<string, List<WsNotificationEvent>> GetMessageQueue()
|
||||
public Dictionary<MongoId, List<WsNotificationEvent>> GetMessageQueue()
|
||||
{
|
||||
return _messageQueue;
|
||||
}
|
||||
|
||||
public List<WsNotificationEvent>? GetMessageFromQueue(string sessionId)
|
||||
public List<WsNotificationEvent>? GetMessageFromQueue(MongoId sessionId)
|
||||
{
|
||||
return _messageQueue.GetValueOrDefault(sessionId);
|
||||
}
|
||||
|
||||
public void UpdateMessageOnQueue(string sessionId, List<WsNotificationEvent> value)
|
||||
public void UpdateMessageOnQueue(MongoId sessionId, List<WsNotificationEvent> value)
|
||||
{
|
||||
if (_messageQueue.ContainsKey(sessionId))
|
||||
{
|
||||
@@ -26,7 +27,7 @@ public class NotificationService
|
||||
}
|
||||
}
|
||||
|
||||
public bool Has(string sessionID)
|
||||
public bool Has(MongoId sessionID)
|
||||
{
|
||||
return _messageQueue.ContainsKey(sessionID);
|
||||
}
|
||||
@@ -34,7 +35,7 @@ public class NotificationService
|
||||
/// <summary>
|
||||
/// Pop first message from queue.
|
||||
/// </summary>
|
||||
public WsNotificationEvent Pop(string sessionID)
|
||||
public WsNotificationEvent Pop(MongoId sessionID)
|
||||
{
|
||||
var result = Get(sessionID).First();
|
||||
Get(sessionID).Remove(result);
|
||||
@@ -44,7 +45,7 @@ public class NotificationService
|
||||
/// <summary>
|
||||
/// Add message to queue
|
||||
/// </summary>
|
||||
public void Add(string sessionID, WsNotificationEvent message)
|
||||
public void Add(MongoId sessionID, WsNotificationEvent message)
|
||||
{
|
||||
Get(sessionID).Add(message);
|
||||
}
|
||||
@@ -53,9 +54,9 @@ public class NotificationService
|
||||
/// Get message queue for session
|
||||
/// </summary>
|
||||
/// <param name="sessionID">Session/player id</param>
|
||||
public List<WsNotificationEvent> Get(string sessionID)
|
||||
public List<WsNotificationEvent> Get(MongoId sessionID)
|
||||
{
|
||||
if (sessionID is null)
|
||||
if (sessionID.IsEmpty())
|
||||
{
|
||||
throw new Exception("sessionID missing");
|
||||
}
|
||||
|
||||
@@ -10,13 +10,13 @@ namespace SPTarkov.Server.Core.Services;
|
||||
/// </summary>
|
||||
[Injectable(InjectionType.Singleton)]
|
||||
public class OpenZoneService(
|
||||
ISptLogger<OpenZoneService> _logger,
|
||||
DatabaseService _databaseService,
|
||||
ServerLocalisationService _serverLocalisationService,
|
||||
ConfigServer _configServer
|
||||
ISptLogger<OpenZoneService> logger,
|
||||
DatabaseService databaseService,
|
||||
ServerLocalisationService serverLocalisationService,
|
||||
ConfigServer configServer
|
||||
)
|
||||
{
|
||||
protected readonly LocationConfig _locationConfig = _configServer.GetConfig<LocationConfig>();
|
||||
protected readonly LocationConfig _locationConfig = configServer.GetConfig<LocationConfig>();
|
||||
|
||||
/// <summary>
|
||||
/// Add open zone to specified map
|
||||
@@ -38,13 +38,13 @@ public class OpenZoneService(
|
||||
/// </summary>
|
||||
public void ApplyZoneChangesToAllMaps()
|
||||
{
|
||||
var dbLocations = _databaseService.GetLocations().GetDictionary();
|
||||
var dbLocations = databaseService.GetLocations().GetDictionary();
|
||||
foreach (var mapKvP in _locationConfig.OpenZones)
|
||||
{
|
||||
if (!dbLocations.ContainsKey(mapKvP.Key))
|
||||
{
|
||||
_logger.Error(
|
||||
_serverLocalisationService.GetText("openzone-unable_to_find_map", mapKvP)
|
||||
logger.Error(
|
||||
serverLocalisationService.GetText("openzone-unable_to_find_map", mapKvP)
|
||||
);
|
||||
|
||||
continue;
|
||||
|
||||
@@ -18,19 +18,18 @@ namespace SPTarkov.Server.Core.Services;
|
||||
|
||||
[Injectable(InjectionType.Singleton)]
|
||||
public class PaymentService(
|
||||
ISptLogger<PaymentService> _logger,
|
||||
HttpResponseUtil _httpResponseUtil,
|
||||
HandbookHelper _handbookHelper,
|
||||
TraderHelper _traderHelper,
|
||||
ItemHelper _itemHelper,
|
||||
InventoryHelper _inventoryHelper,
|
||||
ServerLocalisationService _serverLocalisationService,
|
||||
PaymentHelper _paymentHelper,
|
||||
ConfigServer _configServer
|
||||
ISptLogger<PaymentService> logger,
|
||||
HttpResponseUtil httpResponseUtil,
|
||||
HandbookHelper handbookHelper,
|
||||
TraderHelper traderHelper,
|
||||
ItemHelper itemHelper,
|
||||
InventoryHelper inventoryHelper,
|
||||
ServerLocalisationService serverLocalisationService,
|
||||
PaymentHelper paymentHelper,
|
||||
ConfigServer configServer
|
||||
)
|
||||
{
|
||||
protected readonly InventoryConfig _inventoryConfig =
|
||||
_configServer.GetConfig<InventoryConfig>();
|
||||
protected readonly InventoryConfig _inventoryConfig = configServer.GetConfig<InventoryConfig>();
|
||||
|
||||
/// <summary>
|
||||
/// Take money and insert items into return to server request
|
||||
@@ -42,13 +41,13 @@ public class PaymentService(
|
||||
public void PayMoney(
|
||||
PmcData pmcData,
|
||||
ProcessBuyTradeRequestData request,
|
||||
string sessionID,
|
||||
MongoId sessionID,
|
||||
ItemEventRouterResponse output
|
||||
)
|
||||
{
|
||||
// May need to convert to trader currency
|
||||
var trader = _traderHelper.GetTrader(request.TransactionId, sessionID);
|
||||
var payToTrader = _traderHelper.TraderExists(request.TransactionId);
|
||||
var trader = traderHelper.GetTrader(request.TransactionId, sessionID);
|
||||
var payToTrader = traderHelper.TraderExists(request.TransactionId);
|
||||
|
||||
// Track the amounts of each type of currency involved in the trade.
|
||||
var currencyAmounts = new Dictionary<string, double?>();
|
||||
@@ -60,10 +59,10 @@ public class PaymentService(
|
||||
var item = pmcData.Inventory.Items.FirstOrDefault(i => i.Id == itemRequest.Id);
|
||||
if (item is not null)
|
||||
{
|
||||
if (!_paymentHelper.IsMoneyTpl(item.Template))
|
||||
if (!paymentHelper.IsMoneyTpl(item.Template))
|
||||
{
|
||||
// If the item is not money, remove it from the inventory.
|
||||
_inventoryHelper.RemoveItemByCount(
|
||||
inventoryHelper.RemoveItemByCount(
|
||||
pmcData,
|
||||
item.Id,
|
||||
(int)itemRequest.Count,
|
||||
@@ -122,8 +121,8 @@ public class PaymentService(
|
||||
if (payToTrader)
|
||||
{
|
||||
// Convert the amount to the trader's currency and update the sales sum.
|
||||
var costOfPurchaseInCurrency = _handbookHelper.FromRUB(
|
||||
_handbookHelper.InRUB(currencyAmount ?? 0, currencyTpl),
|
||||
var costOfPurchaseInCurrency = handbookHelper.FromRUB(
|
||||
handbookHelper.InRUB(currencyAmount ?? 0, currencyTpl),
|
||||
trader.Currency.Value.GetCurrencyTpl()
|
||||
);
|
||||
|
||||
@@ -135,10 +134,10 @@ public class PaymentService(
|
||||
// If no currency-based payment is involved, handle it separately
|
||||
if (totalCurrencyAmount == 0 && payToTrader)
|
||||
{
|
||||
_logger.Debug(_serverLocalisationService.GetText("payment-zero_price_no_payment"));
|
||||
logger.Debug(serverLocalisationService.GetText("payment-zero_price_no_payment"));
|
||||
|
||||
// Convert the handbook price to the trader's currency and update the sales sum.
|
||||
var costOfPurchaseInCurrency = _handbookHelper.FromRUB(
|
||||
var costOfPurchaseInCurrency = handbookHelper.FromRUB(
|
||||
GetTraderItemHandbookPriceRouble(request.ItemId, request.TransactionId) ?? 0,
|
||||
trader.Currency.Value.GetCurrencyTpl()
|
||||
);
|
||||
@@ -148,12 +147,12 @@ public class PaymentService(
|
||||
|
||||
if (payToTrader)
|
||||
{
|
||||
_traderHelper.LevelUp(request.TransactionId, pmcData);
|
||||
traderHelper.LevelUp(request.TransactionId, pmcData);
|
||||
}
|
||||
|
||||
if (_logger.IsLogEnabled(LogLevel.Debug))
|
||||
if (logger.IsLogEnabled(LogLevel.Debug))
|
||||
{
|
||||
_logger.Debug("Item(s) taken. Status OK.");
|
||||
logger.Debug("Item(s) taken. Status OK.");
|
||||
}
|
||||
}
|
||||
|
||||
@@ -163,9 +162,9 @@ public class PaymentService(
|
||||
/// <param name="traderAssortId"> ID of the assort to look up</param>
|
||||
/// <param name="traderId"> ID of trader with assort </param>
|
||||
/// <returns> Handbook rouble price of the item </returns>
|
||||
private double? GetTraderItemHandbookPriceRouble(string? traderAssortId, string traderId)
|
||||
private double? GetTraderItemHandbookPriceRouble(MongoId traderAssortId, MongoId traderId)
|
||||
{
|
||||
var purchasedAssortItem = _traderHelper.GetTraderAssortItemByAssortId(
|
||||
var purchasedAssortItem = traderHelper.GetTraderAssortItemByAssortId(
|
||||
traderId,
|
||||
traderAssortId
|
||||
);
|
||||
@@ -174,10 +173,10 @@ public class PaymentService(
|
||||
return 1;
|
||||
}
|
||||
|
||||
var assortItemPriceRouble = _handbookHelper.GetTemplatePrice(purchasedAssortItem.Template);
|
||||
var assortItemPriceRouble = handbookHelper.GetTemplatePrice(purchasedAssortItem.Template);
|
||||
if (assortItemPriceRouble == 0)
|
||||
{
|
||||
_logger.Debug(
|
||||
logger.Debug(
|
||||
$"No item price found for {purchasedAssortItem.Template} on trader: {traderId} in assort: {traderAssortId}"
|
||||
);
|
||||
|
||||
@@ -200,13 +199,13 @@ public class PaymentService(
|
||||
double? amountToSend,
|
||||
ProcessSellTradeRequestData request,
|
||||
ItemEventRouterResponse output,
|
||||
string sessionID
|
||||
MongoId sessionID
|
||||
)
|
||||
{
|
||||
var trader = _traderHelper.GetTrader(request.TransactionId, sessionID);
|
||||
var trader = traderHelper.GetTrader(request.TransactionId, sessionID);
|
||||
if (trader is null)
|
||||
{
|
||||
_logger.Error(
|
||||
logger.Error(
|
||||
$"Unable to add currency to profile as trader: {request.TransactionId} does not exist"
|
||||
);
|
||||
|
||||
@@ -214,14 +213,14 @@ public class PaymentService(
|
||||
}
|
||||
|
||||
var currencyTpl = trader.Currency.Value.GetCurrencyTpl();
|
||||
var calcAmount = _handbookHelper.FromRUB(
|
||||
_handbookHelper.InRUB(amountToSend ?? 0, currencyTpl),
|
||||
var calcAmount = handbookHelper.FromRUB(
|
||||
handbookHelper.InRUB(amountToSend ?? 0, currencyTpl),
|
||||
currencyTpl
|
||||
);
|
||||
var currencyMaxStackSize = _itemHelper.GetItem(currencyTpl).Value.Properties?.StackMaxSize;
|
||||
var currencyMaxStackSize = itemHelper.GetItem(currencyTpl).Value.Properties?.StackMaxSize;
|
||||
if (currencyMaxStackSize is null)
|
||||
{
|
||||
_logger.Error(
|
||||
logger.Error(
|
||||
$"Unable to add currency: {currencyTpl} to profile as it lacks a _props property"
|
||||
);
|
||||
|
||||
@@ -278,7 +277,7 @@ public class PaymentService(
|
||||
};
|
||||
|
||||
// Ensure money is properly split to follow its max stack size limit
|
||||
var rewards = _itemHelper.SplitStackIntoSeparateItems(rootCurrencyReward);
|
||||
var rewards = itemHelper.SplitStackIntoSeparateItems(rootCurrencyReward);
|
||||
|
||||
if (!skipSendingMoneyToStash)
|
||||
{
|
||||
@@ -289,14 +288,14 @@ public class PaymentService(
|
||||
Callback = null,
|
||||
UseSortingTable = true,
|
||||
};
|
||||
_inventoryHelper.AddItemsToStash(sessionID, addItemToStashRequest, pmcData, output);
|
||||
inventoryHelper.AddItemsToStash(sessionID, addItemToStashRequest, pmcData, output);
|
||||
}
|
||||
|
||||
// Calcualte new total sale sum with trader item sold to
|
||||
var saleSum = pmcData.TradersInfo[request.TransactionId].SalesSum + amountToSend;
|
||||
|
||||
pmcData.TradersInfo[request.TransactionId].SalesSum = saleSum;
|
||||
_traderHelper.LevelUp(request.TransactionId, pmcData);
|
||||
traderHelper.LevelUp(request.TransactionId, pmcData);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -309,16 +308,16 @@ public class PaymentService(
|
||||
/// <param name="output"> Client response </param>
|
||||
public void AddPaymentToOutput(
|
||||
PmcData pmcData,
|
||||
string currencyTpl,
|
||||
MongoId currencyTpl,
|
||||
double amountToPay,
|
||||
string sessionID,
|
||||
MongoId sessionID,
|
||||
ItemEventRouterResponse output
|
||||
)
|
||||
{
|
||||
var moneyItemsInInventory = GetSortedMoneyItemsInInventory(
|
||||
pmcData,
|
||||
currencyTpl,
|
||||
pmcData.Inventory.Stash
|
||||
pmcData.Inventory.Stash.Value
|
||||
);
|
||||
|
||||
//Ensure all money items found have a upd
|
||||
@@ -335,15 +334,15 @@ public class PaymentService(
|
||||
// If no money in inventory or amount is not enough we return false
|
||||
if (moneyItemsInInventory.Count <= 0 || amountAvailable < amountToPay)
|
||||
{
|
||||
_logger.Error(
|
||||
_serverLocalisationService.GetText(
|
||||
logger.Error(
|
||||
serverLocalisationService.GetText(
|
||||
"payment-not_enough_money_to_complete_transation", // Typo, needs locale updated if fixed
|
||||
new { amountToPay, amountAvailable }
|
||||
)
|
||||
);
|
||||
_httpResponseUtil.AppendErrorToOutput(
|
||||
httpResponseUtil.AppendErrorToOutput(
|
||||
output,
|
||||
_serverLocalisationService.GetText(
|
||||
serverLocalisationService.GetText(
|
||||
"payment-not_enough_money_to_complete_transation_short",
|
||||
amountToPay
|
||||
), // Typo, needs locale updated if fixed
|
||||
@@ -360,7 +359,7 @@ public class PaymentService(
|
||||
if (leftToPay >= itemAmount)
|
||||
{
|
||||
leftToPay -= itemAmount ?? 0;
|
||||
_inventoryHelper.RemoveItem(pmcData, profileMoneyItem.Id, sessionID, output);
|
||||
inventoryHelper.RemoveItem(pmcData, profileMoneyItem.Id, sessionID, output);
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -388,19 +387,19 @@ public class PaymentService(
|
||||
// TODO - ensure money in containers inside secure container are LAST
|
||||
protected List<Item> GetSortedMoneyItemsInInventory(
|
||||
PmcData pmcData,
|
||||
string currencyTpl,
|
||||
string playerStashId
|
||||
MongoId currencyTpl,
|
||||
MongoId playerStashId
|
||||
)
|
||||
{
|
||||
// Get money stacks player has
|
||||
var moneyItemsInInventory = _itemHelper.FindBarterItems(
|
||||
var moneyItemsInInventory = itemHelper.FindBarterItems(
|
||||
"tpl",
|
||||
pmcData.Inventory.Items,
|
||||
currencyTpl
|
||||
);
|
||||
if (moneyItemsInInventory.Count == 0)
|
||||
{
|
||||
_logger.Debug($"No {currencyTpl} money items found in inventory");
|
||||
logger.Debug($"No {currencyTpl} money items found in inventory");
|
||||
|
||||
return moneyItemsInInventory;
|
||||
}
|
||||
@@ -432,12 +431,12 @@ public class PaymentService(
|
||||
/// <param name="items">Inventory items to check</param>
|
||||
/// <param name="playerStashId">Id of players stash</param>
|
||||
/// <returns>Dictionary</returns>
|
||||
protected IReadOnlyDictionary<string, InventoryLocation> GetItemInStashCache(
|
||||
protected IReadOnlyDictionary<MongoId, InventoryLocation> GetItemInStashCache(
|
||||
List<Item> items,
|
||||
string playerStashId
|
||||
MongoId playerStashId
|
||||
)
|
||||
{
|
||||
var itemsInStashCache = new Dictionary<string, InventoryLocation>();
|
||||
var itemsInStashCache = new Dictionary<MongoId, InventoryLocation>();
|
||||
foreach (var inventoryItem in items)
|
||||
{
|
||||
itemsInStashCache.TryAdd(
|
||||
@@ -464,7 +463,7 @@ public class PaymentService(
|
||||
Item a,
|
||||
Item b,
|
||||
List<Item> inventoryItems,
|
||||
IReadOnlyDictionary<string, InventoryLocation> itemInStashCache
|
||||
IReadOnlyDictionary<MongoId, InventoryLocation> itemInStashCache
|
||||
)
|
||||
{
|
||||
// Get the location of A and B
|
||||
@@ -592,7 +591,7 @@ public class PaymentService(
|
||||
protected InventoryLocation GetItemLocation(
|
||||
MongoId itemId,
|
||||
List<Item> inventoryItems,
|
||||
string playerStashId
|
||||
MongoId playerStashId
|
||||
)
|
||||
{
|
||||
var inventoryItem = inventoryItems.FirstOrDefault(item => item.Id == itemId);
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
using System.Text.RegularExpressions;
|
||||
using SPTarkov.DI.Annotations;
|
||||
using SPTarkov.Server.Core.Helpers;
|
||||
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.Profile;
|
||||
@@ -14,20 +15,20 @@ namespace SPTarkov.Server.Core.Services;
|
||||
|
||||
[Injectable(InjectionType.Singleton)]
|
||||
public class PmcChatResponseService(
|
||||
ISptLogger<OpenZoneService> _logger,
|
||||
RandomUtil _randomUtil,
|
||||
NotificationSendHelper _notificationSendHelper,
|
||||
WeightedRandomHelper _weightedRandomHelper,
|
||||
ServerLocalisationService _serverLocalisationService,
|
||||
GiftService _giftService,
|
||||
LocaleService _localeService,
|
||||
MatchBotDetailsCacheService _matchBotDetailsCacheService,
|
||||
ConfigServer _configServer
|
||||
ISptLogger<OpenZoneService> logger,
|
||||
RandomUtil randomUtil,
|
||||
NotificationSendHelper notificationSendHelper,
|
||||
WeightedRandomHelper weightedRandomHelper,
|
||||
ServerLocalisationService serverLocalisationService,
|
||||
GiftService giftService,
|
||||
LocaleService localeService,
|
||||
MatchBotDetailsCacheService matchBotDetailsCacheService,
|
||||
ConfigServer configServer
|
||||
)
|
||||
{
|
||||
protected GiftsConfig _giftConfig = _configServer.GetConfig<GiftsConfig>();
|
||||
protected GiftsConfig _giftConfig = configServer.GetConfig<GiftsConfig>();
|
||||
protected readonly PmcChatResponse _pmcResponsesConfig =
|
||||
_configServer.GetConfig<PmcChatResponse>();
|
||||
configServer.GetConfig<PmcChatResponse>();
|
||||
|
||||
/// <summary>
|
||||
/// For each PMC victim of the player, have a chance to send a message to the player, can be positive or negative
|
||||
@@ -35,18 +36,18 @@ public class PmcChatResponseService(
|
||||
/// <param name="sessionId"> Session ID </param>
|
||||
/// <param name="pmcVictims"> List of bots killed by player </param>
|
||||
/// <param name="pmcData"> Player profile </param>
|
||||
public void SendVictimResponse(string sessionId, List<Victim> pmcVictims, PmcData pmcData)
|
||||
public void SendVictimResponse(MongoId sessionId, List<Victim> pmcVictims, PmcData pmcData)
|
||||
{
|
||||
foreach (var victim in pmcVictims)
|
||||
{
|
||||
if (!_randomUtil.GetChance100(_pmcResponsesConfig.Victim.ResponseChancePercent))
|
||||
if (!randomUtil.GetChance100(_pmcResponsesConfig.Victim.ResponseChancePercent))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
if (string.IsNullOrEmpty(victim.Name))
|
||||
{
|
||||
_logger.Warning(
|
||||
logger.Warning(
|
||||
$"Victim: {victim.ProfileId} does not have a nickname, skipping pmc response message send"
|
||||
);
|
||||
|
||||
@@ -57,7 +58,7 @@ public class PmcChatResponseService(
|
||||
var message = ChooseMessage(true, pmcData, victim);
|
||||
if (message is not null)
|
||||
{
|
||||
_notificationSendHelper.SendMessageToPlayer(
|
||||
notificationSendHelper.SendMessageToPlayer(
|
||||
sessionId,
|
||||
victimDetails,
|
||||
message,
|
||||
@@ -73,20 +74,20 @@ public class PmcChatResponseService(
|
||||
/// <param name="sessionId"> Session id </param>
|
||||
/// <param name="pmcData"> Players profile </param>
|
||||
/// <param name="killer"> The bot who killed the player </param>
|
||||
public void SendKillerResponse(string sessionId, PmcData pmcData, Aggressor killer)
|
||||
public void SendKillerResponse(MongoId sessionId, PmcData pmcData, Aggressor killer)
|
||||
{
|
||||
if (killer is null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (!_randomUtil.GetChance100(_pmcResponsesConfig.Killer.ResponseChancePercent))
|
||||
if (!randomUtil.GetChance100(_pmcResponsesConfig.Killer.ResponseChancePercent))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
// find bot by id in cache
|
||||
var killerDetailsInCache = _matchBotDetailsCacheService.GetBotById(killer.ProfileId);
|
||||
var killerDetailsInCache = matchBotDetailsCacheService.GetBotById(killer.ProfileId);
|
||||
if (killerDetailsInCache is null)
|
||||
{
|
||||
return;
|
||||
@@ -115,7 +116,7 @@ public class PmcChatResponseService(
|
||||
return;
|
||||
}
|
||||
|
||||
_notificationSendHelper.SendMessageToPlayer(
|
||||
notificationSendHelper.SendMessageToPlayer(
|
||||
sessionId,
|
||||
killerDetails,
|
||||
message,
|
||||
@@ -139,16 +140,16 @@ public class PmcChatResponseService(
|
||||
var possibleResponseLocaleKeys = GetResponseLocaleKeys(responseType, isVictim);
|
||||
if (possibleResponseLocaleKeys.Count == 0)
|
||||
{
|
||||
_logger.Warning(
|
||||
_serverLocalisationService.GetText("pmcresponse-unable_to_find_key", responseType)
|
||||
logger.Warning(
|
||||
serverLocalisationService.GetText("pmcresponse-unable_to_find_key", responseType)
|
||||
);
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
// Choose random response from above list and request it from localisation service
|
||||
var responseText = _serverLocalisationService.GetText(
|
||||
_randomUtil.GetArrayValue(possibleResponseLocaleKeys),
|
||||
var responseText = serverLocalisationService.GetText(
|
||||
randomUtil.GetArrayValue(possibleResponseLocaleKeys),
|
||||
new
|
||||
{
|
||||
playerName = pmcData.Info.Nickname,
|
||||
@@ -163,16 +164,16 @@ public class PmcChatResponseService(
|
||||
// Give the player a gift code if they were killed and response is 'pity'.
|
||||
if (responseType == "pity")
|
||||
{
|
||||
var giftKeys = _giftService.GetGiftIds();
|
||||
var randomGiftKey = _randomUtil.GetArrayValue(giftKeys);
|
||||
var giftKeys = giftService.GetGiftIds();
|
||||
var randomGiftKey = randomUtil.GetArrayValue(giftKeys);
|
||||
|
||||
Regex.Replace(responseText, "/(%giftcode%)/gi", randomGiftKey); // TODO: does regex still work
|
||||
}
|
||||
|
||||
if (AppendSuffixToMessageEnd(isVictim))
|
||||
{
|
||||
var suffixText = _serverLocalisationService.GetText(
|
||||
_randomUtil.GetArrayValue(GetResponseSuffixLocaleKeys())
|
||||
var suffixText = serverLocalisationService.GetText(
|
||||
randomUtil.GetArrayValue(GetResponseSuffixLocaleKeys())
|
||||
);
|
||||
responseText += $" {suffixText}";
|
||||
}
|
||||
@@ -198,7 +199,7 @@ public class PmcChatResponseService(
|
||||
/// <returns> Localised location name </returns>
|
||||
protected string GetLocationName(string locationKey)
|
||||
{
|
||||
return _localeService.GetLocaleDb()[locationKey] ?? locationKey;
|
||||
return localeService.GetLocaleDb()[locationKey] ?? locationKey;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -212,7 +213,7 @@ public class PmcChatResponseService(
|
||||
? _pmcResponsesConfig.Victim.StripCapitalisationChancePercent
|
||||
: _pmcResponsesConfig.Killer.StripCapitalisationChancePercent;
|
||||
|
||||
return _randomUtil.GetChance100(chance);
|
||||
return randomUtil.GetChance100(chance);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -226,7 +227,7 @@ public class PmcChatResponseService(
|
||||
? _pmcResponsesConfig.Victim.AllCapsChancePercent
|
||||
: _pmcResponsesConfig.Killer.AllCapsChancePercent;
|
||||
|
||||
return _randomUtil.GetChance100(chance);
|
||||
return randomUtil.GetChance100(chance);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -240,7 +241,7 @@ public class PmcChatResponseService(
|
||||
? _pmcResponsesConfig.Victim.AppendBroToMessageEndChancePercent
|
||||
: _pmcResponsesConfig.Killer.AppendBroToMessageEndChancePercent;
|
||||
|
||||
return _randomUtil.GetChance100(chance);
|
||||
return randomUtil.GetChance100(chance);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -254,7 +255,7 @@ public class PmcChatResponseService(
|
||||
? _pmcResponsesConfig.Victim.ResponseTypeWeights
|
||||
: _pmcResponsesConfig.Killer.ResponseTypeWeights;
|
||||
|
||||
return _weightedRandomHelper.GetWeightedValue<string>(responseWeights);
|
||||
return weightedRandomHelper.GetWeightedValue<string>(responseWeights);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -266,7 +267,7 @@ public class PmcChatResponseService(
|
||||
protected List<string> GetResponseLocaleKeys(string keyType, bool isVictim = true)
|
||||
{
|
||||
var keyBase = isVictim ? "pmcresponse-victim_" : "pmcresponse-killer_";
|
||||
var keys = _serverLocalisationService.GetLocaleKeys();
|
||||
var keys = serverLocalisationService.GetLocaleKeys();
|
||||
|
||||
return keys.Where(x => x.StartsWith($"{keyBase}{keyType}")).ToList();
|
||||
}
|
||||
@@ -277,7 +278,7 @@ public class PmcChatResponseService(
|
||||
/// <returns> List of keys </returns>
|
||||
protected List<string> GetResponseSuffixLocaleKeys()
|
||||
{
|
||||
var keys = _serverLocalisationService.GetLocaleKeys();
|
||||
var keys = serverLocalisationService.GetLocaleKeys();
|
||||
|
||||
return keys.Where(x => x.StartsWith("pmcresponse-suffix")).ToList();
|
||||
}
|
||||
@@ -290,7 +291,7 @@ public class PmcChatResponseService(
|
||||
// TODO: is this used?
|
||||
protected UserDialogInfo ChooseRandomVictim(List<Victim> pmcVictims)
|
||||
{
|
||||
var randomVictim = _randomUtil.GetArrayValue(pmcVictims);
|
||||
var randomVictim = randomUtil.GetArrayValue(pmcVictims);
|
||||
|
||||
return GetVictimDetails(randomVictim);
|
||||
}
|
||||
@@ -315,7 +316,7 @@ public class PmcChatResponseService(
|
||||
MemberCategory.Developer,
|
||||
};
|
||||
|
||||
var chosenCategory = _randomUtil.GetArrayValue(categories);
|
||||
var chosenCategory = randomUtil.GetArrayValue(categories);
|
||||
|
||||
return new UserDialogInfo
|
||||
{
|
||||
|
||||
@@ -11,39 +11,39 @@ namespace SPTarkov.Server.Core.Services;
|
||||
|
||||
[Injectable(InjectionType.Singleton)]
|
||||
public class PostDbLoadService(
|
||||
ISptLogger<PostDbLoadService> _logger,
|
||||
DatabaseService _databaseService,
|
||||
ServerLocalisationService _serverLocalisationService,
|
||||
SeasonalEventService _seasonalEventService,
|
||||
CustomLocationWaveService _customLocationWaveService,
|
||||
OpenZoneService _openZoneService,
|
||||
ItemBaseClassService _itemBaseClassService,
|
||||
RaidWeatherService _raidWeatherService,
|
||||
ConfigServer _configServer,
|
||||
ICloner _cloner
|
||||
ISptLogger<PostDbLoadService> logger,
|
||||
DatabaseService databaseService,
|
||||
ServerLocalisationService serverLocalisationService,
|
||||
SeasonalEventService seasonalEventService,
|
||||
CustomLocationWaveService customLocationWaveService,
|
||||
OpenZoneService openZoneService,
|
||||
ItemBaseClassService itemBaseClassService,
|
||||
RaidWeatherService raidWeatherService,
|
||||
ConfigServer configServer,
|
||||
ICloner cloner
|
||||
)
|
||||
{
|
||||
protected readonly BotConfig _botConfig = _configServer.GetConfig<BotConfig>();
|
||||
protected readonly CoreConfig _coreConfig = _configServer.GetConfig<CoreConfig>();
|
||||
protected readonly HideoutConfig _hideoutConfig = _configServer.GetConfig<HideoutConfig>();
|
||||
protected readonly ItemConfig _itemConfig = _configServer.GetConfig<ItemConfig>();
|
||||
protected readonly LocationConfig _locationConfig = _configServer.GetConfig<LocationConfig>();
|
||||
protected readonly LootConfig _lootConfig = _configServer.GetConfig<LootConfig>();
|
||||
protected readonly PmcConfig _pmcConfig = _configServer.GetConfig<PmcConfig>();
|
||||
protected readonly RagfairConfig _ragfairConfig = _configServer.GetConfig<RagfairConfig>();
|
||||
protected readonly BotConfig _botConfig = configServer.GetConfig<BotConfig>();
|
||||
protected readonly CoreConfig _coreConfig = configServer.GetConfig<CoreConfig>();
|
||||
protected readonly HideoutConfig _hideoutConfig = configServer.GetConfig<HideoutConfig>();
|
||||
protected readonly ItemConfig _itemConfig = configServer.GetConfig<ItemConfig>();
|
||||
protected readonly LocationConfig _locationConfig = configServer.GetConfig<LocationConfig>();
|
||||
protected readonly LootConfig _lootConfig = configServer.GetConfig<LootConfig>();
|
||||
protected readonly PmcConfig _pmcConfig = configServer.GetConfig<PmcConfig>();
|
||||
protected readonly RagfairConfig _ragfairConfig = configServer.GetConfig<RagfairConfig>();
|
||||
|
||||
public void PerformPostDbLoadActions()
|
||||
{
|
||||
// Regenerate base cache now mods are loaded and game is starting
|
||||
// Mods that add items and use the baseClass service generate the cache including their items, the next mod that
|
||||
// add items gets left out,causing warnings
|
||||
_itemBaseClassService.HydrateItemBaseClassCache();
|
||||
itemBaseClassService.HydrateItemBaseClassCache();
|
||||
|
||||
// Validate that only mongoIds exist in items, quests, and traders
|
||||
// Kill the startup if not.
|
||||
// TODO: We can probably remove this in a couple versions
|
||||
_databaseService.ValidateDatabase();
|
||||
if (!_databaseService.IsDatabaseValid())
|
||||
databaseService.ValidateDatabase();
|
||||
if (!databaseService.IsDatabaseValid())
|
||||
{
|
||||
throw new Exception("Server start failure, database invalid");
|
||||
}
|
||||
@@ -61,7 +61,7 @@ public class PostDbLoadService(
|
||||
|
||||
if (_locationConfig.AddOpenZonesToAllMaps)
|
||||
{
|
||||
_openZoneService.ApplyZoneChangesToAllMaps();
|
||||
openZoneService.ApplyZoneChangesToAllMaps();
|
||||
}
|
||||
|
||||
if (_pmcConfig.RemoveExistingPmcWaves.GetValueOrDefault(false))
|
||||
@@ -71,7 +71,7 @@ public class PostDbLoadService(
|
||||
|
||||
if (_locationConfig.AddCustomBotWavesToMaps)
|
||||
{
|
||||
_customLocationWaveService.ApplyWaveChangesToAllMaps();
|
||||
customLocationWaveService.ApplyWaveChangesToAllMaps();
|
||||
}
|
||||
|
||||
if (_locationConfig.EnableBotTypeLimits)
|
||||
@@ -105,10 +105,10 @@ public class PostDbLoadService(
|
||||
|
||||
ValidateQuestAssortUnlocksExist();
|
||||
|
||||
if (_seasonalEventService.IsAutomaticEventDetectionEnabled())
|
||||
if (seasonalEventService.IsAutomaticEventDetectionEnabled())
|
||||
{
|
||||
_seasonalEventService.CacheActiveEvents();
|
||||
_seasonalEventService.EnableSeasonalEvents();
|
||||
seasonalEventService.CacheActiveEvents();
|
||||
seasonalEventService.EnableSeasonalEvents();
|
||||
}
|
||||
|
||||
// Flea bsg blacklist is off
|
||||
@@ -123,8 +123,8 @@ public class PostDbLoadService(
|
||||
|
||||
AddCustomItemPresetsToGlobals();
|
||||
|
||||
var currentSeason = _seasonalEventService.GetActiveWeatherSeason();
|
||||
_raidWeatherService.GenerateWeather(currentSeason);
|
||||
var currentSeason = seasonalEventService.GetActiveWeatherSeason();
|
||||
raidWeatherService.GenerateWeather(currentSeason);
|
||||
|
||||
if (_botConfig.WeeklyBoss.Enabled)
|
||||
{
|
||||
@@ -165,7 +165,7 @@ public class PostDbLoadService(
|
||||
protected void FlagMapAsGuaranteedBoss(WildSpawnType boss)
|
||||
{
|
||||
// Get the corresponding map for the provided boss
|
||||
var locations = _databaseService.GetLocations();
|
||||
var locations = databaseService.GetLocations();
|
||||
Location? location;
|
||||
switch (boss)
|
||||
{
|
||||
@@ -191,7 +191,7 @@ public class PostDbLoadService(
|
||||
location = locations.Lighthouse;
|
||||
break;
|
||||
default:
|
||||
_logger.Warning($"Unknown boss type: {boss}. Unable to set as weekly. Skipping");
|
||||
logger.Warning($"Unknown boss type: {boss}. Unable to set as weekly. Skipping");
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -200,11 +200,11 @@ public class PostDbLoadService(
|
||||
);
|
||||
if (bossSpawn is null)
|
||||
{
|
||||
_logger.Warning($"Boss: {boss} not found on map, unable to set as weekly. Skipping");
|
||||
logger.Warning($"Boss: {boss} not found on map, unable to set as weekly. Skipping");
|
||||
return;
|
||||
}
|
||||
|
||||
_logger.Debug($"{boss} is boss of the week");
|
||||
logger.Debug($"{boss} is boss of the week");
|
||||
bossSpawn.BossChance = 100;
|
||||
bossSpawn.ShowOnTarkovMap = true;
|
||||
bossSpawn.ShowOnTarkovMapPvE = true;
|
||||
@@ -212,13 +212,13 @@ public class PostDbLoadService(
|
||||
|
||||
private void MergeCustomHideoutAreas()
|
||||
{
|
||||
var hideout = _databaseService.GetHideout();
|
||||
var hideout = databaseService.GetHideout();
|
||||
foreach (var customArea in hideout.CustomAreas)
|
||||
{
|
||||
// Check if exists
|
||||
if (hideout.Areas!.Exists(area => area.Id == customArea.Id))
|
||||
{
|
||||
_logger.Warning(
|
||||
logger.Warning(
|
||||
$"Unable to add new hideout area with Id: {customArea.Id} as ID is already in use, skipping"
|
||||
);
|
||||
|
||||
@@ -234,12 +234,12 @@ public class PostDbLoadService(
|
||||
/// </summary>
|
||||
protected void MergeCustomAchievements()
|
||||
{
|
||||
var achievements = _databaseService.GetAchievements();
|
||||
foreach (var customAchievement in _databaseService.GetCustomAchievements())
|
||||
var achievements = databaseService.GetAchievements();
|
||||
foreach (var customAchievement in databaseService.GetCustomAchievements())
|
||||
{
|
||||
if (achievements.Exists(a => a.Id == customAchievement.Id))
|
||||
{
|
||||
_logger.Debug(
|
||||
logger.Debug(
|
||||
$"Unable to add custom achievement as id: {customAchievement.Id} already exists"
|
||||
);
|
||||
continue;
|
||||
@@ -251,7 +251,7 @@ public class PostDbLoadService(
|
||||
|
||||
private void RemoveNewBeginningRequirementFromPrestige()
|
||||
{
|
||||
var prestigeDb = _databaseService.GetTemplates().Prestige;
|
||||
var prestigeDb = databaseService.GetTemplates().Prestige;
|
||||
var newBeginningQuestId = new HashSet<string>
|
||||
{
|
||||
"6761f28a022f60bb320f3e95",
|
||||
@@ -277,7 +277,7 @@ public class PostDbLoadService(
|
||||
|
||||
private void RemovePraporTestMessage()
|
||||
{
|
||||
foreach ((var locale, var lazyLoad) in _databaseService.GetLocales().Global)
|
||||
foreach ((var locale, var lazyLoad) in databaseService.GetLocales().Global)
|
||||
{
|
||||
lazyLoad.AddTransformer(lazyloadedData =>
|
||||
{
|
||||
@@ -290,16 +290,16 @@ public class PostDbLoadService(
|
||||
|
||||
protected void CloneExistingCraftsAndAddNew()
|
||||
{
|
||||
var hideoutCraftDb = _databaseService.GetHideout().Production;
|
||||
var hideoutCraftDb = databaseService.GetHideout().Production;
|
||||
var craftsToAdd = _hideoutConfig.HideoutCraftsToAdd;
|
||||
foreach (var craftToAdd in craftsToAdd)
|
||||
{
|
||||
var clonedCraft = _cloner.Clone(
|
||||
var clonedCraft = cloner.Clone(
|
||||
hideoutCraftDb.Recipes.FirstOrDefault(x => x.Id == craftToAdd.CraftIdToCopy)
|
||||
);
|
||||
if (clonedCraft is null)
|
||||
{
|
||||
_logger.Warning(
|
||||
logger.Warning(
|
||||
$"Unable to find hideout craft: {craftToAdd.CraftIdToCopy}, skipping"
|
||||
);
|
||||
|
||||
@@ -317,7 +317,7 @@ public class PostDbLoadService(
|
||||
protected void AdjustMinReserveRaiderSpawnChance()
|
||||
{
|
||||
// Get reserve base.json
|
||||
var reserveBase = _databaseService.GetLocation(ELocationName.RezervBase.ToString()).Base;
|
||||
var reserveBase = databaseService.GetLocation(ELocationName.RezervBase.ToString()).Base;
|
||||
|
||||
// Raiders are bosses, get only those from boss spawn array
|
||||
foreach (
|
||||
@@ -351,8 +351,8 @@ public class PostDbLoadService(
|
||||
{
|
||||
if (mapId is null)
|
||||
{
|
||||
_logger.Warning(
|
||||
_serverLocalisationService.GetText(
|
||||
logger.Warning(
|
||||
serverLocalisationService.GetText(
|
||||
"location-unable_to_add_custom_loot_position",
|
||||
mapId
|
||||
)
|
||||
@@ -361,14 +361,14 @@ public class PostDbLoadService(
|
||||
continue;
|
||||
}
|
||||
|
||||
_databaseService
|
||||
databaseService
|
||||
.GetLocation(mapId)
|
||||
.LooseLoot.AddTransformer(looselootData =>
|
||||
{
|
||||
if (looselootData is null)
|
||||
{
|
||||
_logger.Warning(
|
||||
_serverLocalisationService.GetText(
|
||||
logger.Warning(
|
||||
serverLocalisationService.GetText(
|
||||
"location-map_has_no_loose_loot_data",
|
||||
mapId
|
||||
)
|
||||
@@ -408,7 +408,7 @@ public class PostDbLoadService(
|
||||
// BSG have two values for shotgun dispersion, we make sure both have the same value
|
||||
protected void FixShotgunDispersions()
|
||||
{
|
||||
var itemDb = _databaseService.GetItems();
|
||||
var itemDb = databaseService.GetItems();
|
||||
|
||||
var shotguns = new List<string>
|
||||
{
|
||||
@@ -430,7 +430,7 @@ public class PostDbLoadService(
|
||||
|
||||
protected void RemoveExistingPmcWaves()
|
||||
{
|
||||
var locations = _databaseService.GetLocations().GetDictionary();
|
||||
var locations = databaseService.GetLocations().GetDictionary();
|
||||
|
||||
var pmcTypes = new HashSet<string> { "pmcUSEC", "pmcBEAR" };
|
||||
foreach (var locationkvP in locations)
|
||||
@@ -453,7 +453,7 @@ public class PostDbLoadService(
|
||||
/// </summary>
|
||||
protected void AdjustMapBotLimits()
|
||||
{
|
||||
var mapsDb = _databaseService.GetLocations().GetDictionary();
|
||||
var mapsDb = databaseService.GetLocations().GetDictionary();
|
||||
if (_locationConfig.BotTypeLimits is null)
|
||||
{
|
||||
return;
|
||||
@@ -463,8 +463,8 @@ public class PostDbLoadService(
|
||||
{
|
||||
if (!mapsDb.TryGetValue(mapId, out var map))
|
||||
{
|
||||
_logger.Warning(
|
||||
_serverLocalisationService.GetText(
|
||||
logger.Warning(
|
||||
serverLocalisationService.GetText(
|
||||
"bot-unable_to_edit_limits_of_unknown_map",
|
||||
mapId
|
||||
)
|
||||
@@ -509,14 +509,14 @@ public class PostDbLoadService(
|
||||
|
||||
foreach (var (mapId, mapAdjustments) in _lootConfig.LooseLootSpawnPointAdjustments)
|
||||
{
|
||||
_databaseService
|
||||
databaseService
|
||||
.GetLocation(mapId)
|
||||
.LooseLoot.AddTransformer(looselootData =>
|
||||
{
|
||||
if (looselootData is null)
|
||||
{
|
||||
_logger.Warning(
|
||||
_serverLocalisationService.GetText(
|
||||
logger.Warning(
|
||||
serverLocalisationService.GetText(
|
||||
"location-map_has_no_loose_loot_data",
|
||||
mapId
|
||||
)
|
||||
@@ -532,8 +532,8 @@ public class PostDbLoadService(
|
||||
);
|
||||
if (lootPostionToAdjust is null)
|
||||
{
|
||||
_logger.Warning(
|
||||
_serverLocalisationService.GetText(
|
||||
logger.Warning(
|
||||
serverLocalisationService.GetText(
|
||||
"location-unable_to_adjust_loot_position_on_map",
|
||||
new { lootKey, mapId }
|
||||
)
|
||||
@@ -552,7 +552,7 @@ public class PostDbLoadService(
|
||||
|
||||
protected void AdjustLocationBotValues()
|
||||
{
|
||||
var mapsDb = _databaseService.GetLocations();
|
||||
var mapsDb = databaseService.GetLocations();
|
||||
var mapsDict = mapsDb.GetDictionary();
|
||||
foreach (var (key, cap) in _botConfig.MaxBotCap)
|
||||
{
|
||||
@@ -578,7 +578,7 @@ public class PostDbLoadService(
|
||||
var rogueSpawnDelaySeconds = _locationConfig
|
||||
.RogueLighthouseSpawnTimeSettings
|
||||
.WaitTimeSeconds;
|
||||
var lighthouse = _databaseService.GetLocations().Lighthouse?.Base;
|
||||
var lighthouse = databaseService.GetLocations().Lighthouse?.Base;
|
||||
if (lighthouse is null)
|
||||
// Just in case they remove this cursed map
|
||||
{
|
||||
@@ -600,7 +600,7 @@ public class PostDbLoadService(
|
||||
/// </summary>
|
||||
protected void AdjustLabsRaiderSpawnRate()
|
||||
{
|
||||
var labsBase = _databaseService.GetLocations().Laboratory.Base;
|
||||
var labsBase = databaseService.GetLocations().Laboratory.Base;
|
||||
|
||||
// Find spawns with empty string for triggerId/TriggerName
|
||||
var nonTriggerLabsBossSpawns = labsBase.BossLocationSpawn.Where(bossSpawn =>
|
||||
@@ -621,7 +621,7 @@ public class PostDbLoadService(
|
||||
return;
|
||||
}
|
||||
|
||||
foreach (var craft in _databaseService.GetHideout().Production.Recipes)
|
||||
foreach (var craft in databaseService.GetHideout().Production.Recipes)
|
||||
// Only adjust crafts ABOVE the override
|
||||
{
|
||||
craft.ProductionTime = Math.Min(craft.ProductionTime.Value, overrideSeconds);
|
||||
@@ -639,7 +639,7 @@ public class PostDbLoadService(
|
||||
return;
|
||||
}
|
||||
|
||||
foreach (var area in _databaseService.GetHideout().Areas)
|
||||
foreach (var area in databaseService.GetHideout().Areas)
|
||||
foreach (var (_, stage) in area.Stages)
|
||||
// Only adjust crafts ABOVE the override
|
||||
{
|
||||
@@ -658,7 +658,7 @@ public class PostDbLoadService(
|
||||
|
||||
foreach (var craftId in hideoutLootBoxCraftIds)
|
||||
{
|
||||
var recipe = _databaseService
|
||||
var recipe = databaseService
|
||||
.GetHideout()
|
||||
.Production.Recipes.FirstOrDefault(craft => craft.Id == craftId);
|
||||
if (recipe is not null)
|
||||
@@ -673,7 +673,7 @@ public class PostDbLoadService(
|
||||
/// </summary>
|
||||
protected void ValidateQuestAssortUnlocksExist()
|
||||
{
|
||||
var db = _databaseService.GetTables();
|
||||
var db = databaseService.GetTables();
|
||||
var traders = db.Traders;
|
||||
var quests = db.Templates.Quests;
|
||||
foreach (var (traderId, traderData) in traders)
|
||||
@@ -704,8 +704,8 @@ public class PostDbLoadService(
|
||||
traderName = traderId,
|
||||
questName = quests[questKey]?.QuestName ?? "UNKNOWN",
|
||||
};
|
||||
_logger.Warning(
|
||||
_serverLocalisationService.GetText(
|
||||
logger.Warning(
|
||||
serverLocalisationService.GetText(
|
||||
"assort-missing_quest_assort_unlock",
|
||||
messageValues
|
||||
)
|
||||
@@ -717,7 +717,7 @@ public class PostDbLoadService(
|
||||
|
||||
protected void SetAllDbItemsAsSellableOnFlea()
|
||||
{
|
||||
var dbItems = _databaseService.GetItems().Values.ToList();
|
||||
var dbItems = databaseService.GetItems().Values.ToList();
|
||||
foreach (
|
||||
var item in dbItems.Where(item =>
|
||||
string.Equals(item.Type, "Item", StringComparison.OrdinalIgnoreCase)
|
||||
@@ -732,7 +732,7 @@ public class PostDbLoadService(
|
||||
|
||||
protected void AddMissingTraderBuyRestrictionMaxValue()
|
||||
{
|
||||
var restrictions = _databaseService
|
||||
var restrictions = databaseService
|
||||
.GetGlobals()
|
||||
.Configuration.TradingSettings.BuyRestrictionMaxBonus;
|
||||
restrictions["unheard_edition"] = new BuyRestrictionMaxBonus
|
||||
@@ -743,7 +743,7 @@ public class PostDbLoadService(
|
||||
|
||||
protected void ApplyFleaPriceOverrides()
|
||||
{
|
||||
var fleaPrices = _databaseService.GetPrices();
|
||||
var fleaPrices = databaseService.GetPrices();
|
||||
foreach (var (itemTpl, price) in _ragfairConfig.Dynamic.ItemPriceOverrideRouble)
|
||||
{
|
||||
fleaPrices[itemTpl] = price;
|
||||
@@ -754,15 +754,15 @@ public class PostDbLoadService(
|
||||
{
|
||||
foreach (var presetToAdd in _itemConfig.CustomItemGlobalPresets)
|
||||
{
|
||||
if (_databaseService.GetGlobals().ItemPresets.ContainsKey(presetToAdd.Id))
|
||||
if (databaseService.GetGlobals().ItemPresets.ContainsKey(presetToAdd.Id))
|
||||
{
|
||||
_logger.Warning(
|
||||
logger.Warning(
|
||||
$"Global ItemPreset with Id of: {presetToAdd.Id} already exists, unable to overwrite"
|
||||
);
|
||||
continue;
|
||||
}
|
||||
|
||||
_databaseService.GetGlobals().ItemPresets.TryAdd(presetToAdd.Id, presetToAdd);
|
||||
databaseService.GetGlobals().ItemPresets.TryAdd(presetToAdd.Id, presetToAdd);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
using System.Collections.Concurrent;
|
||||
using SPTarkov.DI.Annotations;
|
||||
using SPTarkov.Server.Core.Models.Common;
|
||||
using SPTarkov.Server.Core.Models.Spt.Services;
|
||||
using SPTarkov.Server.Core.Utils;
|
||||
|
||||
@@ -8,9 +9,9 @@ namespace SPTarkov.Server.Core.Services;
|
||||
[Injectable(InjectionType.Singleton)]
|
||||
public class ProfileActivityService(TimeUtil timeUtil)
|
||||
{
|
||||
private readonly ConcurrentDictionary<string, ProfileActivityData> _activeProfiles = [];
|
||||
private readonly ConcurrentDictionary<MongoId, ProfileActivityData> _activeProfiles = [];
|
||||
|
||||
public void AddActiveProfile(string sessionId, long clientStartedTimestamp)
|
||||
public void AddActiveProfile(MongoId sessionId, long clientStartedTimestamp)
|
||||
{
|
||||
_activeProfiles.AddOrUpdate(
|
||||
sessionId,
|
||||
@@ -31,7 +32,7 @@ public class ProfileActivityService(TimeUtil timeUtil)
|
||||
);
|
||||
}
|
||||
|
||||
public bool ContainsActiveProfile(string sessionId)
|
||||
public bool ContainsActiveProfile(MongoId sessionId)
|
||||
{
|
||||
if (_activeProfiles.ContainsKey(sessionId))
|
||||
{
|
||||
@@ -52,7 +53,7 @@ public class ProfileActivityService(TimeUtil timeUtil)
|
||||
return null;
|
||||
}
|
||||
|
||||
public ProfileActivityRaidData GetProfileActivityRaidData(string sessionId)
|
||||
public ProfileActivityRaidData GetProfileActivityRaidData(MongoId sessionId)
|
||||
{
|
||||
// Handle edge cases where people might close the server but keep the client alive
|
||||
if (!ContainsActiveProfile(sessionId))
|
||||
@@ -76,7 +77,7 @@ public class ProfileActivityService(TimeUtil timeUtil)
|
||||
/// <param name="sessionId"> Profile to check </param>
|
||||
/// <param name="minutes"> Minutes to check for activity in </param>
|
||||
/// <returns> True when profile was active within past x minutes </returns>
|
||||
public bool ActiveWithinLastMinutes(string sessionId, int minutes)
|
||||
public bool ActiveWithinLastMinutes(MongoId sessionId, int minutes)
|
||||
{
|
||||
if (!_activeProfiles.TryGetValue(sessionId, out var profileActivity))
|
||||
{
|
||||
@@ -113,7 +114,7 @@ public class ProfileActivityService(TimeUtil timeUtil)
|
||||
/// Update the timestamp a profile was last observed active
|
||||
/// </summary>
|
||||
/// <param name="sessionId"> Profile to update </param>
|
||||
public void SetActivityTimestamp(string sessionId)
|
||||
public void SetActivityTimestamp(MongoId sessionId)
|
||||
{
|
||||
if (_activeProfiles.TryGetValue(sessionId, out var currentActiveProfile))
|
||||
{
|
||||
|
||||
@@ -18,19 +18,19 @@ namespace SPTarkov.Server.Core.Services;
|
||||
|
||||
[Injectable(InjectionType.Singleton)]
|
||||
public class ProfileFixerService(
|
||||
ISptLogger<ProfileFixerService> _logger,
|
||||
JsonUtil _jsonUtil,
|
||||
RewardHelper _rewardHelper,
|
||||
TraderHelper _traderHelper,
|
||||
HideoutHelper _hideoutHelper,
|
||||
DatabaseService _databaseService,
|
||||
ServerLocalisationService _serverLocalisationService,
|
||||
ConfigServer _configServer,
|
||||
InventoryHelper _inventoryHelper
|
||||
ISptLogger<ProfileFixerService> logger,
|
||||
JsonUtil jsonUtil,
|
||||
RewardHelper rewardHelper,
|
||||
TraderHelper traderHelper,
|
||||
HideoutHelper hideoutHelper,
|
||||
DatabaseService databaseService,
|
||||
ServerLocalisationService serverLocalisationService,
|
||||
ConfigServer configServer,
|
||||
InventoryHelper inventoryHelper
|
||||
)
|
||||
{
|
||||
protected readonly List<string> _areas = ["hideout", "main"];
|
||||
protected readonly CoreConfig _coreConfig = _configServer.GetConfig<CoreConfig>();
|
||||
protected readonly CoreConfig _coreConfig = configServer.GetConfig<CoreConfig>();
|
||||
|
||||
/// <summary>
|
||||
/// Find issues in the pmc profile data that may cause issues and fix them
|
||||
@@ -118,17 +118,17 @@ public class ProfileFixerService(
|
||||
continue;
|
||||
}
|
||||
|
||||
_logger.Warning(
|
||||
logger.Warning(
|
||||
$"{mappingKvP.Value.Count - 1} duplicate(s) found for item: {mappingKvP.Key}"
|
||||
);
|
||||
var itemAJson = _jsonUtil.Serialize(mappingKvP.Value[0]);
|
||||
var itemBJson = _jsonUtil.Serialize(mappingKvP.Value[1]);
|
||||
var itemAJson = jsonUtil.Serialize(mappingKvP.Value[0]);
|
||||
var itemBJson = jsonUtil.Serialize(mappingKvP.Value[1]);
|
||||
if (itemAJson == itemBJson)
|
||||
{
|
||||
// Both items match, we can safely delete one (A)
|
||||
var indexOfItemToRemove = pmcProfile.Inventory.Items.IndexOf(mappingKvP.Value[0]);
|
||||
pmcProfile.Inventory.Items.RemoveAt(indexOfItemToRemove);
|
||||
_logger.Warning($"Deleted duplicate item: {mappingKvP.Key}");
|
||||
logger.Warning($"Deleted duplicate item: {mappingKvP.Key}");
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -143,7 +143,7 @@ public class ProfileFixerService(
|
||||
x.Id == mappingKvP.Key
|
||||
);
|
||||
itemToAdjust.Id = new MongoId();
|
||||
_logger.Warning(
|
||||
logger.Warning(
|
||||
$"Replace duplicate item Id: {mappingKvP.Key} with {itemToAdjust.Id}"
|
||||
);
|
||||
}
|
||||
@@ -163,14 +163,14 @@ public class ProfileFixerService(
|
||||
var regxp = new Regex("[^a-zA-Z0-9 -]");
|
||||
if (item.Upd.Tag?.Name is not null && !regxp.IsMatch(item.Upd.Tag.Name))
|
||||
{
|
||||
_logger.Warning($"Fixed item: {item.Id}s Tag value, removed invalid characters");
|
||||
logger.Warning($"Fixed item: {item.Id}s Tag value, removed invalid characters");
|
||||
item.Upd.Tag.Name = regxp.Replace(item.Upd.Tag.Name, "");
|
||||
}
|
||||
|
||||
// Check items with StackObjectsCount (undefined)
|
||||
if (item.Upd.StackObjectsCount is null)
|
||||
{
|
||||
_logger.Warning(
|
||||
logger.Warning(
|
||||
$"Fixed item: {item.Id}s undefined StackObjectsCount value, now set to 1"
|
||||
);
|
||||
item.Upd.StackObjectsCount = 1;
|
||||
@@ -178,7 +178,7 @@ public class ProfileFixerService(
|
||||
}
|
||||
|
||||
// Iterate over clothing
|
||||
var customizationDb = _databaseService.GetTemplates().Customization;
|
||||
var customizationDb = databaseService.GetTemplates().Customization;
|
||||
var customizationDbArray = customizationDb.Values;
|
||||
var playerIsUsec = string.Equals(
|
||||
pmcProfile.Info.Side,
|
||||
@@ -258,7 +258,7 @@ public class ProfileFixerService(
|
||||
|
||||
var taskConditionKeysToRemove = new List<string>();
|
||||
var activeRepeatableQuests = GetActiveRepeatableQuests(pmcProfile.RepeatableQuests);
|
||||
var achievements = _databaseService.GetAchievements();
|
||||
var achievements = databaseService.GetAchievements();
|
||||
|
||||
// Loop over TaskConditionCounters objects and add once we want to remove to counterKeysToRemove
|
||||
foreach (var TaskConditionCounterKvP in pmcProfile.TaskConditionCounters)
|
||||
@@ -286,9 +286,9 @@ public class ProfileFixerService(
|
||||
|
||||
foreach (var counterKeyToRemove in taskConditionKeysToRemove)
|
||||
{
|
||||
if (_logger.IsLogEnabled(LogLevel.Debug))
|
||||
if (logger.IsLogEnabled(LogLevel.Debug))
|
||||
{
|
||||
_logger.Debug($"Removed: {counterKeyToRemove} TaskConditionCounter object");
|
||||
logger.Debug($"Removed: {counterKeyToRemove} TaskConditionCounter object");
|
||||
}
|
||||
|
||||
pmcProfile.TaskConditionCounters.Remove(counterKeyToRemove);
|
||||
@@ -319,7 +319,7 @@ public class ProfileFixerService(
|
||||
/// <param name="pmcProfile">Profile to remove dead quests from</param>
|
||||
protected void RemoveOrphanedQuests(PmcData pmcProfile)
|
||||
{
|
||||
var quests = _databaseService.GetQuests();
|
||||
var quests = databaseService.GetQuests();
|
||||
var profileQuests = pmcProfile.Quests;
|
||||
|
||||
var activeRepeatableQuests = GetActiveRepeatableQuests(pmcProfile.RepeatableQuests);
|
||||
@@ -333,7 +333,7 @@ public class ProfileFixerService(
|
||||
)
|
||||
)
|
||||
{
|
||||
_logger.Info(
|
||||
logger.Info(
|
||||
$"Successfully removed orphaned quest: {profileQuests[i].QId} that doesn't exist in quest data"
|
||||
);
|
||||
profileQuests.RemoveAt(i);
|
||||
@@ -347,7 +347,7 @@ public class ProfileFixerService(
|
||||
/// <param name="pmcProfile">The profile to validate quest productions for</param>
|
||||
protected void VerifyQuestProductionUnlocks(PmcData pmcProfile)
|
||||
{
|
||||
var quests = _databaseService.GetQuests();
|
||||
var quests = databaseService.GetQuests();
|
||||
var profileQuests = pmcProfile.Quests;
|
||||
|
||||
foreach (var profileQuest in profileQuests)
|
||||
@@ -404,15 +404,15 @@ public class ProfileFixerService(
|
||||
Quest questDetails
|
||||
)
|
||||
{
|
||||
var matchingProductions = _rewardHelper.GetRewardProductionMatch(
|
||||
var matchingProductions = rewardHelper.GetRewardProductionMatch(
|
||||
productionUnlockReward,
|
||||
questDetails.Id
|
||||
);
|
||||
|
||||
if (matchingProductions.Count != 1)
|
||||
{
|
||||
_logger.Error(
|
||||
_serverLocalisationService.GetText(
|
||||
logger.Error(
|
||||
serverLocalisationService.GetText(
|
||||
"quest-unable_to_find_matching_hideout_production",
|
||||
new
|
||||
{
|
||||
@@ -431,9 +431,9 @@ public class ProfileFixerService(
|
||||
{
|
||||
pmcProfile.UnlockedInfo.UnlockedProductionRecipe.Add(matchingProductionId);
|
||||
|
||||
if (_logger.IsLogEnabled(LogLevel.Debug))
|
||||
if (logger.IsLogEnabled(LogLevel.Debug))
|
||||
{
|
||||
_logger.Debug(
|
||||
logger.Debug(
|
||||
$"Added production: {matchingProductionId} to unlocked production recipes for: {questDetails.QuestName}"
|
||||
);
|
||||
}
|
||||
@@ -462,7 +462,7 @@ public class ProfileFixerService(
|
||||
/// <param name="pmcProfile">profile to add slots to</param>
|
||||
protected void AddHideoutEliteSlots(PmcData pmcProfile)
|
||||
{
|
||||
var globals = _databaseService.GetGlobals();
|
||||
var globals = databaseService.GetGlobals();
|
||||
|
||||
var generator = pmcProfile.Hideout.Areas.FirstOrDefault(area =>
|
||||
area.Type == HideoutAreas.Generator
|
||||
@@ -480,9 +480,9 @@ public class ProfileFixerService(
|
||||
|
||||
if (genSlots < 6 + extraGenSlots)
|
||||
{
|
||||
if (_logger.IsLogEnabled(LogLevel.Debug))
|
||||
if (logger.IsLogEnabled(LogLevel.Debug))
|
||||
{
|
||||
_logger.Debug(
|
||||
logger.Debug(
|
||||
"Updating generator area slots to a size of 6 + hideout management skill"
|
||||
);
|
||||
}
|
||||
@@ -508,9 +508,9 @@ public class ProfileFixerService(
|
||||
|
||||
if (waterCollSlots < 1 + extraWaterCollSlots)
|
||||
{
|
||||
if (_logger.IsLogEnabled(LogLevel.Debug))
|
||||
if (logger.IsLogEnabled(LogLevel.Debug))
|
||||
{
|
||||
_logger.Debug(
|
||||
logger.Debug(
|
||||
"Updating water collector area slots to a size of 1 + hideout management skill"
|
||||
);
|
||||
}
|
||||
@@ -535,9 +535,9 @@ public class ProfileFixerService(
|
||||
|
||||
if (filterSlots < 3 + extraFilterSlots)
|
||||
{
|
||||
if (_logger.IsLogEnabled(LogLevel.Debug))
|
||||
if (logger.IsLogEnabled(LogLevel.Debug))
|
||||
{
|
||||
_logger.Debug(
|
||||
logger.Debug(
|
||||
"Updating air filter area slots to a size of 3 + hideout management skill"
|
||||
);
|
||||
}
|
||||
@@ -563,9 +563,9 @@ public class ProfileFixerService(
|
||||
// BTC Farm doesnt have extra slots for hideout management, but we still check for modded stuff!!
|
||||
if (btcFarmSlots < 50 + extraBtcSlots)
|
||||
{
|
||||
if (_logger.IsLogEnabled(LogLevel.Debug))
|
||||
if (logger.IsLogEnabled(LogLevel.Debug))
|
||||
{
|
||||
_logger.Debug(
|
||||
logger.Debug(
|
||||
"Updating bitcoin farm area slots to a size of 50 + hideout management skill"
|
||||
);
|
||||
}
|
||||
@@ -582,9 +582,9 @@ public class ProfileFixerService(
|
||||
.Slots.Count;
|
||||
if (cultistAreaSlots < 1)
|
||||
{
|
||||
if (_logger.IsLogEnabled(LogLevel.Debug))
|
||||
if (logger.IsLogEnabled(LogLevel.Debug))
|
||||
{
|
||||
_logger.Debug("Updating cultist area slots to a size of 1");
|
||||
logger.Debug("Updating cultist area slots to a size of 1");
|
||||
}
|
||||
|
||||
AddEmptyObjectsToHideoutAreaSlots(HideoutAreas.CircleOfCultists, 1, pmcProfile);
|
||||
@@ -639,9 +639,9 @@ public class ProfileFixerService(
|
||||
/// </summary>
|
||||
/// <param name="sessionId"> Session ID </param>
|
||||
/// <param name="fullProfile"> Profile to check inventory of </param>
|
||||
public void CheckForOrphanedModdedItems(string sessionId, SptProfile fullProfile)
|
||||
public void CheckForOrphanedModdedItems(MongoId sessionId, SptProfile fullProfile)
|
||||
{
|
||||
var itemsDb = _databaseService.GetItems();
|
||||
var itemsDb = databaseService.GetItems();
|
||||
var pmcProfile = fullProfile.CharacterData.PmcData;
|
||||
|
||||
// Get items placed in root of stash
|
||||
@@ -656,18 +656,18 @@ public class ProfileFixerService(
|
||||
{
|
||||
if (!itemsDb.ContainsKey(item.Template))
|
||||
{
|
||||
_logger.Error(
|
||||
_serverLocalisationService.GetText("fixer-mod_item_found", item.Template)
|
||||
logger.Error(
|
||||
serverLocalisationService.GetText("fixer-mod_item_found", item.Template)
|
||||
);
|
||||
|
||||
if (_coreConfig.Fixes.RemoveModItemsFromProfile)
|
||||
{
|
||||
_logger.Success(
|
||||
logger.Success(
|
||||
$"Deleting item from inventory and insurance with id: {item.Id} tpl: {item.Template}"
|
||||
);
|
||||
|
||||
// also deletes from insured array
|
||||
_inventoryHelper.RemoveItem(pmcProfile, item.Id, sessionId);
|
||||
inventoryHelper.RemoveItem(pmcProfile, item.Id, sessionId);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -732,18 +732,15 @@ public class ProfileFixerService(
|
||||
// Check item exists in itemsDb
|
||||
if (!itemsDb.ContainsKey(item.Template))
|
||||
{
|
||||
_logger.Error(
|
||||
_serverLocalisationService.GetText(
|
||||
"fixer-mod_item_found",
|
||||
item.Template
|
||||
)
|
||||
logger.Error(
|
||||
serverLocalisationService.GetText("fixer-mod_item_found", item.Template)
|
||||
);
|
||||
}
|
||||
|
||||
if (_coreConfig.Fixes.RemoveModItemsFromProfile)
|
||||
{
|
||||
dialog.Value.Messages.Remove(message);
|
||||
_logger.Warning(
|
||||
logger.Warning(
|
||||
$"Item: {item.Template} has resulted in the deletion of message: {message.Id} from dialog {dialog}"
|
||||
);
|
||||
}
|
||||
@@ -753,7 +750,7 @@ public class ProfileFixerService(
|
||||
}
|
||||
}
|
||||
|
||||
var clothingDb = _databaseService.GetTemplates().Customization;
|
||||
var clothingDb = databaseService.GetTemplates().Customization;
|
||||
foreach (
|
||||
var clothingItem in fullProfile.CustomisationUnlocks.Where(customisation =>
|
||||
customisation.Type == CustomisationType.SUITE
|
||||
@@ -763,14 +760,14 @@ public class ProfileFixerService(
|
||||
if (!clothingDb.ContainsKey(clothingItem.Id))
|
||||
{
|
||||
// Item in profile not found in db, not good
|
||||
_logger.Error(
|
||||
_serverLocalisationService.GetText("fixer-clothing_item_found", clothingItem)
|
||||
logger.Error(
|
||||
serverLocalisationService.GetText("fixer-clothing_item_found", clothingItem)
|
||||
);
|
||||
|
||||
if (_coreConfig.Fixes.RemoveModItemsFromProfile)
|
||||
{
|
||||
fullProfile.CustomisationUnlocks.Remove(clothingItem);
|
||||
_logger.Warning(
|
||||
logger.Warning(
|
||||
$"Non-default clothing purchase: {clothingItem} removed from profile"
|
||||
);
|
||||
}
|
||||
@@ -789,17 +786,17 @@ public class ProfileFixerService(
|
||||
|
||||
foreach (var activeQuest in repeatable.ActiveQuests.ToArray())
|
||||
{
|
||||
if (!_traderHelper.TraderExists(activeQuest.TraderId))
|
||||
if (!traderHelper.TraderExists(activeQuest.TraderId))
|
||||
{
|
||||
_logger.Error(
|
||||
_serverLocalisationService.GetText(
|
||||
logger.Error(
|
||||
serverLocalisationService.GetText(
|
||||
"fixer-trader_found",
|
||||
activeQuest.TraderId
|
||||
)
|
||||
);
|
||||
if (_coreConfig.Fixes.RemoveModItemsFromProfile)
|
||||
{
|
||||
_logger.Warning(
|
||||
logger.Warning(
|
||||
$"Non-default quest: {activeQuest.Id} from trader: {activeQuest.TraderId} removed from RepeatableQuests list in profile"
|
||||
);
|
||||
repeatable.ActiveQuests.Remove(activeQuest);
|
||||
@@ -823,7 +820,7 @@ public class ProfileFixerService(
|
||||
{
|
||||
if (!itemsDb.ContainsKey(item.Template))
|
||||
{
|
||||
_logger.Warning(
|
||||
logger.Warning(
|
||||
$"Non-default quest: {activeQuest.Id} from trader: {activeQuest.TraderId} removed from RepeatableQuests list in profile"
|
||||
);
|
||||
repeatable.ActiveQuests.Remove(activeQuest);
|
||||
@@ -834,16 +831,16 @@ public class ProfileFixerService(
|
||||
|
||||
foreach (
|
||||
var TraderPurchaseKvP in fullProfile.TraderPurchases.Where(TraderPurchase =>
|
||||
!_traderHelper.TraderExists(TraderPurchase.Key)
|
||||
!traderHelper.TraderExists(TraderPurchase.Key)
|
||||
)
|
||||
)
|
||||
{
|
||||
_logger.Error(
|
||||
_serverLocalisationService.GetText("fixer-trader_found", TraderPurchaseKvP.Key)
|
||||
logger.Error(
|
||||
serverLocalisationService.GetText("fixer-trader_found", TraderPurchaseKvP.Key)
|
||||
);
|
||||
if (_coreConfig.Fixes.RemoveModItemsFromProfile)
|
||||
{
|
||||
_logger.Warning(
|
||||
logger.Warning(
|
||||
$"Non-default trader: {TraderPurchaseKvP.Key} purchase removed from traderPurchases list in profile"
|
||||
);
|
||||
fullProfile.TraderPurchases.Remove(TraderPurchaseKvP.Key);
|
||||
@@ -873,13 +870,13 @@ public class ProfileFixerService(
|
||||
)
|
||||
)
|
||||
{
|
||||
_logger.Error(
|
||||
_serverLocalisationService.GetText("fixer-mod_item_found", item.Template)
|
||||
logger.Error(
|
||||
serverLocalisationService.GetText("fixer-mod_item_found", item.Template)
|
||||
);
|
||||
|
||||
if (_coreConfig.Fixes.RemoveModItemsFromProfile)
|
||||
{
|
||||
_logger.Warning(
|
||||
logger.Warning(
|
||||
$"Item: {item.Template} has resulted in the deletion of {buildType} build: {build.Name}"
|
||||
);
|
||||
|
||||
@@ -901,13 +898,13 @@ public class ProfileFixerService(
|
||||
)
|
||||
)
|
||||
{
|
||||
_logger.Error(
|
||||
_serverLocalisationService.GetText("fixer-mod_item_found", item.Template)
|
||||
logger.Error(
|
||||
serverLocalisationService.GetText("fixer-mod_item_found", item.Template)
|
||||
);
|
||||
|
||||
if (_coreConfig.Fixes.RemoveModItemsFromProfile)
|
||||
{
|
||||
_logger.Warning(
|
||||
logger.Warning(
|
||||
$"Item: {item.Template} has resulted in the deletion of {buildType} build: {build.Name}"
|
||||
);
|
||||
|
||||
@@ -944,13 +941,13 @@ public class ProfileFixerService(
|
||||
// Check item exists in itemsDb
|
||||
if (!itemsDb.ContainsKey(item.TemplateId))
|
||||
{
|
||||
_logger.Error(
|
||||
_serverLocalisationService.GetText("fixer-mod_item_found", item.TemplateId)
|
||||
logger.Error(
|
||||
serverLocalisationService.GetText("fixer-mod_item_found", item.TemplateId)
|
||||
);
|
||||
|
||||
if (_coreConfig.Fixes.RemoveModItemsFromProfile)
|
||||
{
|
||||
_logger.Warning(
|
||||
logger.Warning(
|
||||
$"Item: {item.TemplateId} has resulted in the deletion of magazine build: {magazineBuild.Name}"
|
||||
);
|
||||
|
||||
@@ -1018,10 +1015,10 @@ public class ProfileFixerService(
|
||||
if (profileBonus is null)
|
||||
{
|
||||
// no bonus, add to profile
|
||||
_logger.Debug(
|
||||
logger.Debug(
|
||||
$"Profile has level {level} area {profileArea.Type} but no bonus found, adding {bonus.Type}"
|
||||
);
|
||||
_hideoutHelper.ApplyPlayerUpgradesBonuses(pmcProfile, bonus);
|
||||
hideoutHelper.ApplyPlayerUpgradesBonuses(pmcProfile, bonus);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1061,12 +1058,12 @@ public class ProfileFixerService(
|
||||
foreach (var traderKvP in fullProfile.CharacterData?.PmcData?.TradersInfo)
|
||||
{
|
||||
var traderId = traderKvP.Key;
|
||||
if (!_traderHelper.TraderExists(traderId))
|
||||
if (!traderHelper.TraderExists(traderId))
|
||||
{
|
||||
_logger.Error(_serverLocalisationService.GetText("fixer-trader_found", traderId));
|
||||
logger.Error(serverLocalisationService.GetText("fixer-trader_found", traderId));
|
||||
if (_coreConfig.Fixes.RemoveInvalidTradersFromProfile)
|
||||
{
|
||||
_logger.Warning(
|
||||
logger.Warning(
|
||||
$"Non - default trader: {traderId} removed from PMC TradersInfo in: {fullProfile.ProfileInfo?.ProfileId} profile"
|
||||
);
|
||||
fullProfile.CharacterData.PmcData.TradersInfo.Remove(traderId);
|
||||
@@ -1077,12 +1074,12 @@ public class ProfileFixerService(
|
||||
foreach (var traderKvP in fullProfile.CharacterData.ScavData?.TradersInfo)
|
||||
{
|
||||
var traderId = traderKvP.Key;
|
||||
if (!_traderHelper.TraderExists(traderId))
|
||||
if (!traderHelper.TraderExists(traderId))
|
||||
{
|
||||
_logger.Error(_serverLocalisationService.GetText("fixer-trader_found", traderId));
|
||||
logger.Error(serverLocalisationService.GetText("fixer-trader_found", traderId));
|
||||
if (_coreConfig.Fixes.RemoveInvalidTradersFromProfile)
|
||||
{
|
||||
_logger.Warning(
|
||||
logger.Warning(
|
||||
$"Non - default trader: {traderId} removed from Scav TradersInfo in: {fullProfile.ProfileInfo?.ProfileId} profile"
|
||||
);
|
||||
fullProfile.CharacterData.ScavData.TradersInfo.Remove(traderId);
|
||||
|
||||
@@ -9,8 +9,8 @@ namespace SPTarkov.Server.Core.Services;
|
||||
|
||||
[Injectable(InjectionType.Singleton)]
|
||||
public class RagfairCategoriesService(
|
||||
ISptLogger<RagfairCategoriesService> _logger,
|
||||
PaymentHelper _paymentHelper
|
||||
ISptLogger<RagfairCategoriesService> logger,
|
||||
PaymentHelper paymentHelper
|
||||
)
|
||||
{
|
||||
/// <summary>
|
||||
@@ -47,7 +47,7 @@ public class RagfairCategoriesService(
|
||||
&& searchRequestData.RemoveBartering.GetValueOrDefault(false)
|
||||
&& (
|
||||
offer.Requirements.Count > 1
|
||||
|| !_paymentHelper.IsMoneyTpl(offer.Requirements.FirstOrDefault().Template)
|
||||
|| !paymentHelper.IsMoneyTpl(offer.Requirements.FirstOrDefault().Template)
|
||||
)
|
||||
)
|
||||
{
|
||||
|
||||
@@ -62,7 +62,7 @@ public class RagfairLinkedItemService(
|
||||
/// </summary>
|
||||
protected void BuildLinkedItemTable()
|
||||
{
|
||||
var linkedItems = new Dictionary<string, HashSet<MongoId>>();
|
||||
var linkedItems = new Dictionary<MongoId, HashSet<MongoId>>();
|
||||
|
||||
foreach (var item in databaseService.GetItems().Values)
|
||||
{
|
||||
|
||||
@@ -102,7 +102,7 @@ public class RagfairOfferService(
|
||||
/// Remove all offers from ragfair made by trader
|
||||
/// </summary>
|
||||
/// <param name="traderId">Trader to remove offers for</param>
|
||||
public void RemoveAllOffersByTrader(string traderId)
|
||||
public void RemoveAllOffersByTrader(MongoId traderId)
|
||||
{
|
||||
ragfairOfferHolder.RemoveAllOffersByTrader(traderId);
|
||||
}
|
||||
@@ -112,7 +112,7 @@ public class RagfairOfferService(
|
||||
/// </summary>
|
||||
/// <param name="traderID"> Trader to check </param>
|
||||
/// <returns> True if they do </returns>
|
||||
public bool TraderOffersNeedRefreshing(string traderID)
|
||||
public bool TraderOffersNeedRefreshing(MongoId traderID)
|
||||
{
|
||||
var trader = databaseService.GetTrader(traderID);
|
||||
if (trader?.Base == null)
|
||||
@@ -175,7 +175,7 @@ public class RagfairOfferService(
|
||||
/// </summary>
|
||||
/// <param name="staleOfferId"> Stale offer id to process </param>
|
||||
/// <param name="flagOfferAsExpired">OPTIONAL - Flag the passed in offer as expired default = true</param>
|
||||
protected void ProcessStaleOffer(string staleOfferId, bool flagOfferAsExpired = true)
|
||||
protected void ProcessStaleOffer(MongoId staleOfferId, bool flagOfferAsExpired = true)
|
||||
{
|
||||
var staleOffer = ragfairOfferHolder.GetOfferById(staleOfferId);
|
||||
if (staleOffer is null)
|
||||
|
||||
@@ -17,18 +17,18 @@ namespace SPTarkov.Server.Core.Services;
|
||||
/// </summary>
|
||||
[Injectable(InjectionType.Singleton)]
|
||||
public class RagfairPriceService(
|
||||
ISptLogger<RagfairPriceService> _logger,
|
||||
RandomUtil _randomUtil,
|
||||
HandbookHelper _handbookHelper,
|
||||
TraderHelper _traderHelper,
|
||||
PresetHelper _presetHelper,
|
||||
ItemHelper _itemHelper,
|
||||
DatabaseService _databaseService,
|
||||
ServerLocalisationService _serverLocalisationService,
|
||||
ConfigServer _configServer
|
||||
ISptLogger<RagfairPriceService> logger,
|
||||
RandomUtil randomUtil,
|
||||
HandbookHelper handbookHelper,
|
||||
TraderHelper traderHelper,
|
||||
PresetHelper presetHelper,
|
||||
ItemHelper itemHelper,
|
||||
DatabaseService databaseService,
|
||||
ServerLocalisationService serverLocalisationService,
|
||||
ConfigServer configServer
|
||||
)
|
||||
{
|
||||
private readonly RagfairConfig _ragfairConfig = _configServer.GetConfig<RagfairConfig>();
|
||||
private readonly RagfairConfig _ragfairConfig = configServer.GetConfig<RagfairConfig>();
|
||||
protected Dictionary<MongoId, double>? _staticPrices;
|
||||
|
||||
/// <summary>
|
||||
@@ -52,14 +52,14 @@ public class RagfairPriceService(
|
||||
{
|
||||
_staticPrices = new Dictionary<MongoId, double>();
|
||||
foreach (
|
||||
var item in _databaseService
|
||||
var item in databaseService
|
||||
.GetItems()
|
||||
.Values.Where(item =>
|
||||
string.Equals(item.Type, "Item", StringComparison.OrdinalIgnoreCase)
|
||||
)
|
||||
)
|
||||
{
|
||||
_staticPrices[item.Id] = _handbookHelper.GetTemplatePrice(item.Id);
|
||||
_staticPrices[item.Id] = handbookHelper.GetTemplatePrice(item.Id);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -80,12 +80,12 @@ public class RagfairPriceService(
|
||||
public double GetFleaPriceForItem(MongoId tplId)
|
||||
{
|
||||
// Get dynamic price (templates/prices), if that doesn't exist get price from static array (templates/handbook)
|
||||
var itemPrice = _itemHelper.GetDynamicItemPrice(tplId) ?? GetStaticPriceForItem(tplId);
|
||||
var itemPrice = itemHelper.GetDynamicItemPrice(tplId) ?? GetStaticPriceForItem(tplId);
|
||||
if (itemPrice is null)
|
||||
{
|
||||
var itemFromDb = _itemHelper.GetItem(tplId);
|
||||
_logger.Warning(
|
||||
_serverLocalisationService.GetText(
|
||||
var itemFromDb = itemHelper.GetItem(tplId);
|
||||
logger.Warning(
|
||||
serverLocalisationService.GetText(
|
||||
"ragfair-unable_to_find_item_price_for_item_in_flea_handbook",
|
||||
new { tpl = tplId, name = itemFromDb.Value.Name ?? "" }
|
||||
)
|
||||
@@ -109,7 +109,7 @@ public class RagfairPriceService(
|
||||
public double GetFleaPriceForOfferItems(List<Item> offerItems)
|
||||
{
|
||||
// Preset weapons take the direct prices.json value, otherwise they're massively inflated
|
||||
if (_itemHelper.IsOfBaseclass(offerItems[0].Template, BaseClasses.WEAPON))
|
||||
if (itemHelper.IsOfBaseclass(offerItems[0].Template, BaseClasses.WEAPON))
|
||||
{
|
||||
return GetFleaPriceForItem(offerItems[0].Template);
|
||||
}
|
||||
@@ -124,7 +124,7 @@ public class RagfairPriceService(
|
||||
/// <returns> Price in roubles </returns>
|
||||
public double? GetDynamicPriceForItem(MongoId itemTpl)
|
||||
{
|
||||
_databaseService.GetPrices().TryGetValue(itemTpl, out var value);
|
||||
databaseService.GetPrices().TryGetValue(itemTpl, out var value);
|
||||
|
||||
return value;
|
||||
}
|
||||
@@ -136,7 +136,7 @@ public class RagfairPriceService(
|
||||
/// <returns>price in roubles</returns>
|
||||
public double? GetStaticPriceForItem(MongoId itemTpl)
|
||||
{
|
||||
return _handbookHelper.GetTemplatePrice(itemTpl);
|
||||
return handbookHelper.GetTemplatePrice(itemTpl);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -146,7 +146,7 @@ public class RagfairPriceService(
|
||||
/// <returns>Dictionary of item tpls and rouble cost</returns>
|
||||
public Dictionary<MongoId, double> GetAllFleaPrices()
|
||||
{
|
||||
var dynamicPrices = _databaseService.GetPrices();
|
||||
var dynamicPrices = databaseService.GetPrices();
|
||||
// Use dynamic prices first, fill in any gaps with data from static prices (handbook)
|
||||
return dynamicPrices
|
||||
.Concat(_staticPrices)
|
||||
@@ -213,7 +213,7 @@ public class RagfairPriceService(
|
||||
foreach (var item in offerItems)
|
||||
{
|
||||
// Skip over armor inserts as those are not factored into item prices.
|
||||
if (_itemHelper.IsOfBaseclass(item.Template, BaseClasses.BUILT_IN_INSERTS))
|
||||
if (itemHelper.IsOfBaseclass(item.Template, BaseClasses.BUILT_IN_INSERTS))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
@@ -229,7 +229,7 @@ public class RagfairPriceService(
|
||||
// Check if the item is a weapon preset.
|
||||
if (
|
||||
item?.Upd?.SptPresetId is not null
|
||||
&& _presetHelper.IsPresetBaseClass(item.Upd.SptPresetId, BaseClasses.WEAPON)
|
||||
&& presetHelper.IsPresetBaseClass(item.Upd.SptPresetId, BaseClasses.WEAPON)
|
||||
)
|
||||
// This is a weapon preset, which has it's own price calculation that takes into account the mods in the
|
||||
// preset. Since we've already calculated the price for the preset entire preset in
|
||||
@@ -252,7 +252,7 @@ public class RagfairPriceService(
|
||||
/// <returns></returns>
|
||||
public double? GetDynamicItemPrice(
|
||||
MongoId itemTemplateId,
|
||||
string desiredCurrency,
|
||||
MongoId desiredCurrency,
|
||||
Item? item = null,
|
||||
List<Item>? offerItems = null,
|
||||
bool? isPackOffer = null
|
||||
@@ -270,7 +270,7 @@ public class RagfairPriceService(
|
||||
// Use trader price if higher, based on config.
|
||||
if (_ragfairConfig.Dynamic.UseTraderPriceForOffersIfHigher)
|
||||
{
|
||||
var traderPrice = _traderHelper.GetHighestSellToTraderPrice(itemTemplateId);
|
||||
var traderPrice = traderHelper.GetHighestSellToTraderPrice(itemTemplateId);
|
||||
if (traderPrice > price)
|
||||
{
|
||||
price = traderPrice;
|
||||
@@ -281,7 +281,7 @@ public class RagfairPriceService(
|
||||
if (
|
||||
item?.Upd?.SptPresetId is not null
|
||||
&& offerItems is not null
|
||||
&& _presetHelper.IsPresetBaseClass(item.Upd.SptPresetId, BaseClasses.WEAPON)
|
||||
&& presetHelper.IsPresetBaseClass(item.Upd.SptPresetId, BaseClasses.WEAPON)
|
||||
)
|
||||
{
|
||||
price = GetWeaponPresetPrice(item, offerItems, price);
|
||||
@@ -305,14 +305,14 @@ public class RagfairPriceService(
|
||||
&& !_ragfairConfig.Dynamic.IgnoreQualityPriceVarianceBlacklist.Contains(itemTemplateId)
|
||||
)
|
||||
{
|
||||
var qualityModifier = _itemHelper.GetItemQualityModifier(item);
|
||||
var qualityModifier = itemHelper.GetItemQualityModifier(item);
|
||||
price *= qualityModifier;
|
||||
}
|
||||
|
||||
// Make adjustments for unreasonably priced items.
|
||||
foreach (var (key, value) in _ragfairConfig.Dynamic.UnreasonableModPrices)
|
||||
{
|
||||
if (!_itemHelper.IsOfBaseclass(itemTemplateId, key) || !value.Enabled)
|
||||
if (!itemHelper.IsOfBaseclass(itemTemplateId, key) || !value.Enabled)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
@@ -327,7 +327,7 @@ public class RagfairPriceService(
|
||||
// Convert to different currency if required.
|
||||
if (desiredCurrency != Money.ROUBLES)
|
||||
{
|
||||
price = _handbookHelper.FromRUB(price, desiredCurrency);
|
||||
price = handbookHelper.FromRUB(price, desiredCurrency);
|
||||
}
|
||||
|
||||
if (price <= 0)
|
||||
@@ -351,7 +351,7 @@ public class RagfairPriceService(
|
||||
double price
|
||||
)
|
||||
{
|
||||
var itemHandbookPrice = _handbookHelper.GetTemplatePrice(itemTpl);
|
||||
var itemHandbookPrice = handbookHelper.GetTemplatePrice(itemTpl);
|
||||
if (itemHandbookPrice > 0)
|
||||
{
|
||||
return price;
|
||||
@@ -433,7 +433,7 @@ public class RagfairPriceService(
|
||||
protected double RandomiseOfferPrice(double existingPrice, MinMax<double> rangeValues)
|
||||
{
|
||||
// Multiply by 100 to get 2 decimal places of precision
|
||||
var multiplier = _randomUtil.GetBiasedRandomNumber(
|
||||
var multiplier = randomUtil.GetBiasedRandomNumber(
|
||||
rangeValues.Min * 100,
|
||||
rangeValues.Max * 100,
|
||||
2,
|
||||
@@ -510,7 +510,7 @@ public class RagfairPriceService(
|
||||
protected double? GetHighestHandbookOrTraderPriceAsRouble(MongoId itemTpl)
|
||||
{
|
||||
var price = GetStaticPriceForItem(itemTpl);
|
||||
var traderPrice = _traderHelper.GetHighestSellToTraderPrice(itemTpl);
|
||||
var traderPrice = traderHelper.GetHighestSellToTraderPrice(itemTpl);
|
||||
if (traderPrice > price)
|
||||
{
|
||||
price = traderPrice;
|
||||
@@ -527,17 +527,17 @@ public class RagfairPriceService(
|
||||
/// <returns>Default preset object</returns>
|
||||
protected WeaponPreset GetWeaponPreset(Item weapon)
|
||||
{
|
||||
var defaultPreset = _presetHelper.GetDefaultPreset(weapon.Template);
|
||||
var defaultPreset = presetHelper.GetDefaultPreset(weapon.Template);
|
||||
if (defaultPreset is not null)
|
||||
{
|
||||
return new WeaponPreset { IsDefault = true, Preset = defaultPreset };
|
||||
}
|
||||
|
||||
var nonDefaultPresets = _presetHelper.GetPresets(weapon.Template);
|
||||
var nonDefaultPresets = presetHelper.GetPresets(weapon.Template);
|
||||
|
||||
if (_logger.IsLogEnabled(LogLevel.Debug))
|
||||
if (logger.IsLogEnabled(LogLevel.Debug))
|
||||
{
|
||||
_logger.Debug(
|
||||
logger.Debug(
|
||||
nonDefaultPresets.Count == 1
|
||||
? $"Item Id: {weapon.Template} has no default encyclopedia entry but only one preset: ({nonDefaultPresets[0].Name}), choosing preset: ({nonDefaultPresets[0].Name})"
|
||||
: $"Item Id: {weapon.Template} has no default encyclopedia entry, choosing first preset({nonDefaultPresets[0].Name}) of {nonDefaultPresets.Count}"
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
using SPTarkov.DI.Annotations;
|
||||
using SPTarkov.Server.Core.Extensions;
|
||||
using SPTarkov.Server.Core.Helpers;
|
||||
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.Ragfair;
|
||||
@@ -13,11 +14,11 @@ namespace SPTarkov.Server.Core.Services;
|
||||
|
||||
[Injectable(InjectionType.Singleton)]
|
||||
public class RagfairTaxService(
|
||||
ISptLogger<RagfairTaxService> _logger,
|
||||
DatabaseService _databaseService,
|
||||
RagfairPriceService _ragfairPriceService,
|
||||
ItemHelper _itemHelper,
|
||||
ICloner _cloner
|
||||
ISptLogger<RagfairTaxService> logger,
|
||||
DatabaseService databaseService,
|
||||
RagfairPriceService ragfairPriceService,
|
||||
ItemHelper itemHelper,
|
||||
ICloner cloner
|
||||
)
|
||||
{
|
||||
protected readonly Dictionary<
|
||||
@@ -26,7 +27,7 @@ public class RagfairTaxService(
|
||||
> _playerOfferTaxCache = new();
|
||||
|
||||
public void StoreClientOfferTaxValue(
|
||||
string sessionId,
|
||||
MongoId sessionId,
|
||||
StorePlayerOfferTaxAmountRequestData offer
|
||||
)
|
||||
{
|
||||
@@ -73,9 +74,9 @@ public class RagfairTaxService(
|
||||
return 0;
|
||||
}
|
||||
|
||||
var globals = _databaseService.GetGlobals();
|
||||
var globals = databaseService.GetGlobals();
|
||||
|
||||
var itemTemplate = _itemHelper.GetItem(item.Template).Value;
|
||||
var itemTemplate = itemHelper.GetItem(item.Template).Value;
|
||||
var itemWorth = CalculateItemWorth(item, itemTemplate, offerItemCount.Value, pmcData);
|
||||
var requirementsPrice = requirementsValue * (sellInOnePiece ? 1 : offerItemCount);
|
||||
|
||||
@@ -114,7 +115,7 @@ public class RagfairTaxService(
|
||||
if (item.Upd.Buff is not null)
|
||||
{
|
||||
var buffType = item.Upd.Buff.BuffType;
|
||||
var itemEnhancementSettings = _databaseService
|
||||
var itemEnhancementSettings = databaseService
|
||||
.GetGlobals()
|
||||
.Configuration.RepairSettings.ItemEnhancementSettings;
|
||||
var priceModiferValue = buffType switch
|
||||
@@ -138,9 +139,9 @@ public class RagfairTaxService(
|
||||
|
||||
var taxValue = Math.Round(discountedTax.Value * itemComissionMult);
|
||||
|
||||
if (_logger.IsLogEnabled(LogLevel.Debug))
|
||||
if (logger.IsLogEnabled(LogLevel.Debug))
|
||||
{
|
||||
_logger.Debug($"Tax Calculated to be: {taxValue}");
|
||||
logger.Debug($"Tax Calculated to be: {taxValue}");
|
||||
}
|
||||
|
||||
return taxValue;
|
||||
@@ -164,7 +165,7 @@ public class RagfairTaxService(
|
||||
bool isRootItem = true
|
||||
)
|
||||
{
|
||||
var worth = _ragfairPriceService.GetFleaPriceForItem(item.Template);
|
||||
var worth = ragfairPriceService.GetFleaPriceForItem(item.Template);
|
||||
|
||||
// In client, all item slots are traversed and any items contained within have their values added
|
||||
if (isRootItem)
|
||||
@@ -173,14 +174,14 @@ public class RagfairTaxService(
|
||||
var itemChildren = pmcData.Inventory.Items.FindAndReturnChildrenAsItems(item.Id);
|
||||
if (itemChildren.Count > 1)
|
||||
{
|
||||
var itemChildrenClone = _cloner.Clone(itemChildren); // Clone is expensive, only run if necessary
|
||||
var itemChildrenClone = cloner.Clone(itemChildren); // Clone is expensive, only run if necessary
|
||||
foreach (var child in itemChildrenClone.Where(child => child.Id != item.Id))
|
||||
{
|
||||
child.Upd ??= new Upd();
|
||||
|
||||
worth += CalculateItemWorth(
|
||||
child,
|
||||
_itemHelper.GetItem(child.Template).Value,
|
||||
itemHelper.GetItem(child.Template).Value,
|
||||
(int)(child.Upd.StackObjectsCount ?? 1),
|
||||
pmcData,
|
||||
false
|
||||
@@ -198,7 +199,7 @@ public class RagfairTaxService(
|
||||
|
||||
if (itemTemplate.Properties is null)
|
||||
{
|
||||
_logger.Warning(
|
||||
logger.Warning(
|
||||
$"Item: {item.Id} lacks _props and cannot have its worth calculated properly"
|
||||
);
|
||||
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
using SPTarkov.DI.Annotations;
|
||||
using SPTarkov.Server.Core.Helpers;
|
||||
using SPTarkov.Server.Core.Models.Common;
|
||||
using SPTarkov.Server.Core.Models.Eft.Common;
|
||||
using SPTarkov.Server.Core.Models.Eft.Game;
|
||||
using SPTarkov.Server.Core.Models.Enums;
|
||||
@@ -13,15 +14,15 @@ namespace SPTarkov.Server.Core.Services;
|
||||
|
||||
[Injectable(InjectionType.Singleton)]
|
||||
public class RaidTimeAdjustmentService(
|
||||
ISptLogger<RaidTimeAdjustmentService> _logger,
|
||||
DatabaseService _databaseService,
|
||||
RandomUtil _randomUtil,
|
||||
WeightedRandomHelper _weightedRandomHelper,
|
||||
ProfileActivityService _profileActivityService,
|
||||
ConfigServer _configServer
|
||||
ISptLogger<RaidTimeAdjustmentService> logger,
|
||||
DatabaseService databaseService,
|
||||
RandomUtil randomUtil,
|
||||
WeightedRandomHelper weightedRandomHelper,
|
||||
ProfileActivityService profileActivityService,
|
||||
ConfigServer configServer
|
||||
)
|
||||
{
|
||||
protected readonly LocationConfig _locationConfig = _configServer.GetConfig<LocationConfig>();
|
||||
protected readonly LocationConfig _locationConfig = configServer.GetConfig<LocationConfig>();
|
||||
|
||||
/// <summary>
|
||||
/// Make alterations to the base map data passed in
|
||||
@@ -33,7 +34,7 @@ public class RaidTimeAdjustmentService(
|
||||
{
|
||||
if (raidAdjustments.DynamicLootPercent < 100 || raidAdjustments.StaticLootPercent < 100)
|
||||
{
|
||||
_logger.Debug(
|
||||
logger.Debug(
|
||||
$"Adjusting dynamic loot multipliers to {raidAdjustments.DynamicLootPercent}% and static loot multipliers to {raidAdjustments.StaticLootPercent}% of original"
|
||||
);
|
||||
}
|
||||
@@ -64,7 +65,7 @@ public class RaidTimeAdjustmentService(
|
||||
var exitToChange = mapBase.Exits.FirstOrDefault(exit => exit.Name == exitChange.Name);
|
||||
if (exitToChange is null)
|
||||
{
|
||||
_logger.Debug($"Exit with Id: {exitChange.Name} not found, skipping");
|
||||
logger.Debug($"Exit with Id: {exitChange.Name} not found, skipping");
|
||||
|
||||
return;
|
||||
}
|
||||
@@ -105,7 +106,7 @@ public class RaidTimeAdjustmentService(
|
||||
{
|
||||
foreach (var location in mapLootMultipliers)
|
||||
{
|
||||
mapLootMultipliers[location.Key] = _randomUtil.GetPercentOfValue(
|
||||
mapLootMultipliers[location.Key] = randomUtil.GetPercentOfValue(
|
||||
mapLootMultipliers[location.Key],
|
||||
loosePercent ?? 1
|
||||
);
|
||||
@@ -134,7 +135,7 @@ public class RaidTimeAdjustmentService(
|
||||
wave.TimeMax -= (int)Math.Max(startSeconds, 0);
|
||||
}
|
||||
|
||||
_logger.Debug(
|
||||
logger.Debug(
|
||||
$"Removed {originalWaveCount - mapBase.Waves.Count} wave from map due to simulated raid start time of {raidAdjustments.SimulatedRaidStartSeconds / 60} minutes"
|
||||
);
|
||||
}
|
||||
@@ -145,10 +146,10 @@ public class RaidTimeAdjustmentService(
|
||||
/// <param name="sessionId">Session id</param>
|
||||
/// <param name="request">Raid adjustment request</param>
|
||||
/// <returns>Response to send to client</returns>
|
||||
public RaidChanges GetRaidAdjustments(string sessionId, GetRaidTimeRequest request)
|
||||
public RaidChanges GetRaidAdjustments(MongoId sessionId, GetRaidTimeRequest request)
|
||||
{
|
||||
var globals = _databaseService.GetGlobals();
|
||||
var mapBase = _databaseService.GetLocation(request.Location.ToLowerInvariant()).Base;
|
||||
var globals = databaseService.GetGlobals();
|
||||
var mapBase = databaseService.GetLocation(request.Location.ToLowerInvariant()).Base;
|
||||
var baseEscapeTimeMinutes = mapBase.EscapeTimeLimit;
|
||||
|
||||
// Prep result object to return
|
||||
@@ -177,7 +178,7 @@ public class RaidTimeAdjustmentService(
|
||||
var mapSettings = GetMapSettings(request.Location);
|
||||
|
||||
// Chance of reducing raid time for scav, not guaranteed
|
||||
if (!_randomUtil.GetChance100(mapSettings.ReducedChancePercent))
|
||||
if (!randomUtil.GetChance100(mapSettings.ReducedChancePercent))
|
||||
// Send default
|
||||
{
|
||||
return result;
|
||||
@@ -185,13 +186,13 @@ public class RaidTimeAdjustmentService(
|
||||
|
||||
// Get the weighted percent to reduce the raid time by
|
||||
var chosenRaidReductionPercent = int.Parse(
|
||||
_weightedRandomHelper.GetWeightedValue(mapSettings.ReductionPercentWeights)
|
||||
weightedRandomHelper.GetWeightedValue(mapSettings.ReductionPercentWeights)
|
||||
);
|
||||
var raidTimeRemainingPercent = 100 - chosenRaidReductionPercent;
|
||||
|
||||
// How many minutes raid will last
|
||||
var newRaidTimeMinutes = Math.Floor(
|
||||
_randomUtil.ReduceValueByPercent(baseEscapeTimeMinutes ?? 1, chosenRaidReductionPercent)
|
||||
randomUtil.ReduceValueByPercent(baseEscapeTimeMinutes ?? 1, chosenRaidReductionPercent)
|
||||
);
|
||||
|
||||
// Time player spawns into the raid if it was online
|
||||
@@ -218,7 +219,7 @@ public class RaidTimeAdjustmentService(
|
||||
);
|
||||
}
|
||||
|
||||
_logger.Debug(
|
||||
logger.Debug(
|
||||
$"Reduced: {request.Location} raid time by: {chosenRaidReductionPercent}% to {newRaidTimeMinutes} minutes"
|
||||
);
|
||||
|
||||
@@ -236,7 +237,7 @@ public class RaidTimeAdjustmentService(
|
||||
}
|
||||
|
||||
// Store state to use in loot generation
|
||||
_profileActivityService.GetProfileActivityRaidData(sessionId).RaidAdjustments = result;
|
||||
profileActivityService.GetProfileActivityRaidData(sessionId).RaidAdjustments = result;
|
||||
|
||||
return result;
|
||||
}
|
||||
@@ -248,10 +249,10 @@ public class RaidTimeAdjustmentService(
|
||||
/// <returns>ScavRaidTimeLocationSettings</returns>
|
||||
protected ScavRaidTimeLocationSettings GetMapSettings(string location)
|
||||
{
|
||||
var mapSettings = _locationConfig.ScavRaidTimeSettings.Maps?[location.ToLowerInvariant()];
|
||||
var mapSettings = _locationConfig.ScavRaidTimeSettings.Maps[location.ToLowerInvariant()];
|
||||
if (mapSettings is null)
|
||||
{
|
||||
_logger.Warning(
|
||||
logger.Warning(
|
||||
$"Unable to find scav raid time settings for map: {location}, using defaults"
|
||||
);
|
||||
return new ScavRaidTimeLocationSettings();
|
||||
@@ -325,7 +326,7 @@ public class RaidTimeAdjustmentService(
|
||||
{
|
||||
exitChange.Chance = 0;
|
||||
|
||||
_logger.Debug(
|
||||
logger.Debug(
|
||||
$"Train Exit: {exit.Name} disabled as new raid time {newRaidTimeMinutes} minutes is below {mostPossibleTimeRemainingAfterDeparture} minutes"
|
||||
);
|
||||
|
||||
@@ -338,7 +339,7 @@ public class RaidTimeAdjustmentService(
|
||||
exitChange.MinTime = Math.Max(exit.MinTime - reductionSeconds ?? 0, 0);
|
||||
exitChange.MaxTime = Math.Max(exit.MaxTime - reductionSeconds ?? 0, 0);
|
||||
|
||||
_logger.Debug(
|
||||
logger.Debug(
|
||||
$"Train appears between: {exitChange.MinTime} and {exitChange.MaxTime} seconds raid time"
|
||||
);
|
||||
|
||||
|
||||
@@ -11,14 +11,14 @@ namespace SPTarkov.Server.Core.Services;
|
||||
|
||||
[Injectable(InjectionType.Singleton)]
|
||||
public class RaidWeatherService(
|
||||
TimeUtil _timeUtil,
|
||||
WeatherGenerator _weatherGenerator,
|
||||
SeasonalEventService _seasonalEventService,
|
||||
WeightedRandomHelper _weightedRandomHelper,
|
||||
ConfigServer _configServer
|
||||
TimeUtil timeUtil,
|
||||
WeatherGenerator weatherGenerator,
|
||||
SeasonalEventService seasonalEventService,
|
||||
WeightedRandomHelper weightedRandomHelper,
|
||||
ConfigServer configServer
|
||||
)
|
||||
{
|
||||
protected readonly WeatherConfig _weatherConfig = _configServer.GetConfig<WeatherConfig>();
|
||||
protected readonly WeatherConfig _weatherConfig = configServer.GetConfig<WeatherConfig>();
|
||||
protected readonly List<Weather> _weatherForecast = [];
|
||||
|
||||
/// <summary>
|
||||
@@ -27,18 +27,18 @@ public class RaidWeatherService(
|
||||
public void GenerateWeather(Season currentSeason)
|
||||
{
|
||||
// When to start generating weather from in milliseconds
|
||||
var staringTimestamp = _timeUtil.GetTodayMidnightTimeStamp();
|
||||
var staringTimestamp = timeUtil.GetTodayMidnightTimeStamp();
|
||||
|
||||
// How far into future do we generate weather
|
||||
var futureTimestampToReach =
|
||||
staringTimestamp
|
||||
+ _timeUtil.GetHoursAsSeconds(_weatherConfig.Weather.GenerateWeatherAmountHours ?? 1);
|
||||
+ timeUtil.GetHoursAsSeconds(_weatherConfig.Weather.GenerateWeatherAmountHours ?? 1);
|
||||
|
||||
// Keep adding new weather until we have reached desired future date
|
||||
var nextTimestamp = staringTimestamp;
|
||||
while (nextTimestamp <= futureTimestampToReach)
|
||||
{
|
||||
var newWeatherToAddToCache = _weatherGenerator.GenerateWeather(
|
||||
var newWeatherToAddToCache = weatherGenerator.GenerateWeather(
|
||||
currentSeason,
|
||||
nextTimestamp
|
||||
);
|
||||
@@ -57,7 +57,7 @@ public class RaidWeatherService(
|
||||
/// <returns>milliseconds</returns>
|
||||
protected long GetWeightedWeatherTimePeriod()
|
||||
{
|
||||
var chosenTimePeriodMinutes = _weightedRandomHelper
|
||||
var chosenTimePeriodMinutes = weightedRandomHelper
|
||||
.WeightedRandom(
|
||||
_weatherConfig.Weather.TimePeriod.Values,
|
||||
_weatherConfig.Weather.TimePeriod.Weights
|
||||
@@ -72,10 +72,10 @@ public class RaidWeatherService(
|
||||
/// </summary>
|
||||
public Weather GetCurrentWeather()
|
||||
{
|
||||
var currentSeason = _seasonalEventService.GetActiveWeatherSeason();
|
||||
var currentSeason = seasonalEventService.GetActiveWeatherSeason();
|
||||
ValidateWeatherDataExists(currentSeason);
|
||||
|
||||
return _weatherForecast.Find(weather => weather.Timestamp >= _timeUtil.GetTimeStamp());
|
||||
return _weatherForecast.Find(weather => weather.Timestamp >= timeUtil.GetTimeStamp());
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -83,10 +83,10 @@ public class RaidWeatherService(
|
||||
/// </summary>
|
||||
public IEnumerable<Weather> GetUpcomingWeather()
|
||||
{
|
||||
var currentSeason = _seasonalEventService.GetActiveWeatherSeason();
|
||||
var currentSeason = seasonalEventService.GetActiveWeatherSeason();
|
||||
ValidateWeatherDataExists(currentSeason);
|
||||
|
||||
return _weatherForecast.Where(weather => weather.Timestamp >= _timeUtil.GetTimeStamp());
|
||||
return _weatherForecast.Where(weather => weather.Timestamp >= timeUtil.GetTimeStamp());
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -95,11 +95,11 @@ public class RaidWeatherService(
|
||||
protected void ValidateWeatherDataExists(Season currentSeason)
|
||||
{
|
||||
// Clear expired weather data
|
||||
_weatherForecast.RemoveAll(weather => weather.Timestamp < _timeUtil.GetTimeStamp());
|
||||
_weatherForecast.RemoveAll(weather => weather.Timestamp < timeUtil.GetTimeStamp());
|
||||
|
||||
// Check data exists for current time
|
||||
var result = _weatherForecast.Where(weather =>
|
||||
weather.Timestamp >= _timeUtil.GetTimeStamp()
|
||||
weather.Timestamp >= timeUtil.GetTimeStamp()
|
||||
);
|
||||
if (!result.Any())
|
||||
{
|
||||
|
||||
@@ -21,20 +21,20 @@ namespace SPTarkov.Server.Core.Services;
|
||||
|
||||
[Injectable(InjectionType.Singleton)]
|
||||
public class RepairService(
|
||||
ISptLogger<RepairService> _logger,
|
||||
RandomUtil _randomUtil,
|
||||
DatabaseService _databaseService,
|
||||
ItemHelper _itemHelper,
|
||||
TraderHelper _traderHelper,
|
||||
PaymentService _paymentService,
|
||||
ProfileHelper _profileHelper,
|
||||
RepairHelper _repairHelper,
|
||||
ServerLocalisationService _serverLocalisationService,
|
||||
ConfigServer _configServer,
|
||||
WeightedRandomHelper _weightedRandomHelper
|
||||
ISptLogger<RepairService> logger,
|
||||
RandomUtil randomUtil,
|
||||
DatabaseService databaseService,
|
||||
ItemHelper itemHelper,
|
||||
TraderHelper traderHelper,
|
||||
PaymentService paymentService,
|
||||
ProfileHelper profileHelper,
|
||||
RepairHelper repairHelper,
|
||||
ServerLocalisationService serverLocalisationService,
|
||||
ConfigServer configServer,
|
||||
WeightedRandomHelper weightedRandomHelper
|
||||
)
|
||||
{
|
||||
protected readonly RepairConfig _repairConfig = _configServer.GetConfig<RepairConfig>();
|
||||
protected readonly RepairConfig _repairConfig = configServer.GetConfig<RepairConfig>();
|
||||
|
||||
/// <summary>
|
||||
/// Use trader to repair an items durability
|
||||
@@ -45,10 +45,10 @@ public class RepairService(
|
||||
/// <param name="traderId">Trader being used to repair item</param>
|
||||
/// <returns>RepairDetails object</returns>
|
||||
public RepairDetails RepairItemByTrader(
|
||||
string sessionID,
|
||||
MongoId sessionID,
|
||||
PmcData pmcData,
|
||||
RepairItem repairItemDetails,
|
||||
string traderId
|
||||
MongoId traderId
|
||||
)
|
||||
{
|
||||
var itemToRepair = pmcData.Inventory.Items.FirstOrDefault(item =>
|
||||
@@ -56,20 +56,20 @@ public class RepairService(
|
||||
);
|
||||
if (itemToRepair is null)
|
||||
{
|
||||
_logger.Error(
|
||||
_serverLocalisationService.GetText(
|
||||
logger.Error(
|
||||
serverLocalisationService.GetText(
|
||||
"repair-unable_to_find_item_in_inventory_cant_repair",
|
||||
repairItemDetails.Id
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
var priceCoef = _traderHelper.GetLoyaltyLevel(traderId, pmcData).RepairPriceCoefficient;
|
||||
var traderRepairDetails = _traderHelper.GetTrader(traderId, sessionID)?.Repair;
|
||||
var priceCoef = traderHelper.GetLoyaltyLevel(traderId, pmcData).RepairPriceCoefficient;
|
||||
var traderRepairDetails = traderHelper.GetTrader(traderId, sessionID)?.Repair;
|
||||
if (traderRepairDetails is null)
|
||||
{
|
||||
_logger.Error(
|
||||
_serverLocalisationService.GetText(
|
||||
logger.Error(
|
||||
serverLocalisationService.GetText(
|
||||
"repair-unable_to_find_trader_details_by_id",
|
||||
traderId
|
||||
)
|
||||
@@ -79,11 +79,11 @@ public class RepairService(
|
||||
var repairQualityMultiplier = traderRepairDetails.Quality;
|
||||
var repairRate = priceCoef <= 0 ? 1 : priceCoef / 100 + 1;
|
||||
|
||||
var items = _databaseService.GetItems();
|
||||
var items = databaseService.GetItems();
|
||||
var itemToRepairDetails = items[itemToRepair.Template];
|
||||
var repairItemIsArmor = itemToRepairDetails.Properties.ArmorMaterial is not null;
|
||||
|
||||
_repairHelper.UpdateItemDurability(
|
||||
repairHelper.UpdateItemDurability(
|
||||
itemToRepair,
|
||||
itemToRepairDetails,
|
||||
repairItemIsArmor,
|
||||
@@ -97,8 +97,8 @@ public class RepairService(
|
||||
var itemRepairCost = items[itemToRepair.Template].Properties.RepairCost;
|
||||
if (itemRepairCost is null)
|
||||
{
|
||||
_logger.Error(
|
||||
_serverLocalisationService.GetText(
|
||||
logger.Error(
|
||||
serverLocalisationService.GetText(
|
||||
"repair-unable_to_find_item_repair_cost",
|
||||
itemToRepair.Template
|
||||
)
|
||||
@@ -112,11 +112,11 @@ public class RepairService(
|
||||
* _repairConfig.PriceMultiplier
|
||||
);
|
||||
|
||||
if (_logger.IsLogEnabled(LogLevel.Debug))
|
||||
if (logger.IsLogEnabled(LogLevel.Debug))
|
||||
{
|
||||
_logger.Debug($"item base repair cost: {itemRepairCost}");
|
||||
_logger.Debug($"price multiplier: {_repairConfig.PriceMultiplier}");
|
||||
_logger.Debug($"repair cost: {repairCost}");
|
||||
logger.Debug($"item base repair cost: {itemRepairCost}");
|
||||
logger.Debug($"price multiplier: {_repairConfig.PriceMultiplier}");
|
||||
logger.Debug($"repair cost: {repairCost}");
|
||||
}
|
||||
|
||||
return new RepairDetails
|
||||
@@ -138,11 +138,11 @@ public class RepairService(
|
||||
/// <param name="traderId">Id of the trader who repaired the item / who is paid</param>
|
||||
/// <param name="output">Client response</param>
|
||||
public void PayForRepair(
|
||||
string sessionID,
|
||||
MongoId sessionID,
|
||||
PmcData pmcData,
|
||||
string repairedItemId,
|
||||
double repairCost,
|
||||
string traderId,
|
||||
MongoId traderId,
|
||||
ItemEventRouterResponse output
|
||||
)
|
||||
{
|
||||
@@ -157,7 +157,7 @@ public class RepairService(
|
||||
SchemeId = 0,
|
||||
};
|
||||
|
||||
_paymentService.PayMoney(pmcData, options, sessionID, output);
|
||||
paymentService.PayMoney(pmcData, options, sessionID, output);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -166,20 +166,24 @@ public class RepairService(
|
||||
/// <param name="sessionId">Session id</param>
|
||||
/// <param name="repairDetails">Details of item repaired, cost/item</param>
|
||||
/// <param name="pmcData">Profile to add points to</param>
|
||||
public void AddRepairSkillPoints(string sessionId, RepairDetails repairDetails, PmcData pmcData)
|
||||
public void AddRepairSkillPoints(
|
||||
MongoId sessionId,
|
||||
RepairDetails repairDetails,
|
||||
PmcData pmcData
|
||||
)
|
||||
{
|
||||
// Handle kit repair of weapon
|
||||
if (
|
||||
repairDetails.RepairedByKit.GetValueOrDefault(false)
|
||||
&& _itemHelper.IsOfBaseclass(repairDetails.RepairedItem.Template, BaseClasses.WEAPON)
|
||||
&& itemHelper.IsOfBaseclass(repairDetails.RepairedItem.Template, BaseClasses.WEAPON)
|
||||
)
|
||||
{
|
||||
var skillPoints = GetWeaponRepairSkillPoints(repairDetails);
|
||||
|
||||
if (skillPoints > 0)
|
||||
{
|
||||
_logger.Debug($"Added: {skillPoints} WEAPON_TREATMENT points to skill");
|
||||
_profileHelper.AddSkillPointsToPlayer(
|
||||
logger.Debug($"Added: {skillPoints} WEAPON_TREATMENT points to skill");
|
||||
profileHelper.AddSkillPointsToPlayer(
|
||||
pmcData,
|
||||
SkillTypes.WeaponTreatment,
|
||||
skillPoints,
|
||||
@@ -191,18 +195,18 @@ public class RepairService(
|
||||
// Handle kit repair of armor
|
||||
if (
|
||||
repairDetails.RepairedByKit.GetValueOrDefault(false)
|
||||
&& _itemHelper.IsOfBaseclasses(
|
||||
&& itemHelper.IsOfBaseclasses(
|
||||
repairDetails.RepairedItem.Template,
|
||||
[BaseClasses.ARMOR_PLATE, BaseClasses.BUILT_IN_INSERTS]
|
||||
)
|
||||
)
|
||||
{
|
||||
var itemDetails = _itemHelper.GetItem(repairDetails.RepairedItem.Template);
|
||||
var itemDetails = itemHelper.GetItem(repairDetails.RepairedItem.Template);
|
||||
if (!itemDetails.Key)
|
||||
{
|
||||
// No item found
|
||||
_logger.Error(
|
||||
_serverLocalisationService.GetText(
|
||||
logger.Error(
|
||||
serverLocalisationService.GetText(
|
||||
"repair-unable_to_find_item_in_db",
|
||||
repairDetails.RepairedItem.Template
|
||||
)
|
||||
@@ -215,8 +219,8 @@ public class RepairService(
|
||||
var vestSkillToLevel = isHeavyArmor ? SkillTypes.HeavyVests : SkillTypes.LightVests;
|
||||
if (repairDetails.RepairPoints is null)
|
||||
{
|
||||
_logger.Error(
|
||||
_serverLocalisationService.GetText(
|
||||
logger.Error(
|
||||
serverLocalisationService.GetText(
|
||||
"repair-item_has_no_repair_points",
|
||||
repairDetails.RepairedItem.Template
|
||||
)
|
||||
@@ -227,20 +231,16 @@ public class RepairService(
|
||||
repairDetails.RepairPoints
|
||||
* _repairConfig.ArmorKitSkillPointGainPerRepairPointMultiplier;
|
||||
|
||||
_logger.Debug($"Added: {pointsToAddToVestSkill} {vestSkillToLevel} skill");
|
||||
_profileHelper.AddSkillPointsToPlayer(
|
||||
pmcData,
|
||||
vestSkillToLevel,
|
||||
pointsToAddToVestSkill
|
||||
);
|
||||
logger.Debug($"Added: {pointsToAddToVestSkill} {vestSkillToLevel} skill");
|
||||
profileHelper.AddSkillPointsToPlayer(pmcData, vestSkillToLevel, pointsToAddToVestSkill);
|
||||
}
|
||||
|
||||
// Handle giving INT to player - differs if using kit/trader and weapon vs armor
|
||||
var intellectGainedFromRepair = GetIntellectGainedFromRepair(repairDetails);
|
||||
if (intellectGainedFromRepair > 0)
|
||||
{
|
||||
_logger.Debug($"Added: {intellectGainedFromRepair} intellect skill");
|
||||
_profileHelper.AddSkillPointsToPlayer(
|
||||
logger.Debug($"Added: {intellectGainedFromRepair} intellect skill");
|
||||
profileHelper.AddSkillPointsToPlayer(
|
||||
pmcData,
|
||||
SkillTypes.Intellect,
|
||||
intellectGainedFromRepair
|
||||
@@ -253,7 +253,7 @@ public class RepairService(
|
||||
if (repairDetails.RepairedByKit.GetValueOrDefault(false))
|
||||
{
|
||||
// Weapons/armor have different multipliers
|
||||
var intRepairMultiplier = _itemHelper.IsOfBaseclass(
|
||||
var intRepairMultiplier = itemHelper.IsOfBaseclass(
|
||||
repairDetails.RepairedItem.Template,
|
||||
BaseClasses.WEAPON
|
||||
)
|
||||
@@ -263,8 +263,8 @@ public class RepairService(
|
||||
// Limit gain to a max value defined in config.maxIntellectGainPerRepair
|
||||
if (repairDetails.RepairPoints is null)
|
||||
{
|
||||
_logger.Error(
|
||||
_serverLocalisationService.GetText(
|
||||
logger.Error(
|
||||
serverLocalisationService.GetText(
|
||||
"repair-item_has_no_repair_points",
|
||||
repairDetails.RepairedItem.Template
|
||||
)
|
||||
@@ -330,7 +330,7 @@ public class RepairService(
|
||||
/// <param name="output">ItemEventRouterResponse</param>
|
||||
/// <returns>Details of repair, item/price</returns>
|
||||
public RepairDetails RepairItemByKit(
|
||||
string sessionId,
|
||||
MongoId sessionId,
|
||||
PmcData pmcData,
|
||||
List<RepairKitsInfo> repairKits,
|
||||
MongoId itemToRepairId,
|
||||
@@ -341,15 +341,15 @@ public class RepairService(
|
||||
var itemToRepair = pmcData.Inventory.Items.FirstOrDefault(x => x.Id == itemToRepairId);
|
||||
if (itemToRepair is null)
|
||||
{
|
||||
_logger.Error(
|
||||
_serverLocalisationService.GetText(
|
||||
logger.Error(
|
||||
serverLocalisationService.GetText(
|
||||
"repair-item_not_found_unable_to_repair",
|
||||
itemToRepairId
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
var itemsDb = _databaseService.GetItems();
|
||||
var itemsDb = databaseService.GetItems();
|
||||
var itemToRepairDetails = itemsDb[itemToRepair.Template];
|
||||
var repairItemIsArmor = itemToRepairDetails.Properties.ArmorMaterial is not null;
|
||||
var repairAmount =
|
||||
@@ -359,7 +359,7 @@ public class RepairService(
|
||||
_repairConfig.ApplyRandomizeDurabilityLoss
|
||||
);
|
||||
|
||||
_repairHelper.UpdateItemDurability(
|
||||
repairHelper.UpdateItemDurability(
|
||||
itemToRepair,
|
||||
itemToRepairDetails,
|
||||
repairItemIsArmor,
|
||||
@@ -377,8 +377,8 @@ public class RepairService(
|
||||
);
|
||||
if (repairKitInInventory is null)
|
||||
{
|
||||
_logger.Error(
|
||||
_serverLocalisationService.GetText(
|
||||
logger.Error(
|
||||
serverLocalisationService.GetText(
|
||||
"repair-repair_kit_not_found_in_inventory",
|
||||
repairKit.Id
|
||||
)
|
||||
@@ -415,7 +415,7 @@ public class RepairService(
|
||||
/// <returns>Number to divide kit points by</returns>
|
||||
protected double GetKitDivisor(TemplateItem itemToRepairDetails, bool isArmor, PmcData pmcData)
|
||||
{
|
||||
var globals = _databaseService.GetGlobals();
|
||||
var globals = databaseService.GetGlobals();
|
||||
var globalConfig = globals.Configuration;
|
||||
var globalRepairSettings = globalConfig.RepairSettings;
|
||||
|
||||
@@ -487,11 +487,11 @@ public class RepairService(
|
||||
if (shouldApplyDurabilityLoss)
|
||||
{
|
||||
// Random loss not disabled via config, perform charisma check
|
||||
var hasEliteCharisma = _profileHelper.HasEliteSkillLevel(SkillTypes.Charisma, pmcData);
|
||||
var hasEliteCharisma = profileHelper.HasEliteSkillLevel(SkillTypes.Charisma, pmcData);
|
||||
if (hasEliteCharisma)
|
||||
// 50/50 chance of loss being ignored at elite level
|
||||
{
|
||||
shouldApplyDurabilityLoss = _randomUtil.GetChance100(50);
|
||||
shouldApplyDurabilityLoss = randomUtil.GetChance100(50);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -511,9 +511,9 @@ public class RepairService(
|
||||
var maxRepairAmount = repairKitDetails.Properties.MaxRepairResource;
|
||||
if (repairKitInInventory.Upd is null)
|
||||
{
|
||||
if (_logger.IsLogEnabled(LogLevel.Debug))
|
||||
if (logger.IsLogEnabled(LogLevel.Debug))
|
||||
{
|
||||
_logger.Debug(
|
||||
logger.Debug(
|
||||
$"Repair kit: {repairKitInInventory.Id} in inventory lacks upd object, adding"
|
||||
);
|
||||
}
|
||||
@@ -546,7 +546,7 @@ public class RepairService(
|
||||
if (ShouldBuffItem(repairDetails, pmcData))
|
||||
{
|
||||
if (
|
||||
_itemHelper.IsOfBaseclasses(
|
||||
itemHelper.IsOfBaseclasses(
|
||||
repairDetails.RepairedItem.Template,
|
||||
[
|
||||
BaseClasses.ARMOR,
|
||||
@@ -561,7 +561,7 @@ public class RepairService(
|
||||
AddBuff(armorConfig, repairDetails.RepairedItem);
|
||||
}
|
||||
else if (
|
||||
_itemHelper.IsOfBaseclass(repairDetails.RepairedItem.Template, BaseClasses.WEAPON)
|
||||
itemHelper.IsOfBaseclass(repairDetails.RepairedItem.Template, BaseClasses.WEAPON)
|
||||
)
|
||||
{
|
||||
var weaponConfig = _repairConfig.RepairKit.Weapon;
|
||||
@@ -578,15 +578,15 @@ public class RepairService(
|
||||
/// <param name="item">Item to repair</param>
|
||||
public void AddBuff(BonusSettings itemConfig, Item item)
|
||||
{
|
||||
var bonusRarityName = _weightedRandomHelper.GetWeightedValue(itemConfig.RarityWeight);
|
||||
var bonusTypeName = _weightedRandomHelper.GetWeightedValue(itemConfig.BonusTypeWeight);
|
||||
var bonusRarityName = weightedRandomHelper.GetWeightedValue(itemConfig.RarityWeight);
|
||||
var bonusTypeName = weightedRandomHelper.GetWeightedValue(itemConfig.BonusTypeWeight);
|
||||
|
||||
var bonusRarity = bonusRarityName == "Rare" ? itemConfig.Rare : itemConfig.Common;
|
||||
var bonusValues = bonusRarity[bonusTypeName].ValuesMinMax;
|
||||
var bonusValue = _randomUtil.GetDouble(bonusValues.Min, bonusValues.Max);
|
||||
var bonusValue = randomUtil.GetDouble(bonusValues.Min, bonusValues.Max);
|
||||
|
||||
var bonusThresholdPercents = bonusRarity[bonusTypeName].ActiveDurabilityPercentMinMax;
|
||||
var bonusThresholdPercent = _randomUtil.GetDouble(
|
||||
var bonusThresholdPercent = randomUtil.GetDouble(
|
||||
bonusThresholdPercents.Min,
|
||||
bonusThresholdPercents.Max
|
||||
);
|
||||
@@ -596,7 +596,7 @@ public class RepairService(
|
||||
Rarity = bonusRarityName,
|
||||
BuffType = Enum.Parse<BuffType>(bonusTypeName),
|
||||
Value = bonusValue,
|
||||
ThresholdDurability = _randomUtil.GetPercentOfValue(
|
||||
ThresholdDurability = randomUtil.GetPercentOfValue(
|
||||
bonusThresholdPercent,
|
||||
item.Upd.Repairable.Durability.Value,
|
||||
0
|
||||
@@ -613,9 +613,9 @@ public class RepairService(
|
||||
/// <returns>True if item should have buff applied</returns>
|
||||
protected bool ShouldBuffItem(RepairDetails repairDetails, PmcData pmcData)
|
||||
{
|
||||
var globals = _databaseService.GetGlobals();
|
||||
var globals = databaseService.GetGlobals();
|
||||
|
||||
var hasTemplate = _itemHelper.GetItem(repairDetails.RepairedItem.Template);
|
||||
var hasTemplate = itemHelper.GetItem(repairDetails.RepairedItem.Template);
|
||||
if (!hasTemplate.Key)
|
||||
{
|
||||
return false;
|
||||
@@ -664,7 +664,7 @@ public class RepairService(
|
||||
).BuffSettings;
|
||||
break;
|
||||
default:
|
||||
_logger.Error($"Unhandled buff type: {itemSkillType}");
|
||||
logger.Error($"Unhandled buff type: {itemSkillType}");
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -678,8 +678,8 @@ public class RepairService(
|
||||
|
||||
if (repairDetails.RepairPoints is null)
|
||||
{
|
||||
_logger.Error(
|
||||
_serverLocalisationService.GetText(
|
||||
logger.Error(
|
||||
serverLocalisationService.GetText(
|
||||
"repair-item_has_no_repair_points",
|
||||
repairDetails.RepairedItem.Template
|
||||
)
|
||||
@@ -707,7 +707,7 @@ public class RepairService(
|
||||
/// <returns>Skill name</returns>
|
||||
protected SkillTypes? GetItemSkillType(TemplateItem itemTemplate)
|
||||
{
|
||||
var isArmorRelated = _itemHelper.IsOfBaseclasses(
|
||||
var isArmorRelated = itemHelper.IsOfBaseclasses(
|
||||
itemTemplate.Id,
|
||||
[BaseClasses.ARMOR, BaseClasses.VEST, BaseClasses.HEADWEAR, BaseClasses.ARMOR_PLATE]
|
||||
);
|
||||
@@ -726,12 +726,12 @@ public class RepairService(
|
||||
}
|
||||
}
|
||||
|
||||
if (_itemHelper.IsOfBaseclass(itemTemplate.Id, BaseClasses.WEAPON))
|
||||
if (itemHelper.IsOfBaseclass(itemTemplate.Id, BaseClasses.WEAPON))
|
||||
{
|
||||
return SkillTypes.WeaponTreatment;
|
||||
}
|
||||
|
||||
if (_itemHelper.IsOfBaseclass(itemTemplate.Id, BaseClasses.KNIFE))
|
||||
if (itemHelper.IsOfBaseclass(itemTemplate.Id, BaseClasses.KNIFE))
|
||||
{
|
||||
return SkillTypes.Melee;
|
||||
}
|
||||
|
||||
@@ -16,14 +16,14 @@ namespace SPTarkov.Server.Core.Services;
|
||||
|
||||
[Injectable(InjectionType.Singleton)]
|
||||
public class SeasonalEventService(
|
||||
ISptLogger<SeasonalEventService> _logger,
|
||||
TimeUtil _timeUtil,
|
||||
DatabaseService _databaseService,
|
||||
GiftService _giftService,
|
||||
ServerLocalisationService _serverLocalisationService,
|
||||
ProfileHelper _profileHelper,
|
||||
ConfigServer _configServer,
|
||||
RandomUtil _randomUtil
|
||||
ISptLogger<SeasonalEventService> logger,
|
||||
TimeUtil timeUtil,
|
||||
DatabaseService databaseService,
|
||||
GiftService giftService,
|
||||
ServerLocalisationService serverLocalisationService,
|
||||
ProfileHelper profileHelper,
|
||||
ConfigServer configServer,
|
||||
RandomUtil randomUtil
|
||||
)
|
||||
{
|
||||
private bool _christmasEventActive;
|
||||
@@ -86,18 +86,18 @@ public class SeasonalEventService(
|
||||
ItemTpl.RANDOMLOOTCONTAINER_PUMPKIN_RAND_LOOT_CONTAINER,
|
||||
];
|
||||
|
||||
protected readonly HttpConfig _httpConfig = _configServer.GetConfig<HttpConfig>();
|
||||
protected readonly LocationConfig _locationConfig = _configServer.GetConfig<LocationConfig>();
|
||||
protected readonly HttpConfig _httpConfig = configServer.GetConfig<HttpConfig>();
|
||||
protected readonly LocationConfig _locationConfig = configServer.GetConfig<LocationConfig>();
|
||||
protected readonly HashSet<string> _lootContainersToFilter =
|
||||
[
|
||||
"Backpack",
|
||||
"Pockets",
|
||||
"TacticalVest",
|
||||
];
|
||||
protected readonly QuestConfig _questConfig = _configServer.GetConfig<QuestConfig>();
|
||||
protected readonly QuestConfig _questConfig = configServer.GetConfig<QuestConfig>();
|
||||
protected readonly SeasonalEventConfig _seasonalEventConfig =
|
||||
_configServer.GetConfig<SeasonalEventConfig>();
|
||||
protected readonly WeatherConfig _weatherConfig = _configServer.GetConfig<WeatherConfig>();
|
||||
configServer.GetConfig<SeasonalEventConfig>();
|
||||
protected readonly WeatherConfig _weatherConfig = configServer.GetConfig<WeatherConfig>();
|
||||
|
||||
/// <summary>
|
||||
/// Get an array of christmas items found in bots inventories as loot
|
||||
@@ -243,7 +243,7 @@ public class SeasonalEventService(
|
||||
/// <param name="questId">Quest to look up</param>
|
||||
/// <param name="eventType">event type (Christmas/Halloween/None)</param>
|
||||
/// <returns>true if related</returns>
|
||||
public bool IsQuestRelatedToEvent(string questId, SeasonalEventType eventType)
|
||||
public bool IsQuestRelatedToEvent(MongoId questId, SeasonalEventType eventType)
|
||||
{
|
||||
var eventQuestData = _questConfig.EventQuests.GetValueOrDefault(questId, null);
|
||||
return eventQuestData?.Season == eventType;
|
||||
@@ -256,7 +256,7 @@ public class SeasonalEventService(
|
||||
{
|
||||
if (_currentlyActiveEvents.Any())
|
||||
{
|
||||
var globalConfig = _databaseService.GetGlobals().Configuration;
|
||||
var globalConfig = databaseService.GetGlobals().Configuration;
|
||||
foreach (var activeEvent in _currentlyActiveEvents)
|
||||
{
|
||||
UpdateGlobalEvents(globalConfig, activeEvent);
|
||||
@@ -271,11 +271,11 @@ public class SeasonalEventService(
|
||||
/// <returns>True if event was successfully force enabled</returns>
|
||||
public bool ForceSeasonalEvent(SeasonalEventType eventType)
|
||||
{
|
||||
var globalConfig = _databaseService.GetGlobals().Configuration;
|
||||
var globalConfig = databaseService.GetGlobals().Configuration;
|
||||
var seasonEvent = _seasonalEventConfig.Events.FirstOrDefault(e => e.Type == eventType);
|
||||
if (seasonEvent is null)
|
||||
{
|
||||
_logger.Warning(
|
||||
logger.Warning(
|
||||
$"Unable to force event: {eventType} as it cannot be found in events config"
|
||||
);
|
||||
return false;
|
||||
@@ -330,7 +330,7 @@ public class SeasonalEventService(
|
||||
return _weatherConfig.OverrideSeason.Value;
|
||||
}
|
||||
|
||||
var currentDate = _timeUtil.GetDateTimeNow();
|
||||
var currentDate = timeUtil.GetDateTimeNow();
|
||||
foreach (var seasonRange in _weatherConfig.SeasonDates)
|
||||
{
|
||||
if (
|
||||
@@ -346,8 +346,8 @@ public class SeasonalEventService(
|
||||
}
|
||||
}
|
||||
|
||||
_logger.Warning(
|
||||
_serverLocalisationService.GetText("season-no_matching_season_found_for_date")
|
||||
logger.Warning(
|
||||
serverLocalisationService.GetText("season-no_matching_season_found_for_date")
|
||||
);
|
||||
|
||||
return Season.SUMMER;
|
||||
@@ -367,8 +367,8 @@ public class SeasonalEventService(
|
||||
{
|
||||
if (botInventory.Equipment[equipmentSlotKey] is null)
|
||||
{
|
||||
_logger.Warning(
|
||||
_serverLocalisationService.GetText(
|
||||
logger.Warning(
|
||||
serverLocalisationService.GetText(
|
||||
"seasonal-missing_equipment_slot_on_bot",
|
||||
new { equipmentSlot = equipmentSlotKey, botRole }
|
||||
)
|
||||
@@ -396,8 +396,8 @@ public class SeasonalEventService(
|
||||
|
||||
if (prop is null)
|
||||
{
|
||||
_logger.Warning(
|
||||
_serverLocalisationService.GetText(
|
||||
logger.Warning(
|
||||
serverLocalisationService.GetText(
|
||||
"seasonal-missing_loot_container_slot_on_bot",
|
||||
new { lootContainer = lootContainerKey, botRole }
|
||||
)
|
||||
@@ -416,9 +416,7 @@ public class SeasonalEventService(
|
||||
/// <param name="event">Name of the event to enable. e.g. Christmas</param>
|
||||
private void UpdateGlobalEvents(Config globalConfig, SeasonalEvent eventType)
|
||||
{
|
||||
_logger.Success(
|
||||
_serverLocalisationService.GetText("season-event_is_active", eventType.Type)
|
||||
);
|
||||
logger.Success(serverLocalisationService.GetText("season-event_is_active", eventType.Type));
|
||||
_christmasEventActive = false;
|
||||
_halloweenEventActive = false;
|
||||
|
||||
@@ -584,7 +582,7 @@ public class SeasonalEventService(
|
||||
|
||||
foreach (var botTypeKey in adjustments)
|
||||
{
|
||||
var botDb = _databaseService.GetBots().Types[botTypeKey.Key];
|
||||
var botDb = databaseService.GetBots().Types[botTypeKey.Key];
|
||||
if (botDb is null)
|
||||
{
|
||||
continue;
|
||||
@@ -616,7 +614,7 @@ public class SeasonalEventService(
|
||||
Dictionary<string, List<AdditionalHostilitySettings>> hostilitySettings
|
||||
)
|
||||
{
|
||||
var locations = _databaseService.GetLocations().GetDictionary();
|
||||
var locations = databaseService.GetLocations().GetDictionary();
|
||||
var ignoreList = _locationConfig.NonMaps;
|
||||
|
||||
foreach (var (locationName, locationBase) in locations)
|
||||
@@ -710,13 +708,13 @@ public class SeasonalEventService(
|
||||
{
|
||||
foreach (var locationId in locationIds)
|
||||
{
|
||||
var location = _databaseService.GetLocation(locationId);
|
||||
var location = databaseService.GetLocation(locationId);
|
||||
location.Base.AccessKeys = [];
|
||||
location.Base.AccessKeysPvE = [];
|
||||
}
|
||||
}
|
||||
|
||||
public void GivePlayerSeasonalGifts(string sessionId)
|
||||
public void GivePlayerSeasonalGifts(MongoId sessionId)
|
||||
{
|
||||
if (_currentlyActiveEvents is null)
|
||||
{
|
||||
@@ -743,7 +741,7 @@ public class SeasonalEventService(
|
||||
/// </summary>
|
||||
protected void AdjustZryachiyMeleeChance()
|
||||
{
|
||||
var zryachiyKvP = _databaseService
|
||||
var zryachiyKvP = databaseService
|
||||
.GetBots()
|
||||
.Types.FirstOrDefault(x =>
|
||||
string.Equals(x.Key, "bosszryachiy", StringComparison.OrdinalIgnoreCase)
|
||||
@@ -769,19 +767,19 @@ public class SeasonalEventService(
|
||||
/// </summary>
|
||||
protected void EnableHalloweenSummonEvent()
|
||||
{
|
||||
_databaseService.GetGlobals().Configuration.EventSettings.EventActive = true;
|
||||
databaseService.GetGlobals().Configuration.EventSettings.EventActive = true;
|
||||
}
|
||||
|
||||
protected void ConfigureZombies(ZombieSettings zombieSettings)
|
||||
{
|
||||
// Flag zombies as being enabled
|
||||
var botData = _databaseService.GetBots();
|
||||
var botData = databaseService.GetBots();
|
||||
if (!botData.Core.TryAdd("ACTIVE_HALLOWEEN_ZOMBIES_EVENT", true))
|
||||
{
|
||||
botData.Core["ACTIVE_HALLOWEEN_ZOMBIES_EVENT"] = true;
|
||||
}
|
||||
|
||||
var globals = _databaseService.GetGlobals();
|
||||
var globals = databaseService.GetGlobals();
|
||||
var infectionHalloween = globals.Configuration.SeasonActivity.InfectionHalloween;
|
||||
infectionHalloween.DisplayUIEnabled = true;
|
||||
infectionHalloween.Enabled = true;
|
||||
@@ -794,10 +792,10 @@ public class SeasonalEventService(
|
||||
infectionPercentage == 100
|
||||
? infectionPercentage
|
||||
: Convert.ToDouble(
|
||||
_randomUtil.GetInt(Convert.ToInt32(infectionPercentage), 100)
|
||||
randomUtil.GetInt(Convert.ToInt32(infectionPercentage), 100)
|
||||
);
|
||||
if (_logger.IsLogEnabled(LogLevel.Debug))
|
||||
_logger.Debug(
|
||||
if (logger.IsLogEnabled(LogLevel.Debug))
|
||||
logger.Debug(
|
||||
$"Percent infected from map {locationId} is {randomInfectionPercentage}"
|
||||
);
|
||||
// Infection rates sometimes apply to multiple maps, e.g. Factory day/night or Sandbox/sandbox_high
|
||||
@@ -806,7 +804,7 @@ public class SeasonalEventService(
|
||||
var mappedLocations = GetLocationFromInfectedLocation(locationId);
|
||||
foreach (var locationKey in mappedLocations)
|
||||
{
|
||||
_databaseService
|
||||
databaseService
|
||||
.GetLocation(locationKey)
|
||||
.Base.Events.Halloween2024.InfectionPercentage = randomInfectionPercentage;
|
||||
}
|
||||
@@ -817,12 +815,12 @@ public class SeasonalEventService(
|
||||
|
||||
foreach (var locationId in zombieSettings.DisableBosses)
|
||||
{
|
||||
_databaseService.GetLocation(locationId).Base.BossLocationSpawn = [];
|
||||
databaseService.GetLocation(locationId).Base.BossLocationSpawn = [];
|
||||
}
|
||||
|
||||
foreach (var locationId in zombieSettings.DisableWaves)
|
||||
{
|
||||
_databaseService.GetLocation(locationId).Base.Waves = [];
|
||||
databaseService.GetLocation(locationId).Base.Waves = [];
|
||||
}
|
||||
|
||||
var locationsWithActiveInfection = GetLocationsWithZombies(
|
||||
@@ -875,17 +873,17 @@ public class SeasonalEventService(
|
||||
|
||||
if (wavesToAddByMap is null)
|
||||
{
|
||||
_logger.Warning($"Unable to add: {eventType} waves, eventWaves is missing");
|
||||
logger.Warning($"Unable to add: {eventType} waves, eventWaves is missing");
|
||||
return;
|
||||
}
|
||||
|
||||
var locations = _databaseService.GetLocations().GetAllPropsAsDict();
|
||||
var locations = databaseService.GetLocations().GetAllPropsAsDict();
|
||||
foreach (var map in wavesToAddByMap)
|
||||
{
|
||||
var wavesToAdd = wavesToAddByMap[map.Key];
|
||||
if (wavesToAdd is null)
|
||||
{
|
||||
_logger.Warning($"Unable to add: {eventType} wave to: {map.Key}");
|
||||
logger.Warning($"Unable to add: {eventType} wave to: {map.Key}");
|
||||
continue;
|
||||
}
|
||||
|
||||
@@ -908,11 +906,11 @@ public class SeasonalEventService(
|
||||
)
|
||||
)
|
||||
{
|
||||
_logger.Warning($"Unable to add: {eventType} bosses, eventBossSpawns is missing");
|
||||
logger.Warning($"Unable to add: {eventType} bosses, eventBossSpawns is missing");
|
||||
return;
|
||||
}
|
||||
|
||||
var locations = _databaseService.GetLocations().GetAllPropsAsDict();
|
||||
var locations = databaseService.GetLocations().GetAllPropsAsDict();
|
||||
foreach (var (locationKey, bossesToAdd) in botsToAddPerMap)
|
||||
{
|
||||
if (bossesToAdd.Count == 0)
|
||||
@@ -925,7 +923,7 @@ public class SeasonalEventService(
|
||||
continue;
|
||||
}
|
||||
|
||||
var locationName = _databaseService.GetLocations().GetMappedKey(locationKey);
|
||||
var locationName = databaseService.GetLocations().GetMappedKey(locationKey);
|
||||
var mapBosses = ((Location)locations[locationName]).Base.BossLocationSpawn;
|
||||
foreach (var boss in bossesToAdd)
|
||||
{
|
||||
@@ -988,7 +986,7 @@ public class SeasonalEventService(
|
||||
/// </summary>
|
||||
protected void AddLootItemsToGifterDropItemsList()
|
||||
{
|
||||
var gifterBot = _databaseService.GetBots().Types["gifter"];
|
||||
var gifterBot = databaseService.GetBots().Types["gifter"];
|
||||
var itemsCSV = string.Join(",", gifterBot.BotInventory.Items.Backpack.Keys);
|
||||
string[] difficulties = ["easy", "normal", "hard", "impossible"];
|
||||
|
||||
@@ -1008,9 +1006,7 @@ public class SeasonalEventService(
|
||||
var botGearChanges = GetEventBotGear(eventType);
|
||||
if (botGearChanges is null)
|
||||
{
|
||||
_logger.Warning(
|
||||
_serverLocalisationService.GetText("gameevent-no_gear_data", eventType)
|
||||
);
|
||||
logger.Warning(serverLocalisationService.GetText("gameevent-no_gear_data", eventType));
|
||||
|
||||
return;
|
||||
}
|
||||
@@ -1018,11 +1014,11 @@ public class SeasonalEventService(
|
||||
// Iterate over bots with changes to apply
|
||||
foreach (var botKvP in botGearChanges)
|
||||
{
|
||||
var botToUpdate = _databaseService.GetBots().Types[botKvP.Key.ToLowerInvariant()];
|
||||
var botToUpdate = databaseService.GetBots().Types[botKvP.Key.ToLowerInvariant()];
|
||||
if (botToUpdate is null)
|
||||
{
|
||||
_logger.Warning(
|
||||
_serverLocalisationService.GetText("gameevent-bot_not_found", botKvP)
|
||||
logger.Warning(
|
||||
serverLocalisationService.GetText("gameevent-bot_not_found", botKvP)
|
||||
);
|
||||
continue;
|
||||
}
|
||||
@@ -1058,9 +1054,7 @@ public class SeasonalEventService(
|
||||
var botLootChanges = GetEventBotLoot(eventType);
|
||||
if (botLootChanges is null)
|
||||
{
|
||||
_logger.Warning(
|
||||
_serverLocalisationService.GetText("gameevent-no_gear_data", eventType)
|
||||
);
|
||||
logger.Warning(serverLocalisationService.GetText("gameevent-no_gear_data", eventType));
|
||||
|
||||
return;
|
||||
}
|
||||
@@ -1068,11 +1062,11 @@ public class SeasonalEventService(
|
||||
// Iterate over bots with changes to apply
|
||||
foreach (var botKvpP in botLootChanges)
|
||||
{
|
||||
var botToUpdate = _databaseService.GetBots().Types[botKvpP.Key.ToLowerInvariant()];
|
||||
var botToUpdate = databaseService.GetBots().Types[botKvpP.Key.ToLowerInvariant()];
|
||||
if (botToUpdate is null)
|
||||
{
|
||||
_logger.Warning(
|
||||
_serverLocalisationService.GetText("gameevent-bot_not_found", botKvpP)
|
||||
logger.Warning(
|
||||
serverLocalisationService.GetText("gameevent-bot_not_found", botKvpP)
|
||||
);
|
||||
continue;
|
||||
}
|
||||
@@ -1097,14 +1091,14 @@ public class SeasonalEventService(
|
||||
/// </summary>
|
||||
protected void AddPumpkinsToScavBackpacks()
|
||||
{
|
||||
_databaseService.GetBots().Types["assault"].BotInventory.Items.Backpack[
|
||||
databaseService.GetBots().Types["assault"].BotInventory.Items.Backpack[
|
||||
ItemTpl.RANDOMLOOTCONTAINER_PUMPKIN_RAND_LOOT_CONTAINER
|
||||
] = 400;
|
||||
}
|
||||
|
||||
protected void RenameBitcoin()
|
||||
{
|
||||
if (_databaseService.GetLocales().Global.TryGetValue("en", out var lazyLoad))
|
||||
if (databaseService.GetLocales().Global.TryGetValue("en", out var lazyLoad))
|
||||
{
|
||||
lazyLoad.AddTransformer(localeData =>
|
||||
{
|
||||
@@ -1121,7 +1115,7 @@ public class SeasonalEventService(
|
||||
/// </summary>
|
||||
protected void EnableDancingTree()
|
||||
{
|
||||
var maps = _databaseService.GetLocations();
|
||||
var maps = databaseService.GetLocations();
|
||||
HashSet<string> mapsToCheck = ["hideout", "base", "privatearea"];
|
||||
foreach (var mapKvP in maps.GetDictionary())
|
||||
{
|
||||
@@ -1146,17 +1140,17 @@ public class SeasonalEventService(
|
||||
protected void AddGifterBotToMaps()
|
||||
{
|
||||
var gifterSettings = _seasonalEventConfig.GifterSettings;
|
||||
var maps = _databaseService.GetLocations().GetDictionary();
|
||||
var maps = databaseService.GetLocations().GetDictionary();
|
||||
foreach (var gifterMapSettings in gifterSettings)
|
||||
{
|
||||
if (
|
||||
!maps.TryGetValue(
|
||||
_databaseService.GetLocations().GetMappedKey(gifterMapSettings.Map),
|
||||
databaseService.GetLocations().GetMappedKey(gifterMapSettings.Map),
|
||||
out var mapData
|
||||
)
|
||||
)
|
||||
{
|
||||
_logger.Warning($"AddGifterBotToMaps() Map not found {gifterMapSettings.Map}");
|
||||
logger.Warning($"AddGifterBotToMaps() Map not found {gifterMapSettings.Map}");
|
||||
|
||||
continue;
|
||||
}
|
||||
@@ -1252,18 +1246,18 @@ public class SeasonalEventService(
|
||||
/// </summary>
|
||||
/// <param name="playerId">Player to send gift to</param>
|
||||
/// <param name="giftKey">Key of gift to give</param>
|
||||
protected void GiveGift(string playerId, string giftKey)
|
||||
protected void GiveGift(MongoId playerId, string giftKey)
|
||||
{
|
||||
var giftData = _giftService.GetGiftById(giftKey);
|
||||
var giftData = giftService.GetGiftById(giftKey);
|
||||
if (
|
||||
!_profileHelper.PlayerHasReceivedMaxNumberOfGift(
|
||||
!profileHelper.PlayerHasReceivedMaxNumberOfGift(
|
||||
playerId,
|
||||
giftKey,
|
||||
giftData.MaxToSendPlayer ?? 5
|
||||
)
|
||||
)
|
||||
{
|
||||
_giftService.SendGiftToPlayer(playerId, giftKey);
|
||||
giftService.SendGiftToPlayer(playerId, giftKey);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
using SPTarkov.DI.Annotations;
|
||||
using SPTarkov.Server.Core.Helpers;
|
||||
using SPTarkov.Server.Core.Models.Common;
|
||||
using SPTarkov.Server.Core.Models.Eft.Profile;
|
||||
using SPTarkov.Server.Core.Models.Spt.Config;
|
||||
using SPTarkov.Server.Core.Models.Utils;
|
||||
@@ -10,15 +11,15 @@ namespace SPTarkov.Server.Core.Services;
|
||||
|
||||
[Injectable(InjectionType.Singleton)]
|
||||
public class TraderPurchasePersisterService(
|
||||
ISptLogger<TraderPurchasePersisterService> _logger,
|
||||
RandomUtil _randomUtil,
|
||||
TimeUtil _timeUtil,
|
||||
ProfileHelper _profileHelper,
|
||||
ServerLocalisationService _serverLocalisationService,
|
||||
ConfigServer _configServer
|
||||
ISptLogger<TraderPurchasePersisterService> logger,
|
||||
RandomUtil randomUtil,
|
||||
TimeUtil timeUtil,
|
||||
ProfileHelper profileHelper,
|
||||
ServerLocalisationService serverLocalisationService,
|
||||
ConfigServer configServer
|
||||
)
|
||||
{
|
||||
protected readonly TraderConfig _traderConfig = _configServer.GetConfig<TraderConfig>();
|
||||
protected readonly TraderConfig _traderConfig = configServer.GetConfig<TraderConfig>();
|
||||
|
||||
/// <summary>
|
||||
/// Get the purchases made from a trader for this profile before the last trader reset
|
||||
@@ -27,11 +28,11 @@ public class TraderPurchasePersisterService(
|
||||
/// <param name="traderId"> Trader to loop up purchases for </param>
|
||||
/// <returns> Dictionary of assort id and count purchased </returns>
|
||||
public Dictionary<string, TraderPurchaseData>? GetProfileTraderPurchases(
|
||||
string sessionId,
|
||||
string traderId
|
||||
MongoId sessionId,
|
||||
MongoId traderId
|
||||
)
|
||||
{
|
||||
var profile = _profileHelper.GetFullProfile(sessionId);
|
||||
var profile = profileHelper.GetFullProfile(sessionId);
|
||||
|
||||
return profile?.TraderPurchases?.GetValueOrDefault(traderId);
|
||||
}
|
||||
@@ -44,12 +45,12 @@ public class TraderPurchasePersisterService(
|
||||
/// <param name="assortId"> ID of assort to get data for </param>
|
||||
/// <returns> TraderPurchaseData </returns>
|
||||
public TraderPurchaseData? GetProfileTraderPurchase(
|
||||
string sessionId,
|
||||
string traderId,
|
||||
MongoId sessionId,
|
||||
MongoId traderId,
|
||||
string assortId
|
||||
)
|
||||
{
|
||||
var profile = _profileHelper.GetFullProfile(sessionId);
|
||||
var profile = profileHelper.GetFullProfile(sessionId);
|
||||
|
||||
if (profile.TraderPurchases is null)
|
||||
{
|
||||
@@ -75,10 +76,10 @@ public class TraderPurchasePersisterService(
|
||||
/// Remove all trader purchase records from all profiles that exist
|
||||
/// </summary>
|
||||
/// <param name="traderId"> Traders ID </param>
|
||||
public void ResetTraderPurchasesStoredInProfile(string traderId)
|
||||
public void ResetTraderPurchasesStoredInProfile(MongoId traderId)
|
||||
{
|
||||
// Reset all profiles purchase dictionaries now a trader update has occured;
|
||||
var profiles = _profileHelper.GetProfiles();
|
||||
var profiles = profileHelper.GetProfiles();
|
||||
foreach (var profile in profiles)
|
||||
{
|
||||
// Skip if no purchases
|
||||
@@ -96,16 +97,16 @@ public class TraderPurchasePersisterService(
|
||||
profile.Value.TraderPurchases[traderId] = new Dictionary<string, TraderPurchaseData>();
|
||||
}
|
||||
|
||||
_logger.Debug($"Reset trader: {traderId} assort buy limits");
|
||||
logger.Debug($"Reset trader: {traderId} assort buy limits");
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Iterate over all server profiles and remove specific trader purchase data that has passed the trader refresh time
|
||||
/// </summary>
|
||||
/// <param name="traderId"> Trader ID </param>
|
||||
public void RemoveStalePurchasesFromProfiles(string traderId)
|
||||
public void RemoveStalePurchasesFromProfiles(MongoId traderId)
|
||||
{
|
||||
var profiles = _profileHelper.GetProfiles();
|
||||
var profiles = profileHelper.GetProfiles();
|
||||
foreach (var profileKvP in profiles)
|
||||
{
|
||||
var profile = profileKvP.Value;
|
||||
@@ -124,8 +125,8 @@ public class TraderPurchasePersisterService(
|
||||
);
|
||||
if (traderUpdateDetails is null)
|
||||
{
|
||||
_logger.Error(
|
||||
_serverLocalisationService.GetText(
|
||||
logger.Error(
|
||||
serverLocalisationService.GetText(
|
||||
"trader-unable_to_delete_stale_purchases",
|
||||
new { profileId = profile.ProfileInfo.ProfileId, traderId }
|
||||
)
|
||||
@@ -137,14 +138,14 @@ public class TraderPurchasePersisterService(
|
||||
var purchaseDetails = purchaseKvP.Value;
|
||||
var resetTimeForItem =
|
||||
purchaseDetails.PurchaseTimestamp
|
||||
+ _randomUtil.GetDouble(
|
||||
+ randomUtil.GetDouble(
|
||||
traderUpdateDetails.Seconds.Min,
|
||||
traderUpdateDetails.Seconds.Max
|
||||
);
|
||||
if (resetTimeForItem < _timeUtil.GetTimeStamp())
|
||||
if (resetTimeForItem < timeUtil.GetTimeStamp())
|
||||
{
|
||||
// Item was purchased far enough in past a trader refresh would have occured, remove purchase record from profile
|
||||
_logger.Debug(
|
||||
logger.Debug(
|
||||
$"Removed trader: {traderId} purchase: {purchaseKvP} from profile: {profile.ProfileInfo.ProfileId}"
|
||||
);
|
||||
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
using SPTarkov.DI.Annotations;
|
||||
using SPTarkov.Server.Core.DI;
|
||||
using SPTarkov.Server.Core.Models;
|
||||
using SPTarkov.Server.Core.Models.Common;
|
||||
using SPTarkov.Server.Core.Models.Eft.Common.Tables;
|
||||
using SPTarkov.Server.Core.Models.Utils;
|
||||
|
||||
@@ -17,7 +18,7 @@ public class TraderStore(
|
||||
ISptLogger<TraderStore> logger
|
||||
) : IOnLoad
|
||||
{
|
||||
private readonly Dictionary<string, ITrader> _traders = new();
|
||||
private readonly Dictionary<MongoId, ITrader> _traders = new();
|
||||
|
||||
public Task OnLoad()
|
||||
{
|
||||
@@ -71,7 +72,7 @@ public class TraderStore(
|
||||
/// </summary>
|
||||
/// <param name="traderId"></param>
|
||||
/// <returns></returns>
|
||||
public ITrader? GetTraderById(string traderId)
|
||||
public ITrader? GetTraderById(MongoId traderId)
|
||||
{
|
||||
return _traders.GetValueOrDefault(traderId);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user