More strings to MongoIds

Convert constructors into primary constructors

Simplified logic with use of ??, ??= and method groups

Cleaned up redundant conditional access qualifiers
This commit is contained in:
Chomp
2025-07-14 22:29:41 +01:00
parent 26afa19387
commit 040be2feaa
150 changed files with 482 additions and 631 deletions
+3 -4
View File
@@ -1,5 +1,4 @@
using System;
using BenchmarkDotNet.Attributes;
using BenchmarkDotNet.Attributes;
using SPTarkov.Server.Core.Utils;
namespace Benchmarks
@@ -11,8 +10,8 @@ namespace Benchmarks
private MathUtil _mathUtil;
private double input = 15d;
private new List<double> x = [1, 10, 20, 30, 40, 50, 60];
private new List<double> y = [11000, 20000, 32000, 45000, 58000, 70000, 82000];
private List<double> x = [1, 10, 20, 30, 40, 50, 60];
private List<double> y = [11000, 20000, 32000, 45000, 58000, 70000, 82000];
[GlobalSetup]
public void Setup()
@@ -1,11 +1,6 @@
namespace SPTarkov.DI;
public class SingletonStateHolder<T>
public class SingletonStateHolder<T>(T state)
{
public T State { get; }
public SingletonStateHolder(T state)
{
State = state;
}
public T State { get; } = state;
}
@@ -91,7 +91,7 @@ public class DialogueCallbacks(
/// Handle client/mail/dialog/view
/// </summary>
/// <param name="url"></param>
/// <param name="info"></param>
/// <param name="request"></param>
/// <param name="sessionID">Session/player id</param>
/// <returns></returns>
public virtual ValueTask<string> GetMailDialogView(
@@ -32,7 +32,7 @@ public class MatchCallbacks(
/// Handle client/match/exit
/// </summary>
/// <param name="url"></param>
/// <param name="info"></param>
/// <param name="_"></param>
/// <param name="sessionID">Session/player id</param>
/// <returns></returns>
public ValueTask<string> ExitMatch(string url, EmptyRequestData _, MongoId sessionID)
@@ -320,7 +320,7 @@ public class MatchCallbacks(
/// Handle client/match/group/raid/not-ready
/// </summary>
/// <param name="url"></param>
/// <param name="info"></param>
/// <param name="_"></param>
/// <param name="sessionID">Session/player id</param>
/// <returns></returns>
public ValueTask<string> NotRaidReady(string url, EmptyRequestData _, MongoId sessionID)
@@ -17,7 +17,7 @@ public class PrestigeCallbacks(
/// Handle client/prestige/list
/// </summary>
/// <param name="url"></param>
/// <param name="info"></param>
/// <param name="_"></param>
/// <param name="sessionID">Session/player id</param>
/// <returns></returns>
public ValueTask<string> GetPrestige(string url, EmptyRequestData _, MongoId sessionID)
@@ -102,7 +102,7 @@ public class QuestCallbacks(
/// Handle client/repeatalbeQuests/activityPeriods
/// </summary>
/// <param name="url"></param>
/// <param name="info"></param>
/// <param name="_"></param>
/// <param name="sessionID">Session/player id</param>
/// <returns></returns>
public ValueTask<string> ActivityPeriods(string url, EmptyRequestData _, MongoId sessionID)
@@ -138,7 +138,7 @@ public class RagfairCallbacks(
/// Called when clicking an item to list on flea
/// </summary>
/// <param name="url"></param>
/// <param name="info"></param>
/// <param name="_"></param>
/// <param name="sessionID">Session/player id</param>
/// <returns></returns>
public ValueTask<string> GetFleaPrices(string url, EmptyRequestData _, MongoId sessionID)
@@ -68,7 +68,7 @@ public class TraderCallbacks(
/// Handle /singleplayer/moddedTraders
/// </summary>
/// <param name="url"></param>
/// <param name="info"></param>
/// <param name="_"></param>
/// <param name="sessionID">Session/player id</param>
/// <returns></returns>
public ValueTask<string> GetModdedTraderData(string url, EmptyRequestData _, MongoId sessionID)
@@ -16,7 +16,7 @@ public class WeatherCallbacks(
/// Handle client/weather
/// </summary>
/// <param name="url"></param>
/// <param name="info"></param>
/// <param name="_"></param>
/// <param name="sessionID">Session/player id</param>
/// <returns></returns>
public ValueTask<string> GetWeather(string url, EmptyRequestData _, MongoId sessionID)
@@ -28,7 +28,7 @@ public class WeatherCallbacks(
/// Handle client/localGame/weather
/// </summary>
/// <param name="url"></param>
/// <param name="info"></param>
/// <param name="_"></param>
/// <param name="sessionID">Session/player id</param>
/// <returns></returns>
public ValueTask<string> GetLocalWeather(string url, EmptyRequestData _, MongoId sessionID)
@@ -78,7 +78,6 @@ public class BotController(
/// <param name="sessionId">Which user is requesting his bot settings</param>
/// <param name="type">what bot the server is requesting settings for</param>
/// <param name="diffLevel">difficulty level server requested settings for</param>
/// <param name="raidConfig">OPTIONAL - applicationContext Data stored at start of raid</param>
/// <param name="ignoreRaidSettings">OPTIONAL - should raid settings chosen pre-raid be ignored</param>
/// <returns>Difficulty object</returns>
public DifficultyCategories GetBotDifficulty(
@@ -92,7 +91,7 @@ public class BotController(
var raidConfig = _profileActivityService
.GetProfileActivityRaidData(sessionId)
?.RaidConfiguration;
.RaidConfiguration;
if (!(raidConfig != null || ignoreRaidSettings))
{
@@ -33,7 +33,7 @@ public class BuildController(
const string secureContainerSlotId = "SecuredContainer";
var profile = profileHelper.GetFullProfile(sessionID);
if (profile?.UserBuildData is null)
if (profile.UserBuildData is null)
{
profile.UserBuildData = new UserBuilds
{
@@ -50,12 +50,12 @@ public class BuildController(
// Get players secure container
var playerSecureContainer =
profile?.CharacterData?.PmcData?.Inventory?.Items?.FirstOrDefault(x =>
profile.CharacterData?.PmcData?.Inventory?.Items?.FirstOrDefault(x =>
x.SlotId == secureContainerSlotId
);
var firstDefaultItemsSecureContainer = defaultEquipmentPresetsClone
?.FirstOrDefault()
.FirstOrDefault()
?.Items?.FirstOrDefault(x => x.SlotId == secureContainerSlotId);
if (
@@ -81,7 +81,7 @@ public class BuildController(
var userBuildsClone = cloner.Clone(profile?.UserBuildData);
userBuildsClone.EquipmentBuilds ??= [];
userBuildsClone?.EquipmentBuilds?.AddRange(defaultEquipmentPresetsClone);
userBuildsClone.EquipmentBuilds?.AddRange(defaultEquipmentPresetsClone);
return userBuildsClone;
}
@@ -34,17 +34,17 @@ public class CustomizationController(
/// <param name="traderId">trader to look up clothing for</param>
/// <param name="sessionId">Session id</param>
/// <returns>Suit array</returns>
public List<Suit> GetTraderSuits(string traderId, MongoId sessionId)
public List<Suit> GetTraderSuits(MongoId traderId, MongoId sessionId)
{
var pmcData = profileHelper.GetPmcProfile(sessionId);
var clothing = databaseService.GetCustomization();
var suits = databaseService.GetTrader(traderId).Suits;
var matchingSuits = suits?.Where(s => clothing.ContainsKey(s.SuiteId!)).ToList();
var matchingSuits = suits?.Where(s => clothing.ContainsKey(s.SuiteId)).ToList();
matchingSuits = matchingSuits
?.Where(s =>
clothing[s.SuiteId ?? string.Empty]
?.Properties?.Side?.Contains(pmcData?.Info?.Side ?? string.Empty) ?? false
clothing[s.SuiteId]?.Properties?.Side?.Contains(pmcData?.Info?.Side ?? string.Empty)
?? false
)
.ToList();
@@ -90,9 +90,9 @@ public class CustomizationController(
}
var suitId = traderOffer.SuiteId;
if (OutfitAlreadyPurchased(suitId ?? string.Empty, sessionId))
if (OutfitAlreadyPurchased(traderOffer.SuiteId, sessionId))
{
var suitDetails = databaseService.GetCustomization()!.GetValueOrDefault(suitId);
var suitDetails = databaseService.GetCustomization().GetValueOrDefault(suitId);
logger.Error(
serverLocalisationService.GetText(
"customisation-item_already_purchased",
@@ -127,7 +127,7 @@ public class CustomizationController(
/// <param name="suitId">clothing id</param>
/// <param name="sessionId">Session id of profile to check for clothing in</param>
/// <returns>true if already purchased</returns>
protected bool OutfitAlreadyPurchased(object suitId, MongoId sessionId)
protected bool OutfitAlreadyPurchased(MongoId suitId, MongoId sessionId)
{
var fullProfile = profileHelper.GetFullProfile(sessionId);
@@ -297,9 +297,7 @@ public class CustomizationController(
/// <param name="pmcData">Profile to update</param>
protected void ApplyClothingItemToProfile(CustomizationSetOption customisation, PmcData pmcData)
{
var dbSuit = databaseService.GetCustomization()[customisation.Id!];
if (dbSuit is null)
if (!databaseService.GetCustomization().TryGetValue(customisation.Id, out var dbSuit))
{
logger.Error(
$"Unable to find suit customisation id: {customisation.Id}, cannot apply clothing to player profile: {pmcData.Id}"
@@ -172,7 +172,7 @@ public class DialogueController(
var result = new DialogueInfo
{
Id = dialogue.Id,
Type = dialogue?.Type ?? MessageType.NpcTraderMessage,
Type = dialogue.Type ?? MessageType.NpcTraderMessage,
Message = dialogueHelper.GetMessagePreview(dialogue),
New = dialogue?.New,
AttachmentsNew = dialogue?.AttachmentsNew,
@@ -210,7 +210,7 @@ public class DialogueController(
dialog.Users.Add(
new UserDialogInfo
{
Id = profile.CharacterData?.PmcData?.SessionId,
Id = profile.CharacterData.PmcData.SessionId.Value,
Aid = profile.CharacterData?.PmcData?.Aid,
Info = new UserDialogDetails
{
@@ -478,7 +478,7 @@ public class DialogueController(
public virtual void SetRead(List<string>? dialogueIds, MongoId sessionId)
{
var dialogs = dialogueHelper.GetDialogsForProfile(sessionId);
if (dialogs?.Any() != true)
if (dialogs.Any() != true)
{
logger.Error(
serverLocalisationService.GetText(
@@ -543,7 +543,7 @@ public class DialogueController(
SendMessageRequest request
)
{
mailSendService.SendPlayerMessageToNpc(sessionId, request.DialogId!, request.Text!);
mailSendService.SendPlayerMessageToNpc(sessionId, request.DialogId, request.Text);
var chatBot = _dialogueChatBots.FirstOrDefault(cb =>
cb.GetChatBot().Id == request.DialogId
@@ -638,9 +638,9 @@ public class DialogueController(
// Only add the profile to the friends list if it doesn't already exist
var profile = saveServer.GetProfile(sessionID);
if (!profile.FriendProfileIds.Contains(request.To))
if (!profile.FriendProfileIds.Contains(request.To.Value))
{
profile.FriendProfileIds.Add(request.To);
profile.FriendProfileIds.Add(request.To.Value);
}
// We need to delay this so that the friend request gets properly added to the clientside list before we accept it
@@ -440,13 +440,13 @@ public class GameController(
// One day post-profile creation
if (currentTimeStamp > timeStampProfileCreated + oneDaySeconds)
{
giftService.SendPraporStartingGift(pmcProfile.SessionId!, 1);
giftService.SendPraporStartingGift(pmcProfile.SessionId.Value, 1);
}
// Two day post-profile creation
if (currentTimeStamp > timeStampProfileCreated + oneDaySeconds * 2)
{
giftService.SendPraporStartingGift(pmcProfile.SessionId!, 2);
giftService.SendPraporStartingGift(pmcProfile.SessionId.Value, 2);
}
}
@@ -456,7 +456,11 @@ public class GameController(
/// <param name="pmcProfile"></param>
protected void SendMechanicGiftsToNewProfile(PmcData pmcProfile)
{
giftService.SendGiftWithSilentReceivedCheck("MechanicGiftDay1", pmcProfile.SessionId, 1);
giftService.SendGiftWithSilentReceivedCheck(
"MechanicGiftDay1",
pmcProfile.SessionId.Value,
1
);
}
/// <summary>
@@ -304,13 +304,15 @@ public class HealthController(
return output;
}
foreach (var bodyPartKvP in healthTreatmentRequest.Difference.BodyParts.GetAllPropsAsDict())
foreach (
var (key, rawEffects) in healthTreatmentRequest.Difference.BodyParts.GetAllPropsAsDict()
)
{
// Get body part from request + from pmc profile
var partRequest = (BodyPartEffects)bodyPartKvP.Value;
var profilePart = pmcData.Health.BodyParts[bodyPartKvP.Key];
var partRequest = (BodyPartEffects)rawEffects;
var profilePart = pmcData.Health.BodyParts[key];
// Bodypart healing is chosen when part request hp is above 0
// Body part healing is chosen when part request hp is above 0
if (partRequest.Health > 0)
// Heal bodypart
{
@@ -318,18 +320,18 @@ public class HealthController(
}
// Check for effects to remove
if (partRequest.Effects?.Count > 0)
if (partRequest.Effects.Count > 0)
{
// Found some, loop over them and remove from pmc profile
foreach (var effect in partRequest.Effects)
{
pmcData.Health.BodyParts[bodyPartKvP.Key].Effects.Remove(effect);
pmcData.Health.BodyParts[key].Effects.Remove(effect);
}
// Remove empty effect object
if (pmcData.Health.BodyParts[bodyPartKvP.Key].Effects.Count == 0)
if (pmcData.Health.BodyParts[key].Effects.Count == 0)
{
pmcData.Health.BodyParts[bodyPartKvP.Key].Effects = null;
pmcData.Health.BodyParts[key].Effects = null;
}
}
}
@@ -212,7 +212,19 @@ public class HideoutController(
}
// Apply bonuses
var hideoutStage = hideoutData.Stages[profileHideoutArea.Level.ToString()];
if (
!hideoutData.Stages.TryGetValue(
profileHideoutArea.Level.ToString(),
out var hideoutStage
)
)
{
logger.Error(
$"Stage level: {profileHideoutArea.Level} not found for area: {request.AreaType}"
);
return;
}
var bonuses = hideoutStage.Bonuses;
if (bonuses?.Count > 0)
{
@@ -223,7 +235,7 @@ public class HideoutController(
}
// Upgrade includes a container improvement/addition
if (!string.IsNullOrEmpty(hideoutStage?.Container))
if (!string.IsNullOrEmpty(hideoutStage.Container))
{
AddContainerImprovementToProfile(
output,
@@ -411,7 +423,7 @@ public class HideoutController(
if (existingInventoryItem is not null)
{
// Update existing items container tpl to point to new id (tpl)
existingInventoryItem.Template = hideoutStage.Container;
existingInventoryItem.Template = hideoutStage.Container.Value;
return;
}
@@ -420,7 +432,7 @@ public class HideoutController(
var newContainerItem = new Item
{
Id = dbHideoutArea.Id,
Template = hideoutStage.Container,
Template = hideoutStage.Container.Value,
};
pmcData.Inventory.Items.Add(newContainerItem);
}
@@ -611,7 +623,7 @@ public class HideoutController(
BotHideoutArea hideoutArea
)
{
var slotIndexToRemove = removeResourceRequest?.Slots?.FirstOrDefault();
var slotIndexToRemove = removeResourceRequest.Slots?.FirstOrDefault();
if (slotIndexToRemove is null)
{
logger.Error(
@@ -1709,7 +1721,7 @@ public class HideoutController(
)
{
// Each slot is a single Mannequin
var slots = itemHelper.GetItem(equipmentPresetStage.Container).Value.Properties.Slots;
var slots = itemHelper.GetItem(equipmentPresetStage.Container.Value).Value.Properties.Slots;
foreach (var mannequinSlot in slots)
{
// Check if we've already added this mannequin
@@ -559,7 +559,7 @@ public class InsuranceController(
var price = ragfairPriceService.GetDynamicItemPrice(attachment.Template, Money.ROUBLES);
if (price is not null)
{
result[attachment.Id] = Math.Round(price ?? 0);
result.Add(attachment.Id, Math.Round(price.Value));
}
}
@@ -675,7 +675,7 @@ public class InsuranceController(
/// Edge case - labyrinth doesn't allow for insurance returns unless location config is edited
/// </summary>
/// <param name="insurance">The insured items to process</param>
/// <param name="labsId">OPTIONAL - id of labs location</param>
/// <param name="labyrinthId">OPTIONAL - id of labyrinth location</param>
/// <returns></returns>
protected bool IsMapLabyrinthAndInsuranceDisabled(
Insurance insurance,
@@ -59,7 +59,7 @@ public class InventoryController(
// Changes made to result apply to character inventory
var ownerInventoryItems = inventoryHelper.GetOwnerInventoryItems(
moveRequest,
moveRequest.Item,
moveRequest.Item.Value,
sessionId
);
if (ownerInventoryItems.SameInventory.GetValueOrDefault(false))
@@ -503,14 +503,7 @@ public class InventoryController(
inventoryItem.ParentId = change.ParentId;
inventoryItem.SlotId = change.SlotId;
if (change.Location is not null)
{
inventoryItem.Location = change.Location;
}
else
{
inventoryItem.Location = null;
}
inventoryItem.Location = change.Location ?? null;
}
}
@@ -829,9 +822,7 @@ public class InventoryController(
playerData = profileHelper.GetScavProfile(sessionId);
}
var itemToFold = playerData.Inventory.Items.FirstOrDefault(item =>
item?.Id == request.Item
);
var itemToFold = playerData.Inventory.Items.FirstOrDefault(item => item.Id == request.Item);
if (itemToFold is null)
{
// Item not found
@@ -897,32 +888,18 @@ public class InventoryController(
);
}
// to.id is the parentid
// to.id is the parentId
itemOne.ParentId = request.To.Id;
// to.container is the slotid
// to.container is the slotId
itemOne.SlotId = request.To.Container;
// Request object has location data, add it in, otherwise remove existing location from object
if (request.To.Location is not null)
{
itemOne.Location = request.To.Location;
}
else
{
itemOne.Location = null;
}
itemOne.Location = request.To.Location ?? null;
itemTwo.ParentId = request.To2.Id;
itemTwo.SlotId = request.To2.Container;
if (request.To2.Location is not null)
{
itemTwo.Location = request.To2.Location;
}
else
{
itemTwo.Location = null;
}
itemTwo.Location = request.To2.Location ?? null;
// Client already informed of inventory locations, nothing for us to do
return eventOutputHolder.GetOutput(sessionId);
@@ -224,7 +224,7 @@ public class LauncherController(
/// <summary>
/// Get the mods a profile has ever loaded into game with
/// </summary>
/// <param name="sessionID">Session/Player id</param>
/// <param name="sessionId">Session/Player id</param>
/// <returns>Array of mod details</returns>
public List<ModDetails> GetServerModsProfileUsed(MongoId sessionId)
{
@@ -48,7 +48,7 @@ public class RagfairController(
ConfigServer configServer
)
{
protected RagfairConfig _ragfairConfig = configServer.GetConfig<RagfairConfig>();
protected readonly RagfairConfig _ragfairConfig = configServer.GetConfig<RagfairConfig>();
/// <summary>
/// Check all profiles and sell player offers / send player money for listing if it sold
@@ -127,11 +127,7 @@ public class RagfairController(
}
// Update trader offers' values, Lock quest-linked offers + adjust offer buy limits
foreach (
var traderOffer in result.Offers.Where(offer =>
ragfairOfferHelper.OfferIsFromTrader(offer)
)
)
foreach (var traderOffer in result.Offers.Where(ragfairOfferHelper.OfferIsFromTrader))
{
// For the items, check the barter schemes. The method getDisplayableAssorts sets a flag sptQuestLocked
// to true if the quest is not completed yet
@@ -353,7 +349,7 @@ public class RagfairController(
);
}
if (searchRequest.NeededSearchId?.Length > 0)
if (searchRequest.NeededSearchId is not null)
{
return ragfairOfferHelper.GetOffersThatRequireItem(searchRequest, pmcProfile);
}
@@ -521,7 +517,7 @@ public class RagfairController(
/// <returns>Is offer valid</returns>
protected bool IsValidPlayerOfferRequest(AddOfferRequestData offerRequest)
{
if (offerRequest?.Items is null || offerRequest.Items.Count == 0)
if (offerRequest.Items is null || offerRequest.Items.Count == 0)
{
logger.Error(localisationService.GetText("ragfair-invalid_player_offer_request"));
@@ -1091,7 +1087,7 @@ public class RagfairController(
itemsToReturn.Add(pmcData.Inventory.Items.FindAndReturnChildrenAsItems(itemId));
}
if (itemsToReturn?.Count == 0)
if (itemsToReturn.Count == 0)
{
errorMessage = localisationService.GetText(
"ragfair-unable_to_find_requested_items_in_inventory"
@@ -1280,7 +1276,7 @@ public class RagfairController(
return offerToReturn;
}
public record GetItemsToListOnFleaFromInventoryResult
protected record GetItemsToListOnFleaFromInventoryResult
{
public List<List<Item>>? Items { get; set; }
@@ -34,7 +34,7 @@ public class RepairController(EventOutputHolder eventOutputHolder, RepairService
sessionID,
pmcData,
repairItem,
request.TId
request.TraderId
);
repairService.PayForRepair(
@@ -42,7 +42,7 @@ public class RepairController(EventOutputHolder eventOutputHolder, RepairService
pmcData,
repairItem.Id,
repairDetails.RepairCost.Value,
request.TId,
request.TraderId,
output
);
@@ -805,7 +805,7 @@ public class RepeatableQuestController(
protected bool PlayerHasDailyScavQuestsUnlocked(PmcData pmcData)
{
return pmcData
?.Hideout?.Areas?.FirstOrDefault(hideoutArea =>
.Hideout?.Areas?.FirstOrDefault(hideoutArea =>
hideoutArea.Type == HideoutAreas.IntelligenceCenter
)
?.Level >= 1;
@@ -334,7 +334,7 @@ public class TradeController(
};
// Ensure money is properly split to follow its max stack size limit
var curencyReward = itemHelper.SplitStackIntoSeparateItems(rootCurrencyReward);
var currencyReward = itemHelper.SplitStackIntoSeparateItems(rootCurrencyReward);
// Send mail from trader
mailSendService.SendLocalisedNpcMessageToPlayer(
@@ -344,9 +344,9 @@ public class TradeController(
randomUtil.GetArrayValue(
databaseService.GetTrader(trader).Dialogue.TryGetValue("soldItems", out var items)
? items
: new List<string>()
: []
),
curencyReward.SelectMany(x => x).ToList(),
currencyReward.SelectMany(x => x).ToList(),
timeUtil.GetHoursAsSeconds(72)
);
}
@@ -58,7 +58,7 @@ public class TraderController(
}
// Adjust price by traderPriceMultiplier config property
if (!TraderConfig.TraderPriceMultiplier.Approx(1, 0.001))
if (!TraderConfig.TraderPriceMultiplier.Approx(1))
{
AdjustTraderItemPrices(trader, TraderConfig.TraderPriceMultiplier);
}
@@ -82,7 +82,7 @@ public class TraderController(
{
foreach (var kvp in trader.Assort?.BarterScheme)
{
var barterSchemeItem = kvp.Value?.FirstOrDefault()?.FirstOrDefault();
var barterSchemeItem = kvp.Value.FirstOrDefault()?.FirstOrDefault();
if (
barterSchemeItem?.Template != null
&& paymentHelper.IsMoneyTpl(barterSchemeItem.Template)
+4 -13
View File
@@ -40,17 +40,8 @@ public abstract class Router
}
}
public abstract class StaticRouter : Router
public abstract class StaticRouter(JsonUtil jsonUtil, List<RouteAction> routes) : Router
{
private readonly List<RouteAction> _actions;
private readonly JsonUtil _jsonUtil;
public StaticRouter(JsonUtil jsonUtil, List<RouteAction> routes)
{
_actions = routes;
_jsonUtil = jsonUtil;
}
public async ValueTask<object> HandleStatic(
string url,
string? body,
@@ -58,12 +49,12 @@ public abstract class StaticRouter : Router
string output
)
{
var action = _actions.Single(route => route.url == url);
var action = routes.Single(route => route.url == url);
var type = action.bodyType;
IRequestData? info = null;
if (type != null && !string.IsNullOrEmpty(body))
{
info = (IRequestData?)_jsonUtil.Deserialize(body, type);
info = (IRequestData?)jsonUtil.Deserialize(body, type);
}
return await action.action(url, info, sessionId, output);
@@ -71,7 +62,7 @@ public abstract class StaticRouter : Router
protected override List<HandledRoute> GetHandledRoutes()
{
return _actions.Select(route => new HandledRoute(route.url, false)).ToList();
return routes.Select(route => new HandledRoute(route.url, false)).ToList();
}
}
@@ -1,4 +1,5 @@
using SPTarkov.Server.Core.Models.Eft.Common.Tables;
using SPTarkov.Server.Core.Models.Common;
using SPTarkov.Server.Core.Models.Eft.Common.Tables;
using SPTarkov.Server.Core.Models.Eft.Profile;
using SPTarkov.Server.Core.Models.Enums;
@@ -11,7 +12,7 @@ namespace SPTarkov.Server.Core.Extensions
/// </summary>
/// <param name="fullProfile">Profile to add clothing to</param>
/// <param name="clothingIds">Clothing Ids to add to profile</param>
public static void AddSuitsToProfile(this SptProfile fullProfile, List<string> clothingIds)
public static void AddSuitsToProfile(this SptProfile fullProfile, List<MongoId> clothingIds)
{
fullProfile.CustomisationUnlocks ??= [];
@@ -224,6 +224,7 @@ namespace SPTarkov.Server.Core.Extensions
return list;
}
/// <summary>
/// Check if the passed in item has buy count restrictions
/// </summary>
/// <param name="itemToCheck">Item to check</param>
@@ -27,7 +27,7 @@ namespace SPTarkov.Server.Core.Extensions
/// <summary>
/// Check if item is quest item
/// </summary>
/// <param name="tpl">Items tpl to check quest status of</param>
/// <param name="templateItem">Item to check quest status of</param>
/// <returns>true if item is flagged as quest item</returns>
public static bool IsQuestItem(this TemplateItem templateItem)
{
@@ -5,9 +5,9 @@
public static List<T> IntersectWith<T>(this List<T> first, List<T> second)
{
//a.Intersect(x => b.Contains(x)).ToList();
// gives error Delegate type could not be infered
// gives error Delegate type could not be inferred
return first.Where(x => second.Contains(x)).ToList();
return first.Where(second.Contains).ToList();
}
}
}
@@ -197,7 +197,8 @@ public class BotEquipmentModGenerator(
);
switch (plateSlotFilteringOutcome.Result)
{
case Result.UNKNOWN_FAILURE or Result.NO_DEFAULT_FILTER:
case Result.UNKNOWN_FAILURE
or Result.NO_DEFAULT_FILTER:
if (logger.IsLogEnabled(LogLevel.Debug))
{
logger.Debug(
@@ -1373,10 +1374,9 @@ public class BotEquipmentModGenerator(
// Limit how many attempts to find a compatible mod can occur before giving up
var maxBlockedAttempts = Math.Round(modPool.Count * 0.75); // 75% of pool size
var blockedAttemptCount = 0;
string chosenTpl;
while (exhaustableModPool.HasValues())
{
chosenTpl = exhaustableModPool.GetRandomValue();
var chosenTpl = exhaustableModPool.GetRandomValue();
var pickedItemDetails = itemHelper.GetItem(chosenTpl);
if (!pickedItemDetails.Key)
// Not valid item, try again
@@ -1408,7 +1408,7 @@ public class BotEquipmentModGenerator(
if (existingItemBlockingChoice is not null)
{
// Give max of x attempts of picking a mod if blocked by another
// OR Blocked and modpool only had 1 item
// OR Blocked and mod pool only had 1 item
if (blockedAttemptCount > maxBlockedAttempts || modPool.Count == 1)
{
blockedAttemptCount = 0; // reset
@@ -1420,11 +1420,10 @@ public class BotEquipmentModGenerator(
blockedAttemptCount++;
// Not compatible - Try again
;
continue;
}
// Edge case- Some mod combos will never work, make sure this isnt the case
// Edge case - Some mod combos will never work, make sure this isn't the case
if (WeaponModComboIsIncompatible(weapon, chosenTpl))
{
chosenModResult.Reason =
@@ -1492,12 +1491,7 @@ public class BotEquipmentModGenerator(
}
// Required mod is not default or randomisable, use existing pool
if (!request.ItemModPool.TryGetValue(request.ModSlot, out var modsForSlot))
{
return null;
}
return modsForSlot;
return request.ItemModPool.GetValueOrDefault(request.ModSlot);
}
/// <summary>
@@ -1733,8 +1727,8 @@ public class BotEquipmentModGenerator(
}
}
// No mod found
return null;
// No mod found, return fallback
return tmpModTpl;
}
/// <summary>
@@ -1774,7 +1768,7 @@ public class BotEquipmentModGenerator(
}
// Mod has invalid db item
if (!modToAdd.HasValue)
if (!modToAdd.Value.Key)
{
// Parent slot must be filled but db object is invalid, show warning and return false
if (slotAddedToTemplate.Required ?? false)
@@ -29,7 +29,6 @@ public class BotGenerator(
BotEquipmentFilterService botEquipmentFilterService,
WeightedRandomHelper weightedRandomHelper,
BotHelper botHelper,
BotGeneratorHelper botGeneratorHelper,
SeasonalEventService seasonalEventService,
ItemFilterService itemFilterService,
BotNameService botNameService,
@@ -175,6 +175,7 @@ public class BotInventoryGenerator(
/// <param name="botInventory">Inventory to add equipment to</param>
/// <param name="botLevel">Level of bot</param>
/// <param name="chosenGameVersion">Game version for bot, only really applies for PMCs</param>
/// <param name="isPmc">Is the generated bot a PMC</param>
/// <param name="raidConfig">RadiConfig</param>
public void GenerateAndAddEquipmentToBot(
MongoId sessionId,
@@ -1,3 +1,4 @@
using System.Globalization;
using SPTarkov.DI.Annotations;
using SPTarkov.Server.Core.Models.Common;
using SPTarkov.Server.Core.Models.Eft.Bot;
@@ -44,7 +45,8 @@ public class BotLevelGenerator(
// Get random level based on the exp table.
var exp = 0;
var level = int.Parse(
ChooseBotLevel(botLevelRange.Min, botLevelRange.Max, 1, 1.15).ToString()
ChooseBotLevel(botLevelRange.Min, botLevelRange.Max, 1, 1.15)
.ToString(CultureInfo.InvariantCulture)
); // TODO - nasty double to string to int conversion
for (var i = 0; i < level; i++)
{
@@ -765,10 +765,10 @@ public class BotLootGenerator(
{
var chosenWeaponType = randomUtil.GetArrayValue<string>(
[
EquipmentSlots.FirstPrimaryWeapon.ToString(),
EquipmentSlots.FirstPrimaryWeapon.ToString(),
EquipmentSlots.FirstPrimaryWeapon.ToString(),
EquipmentSlots.Holster.ToString(),
nameof(EquipmentSlots.FirstPrimaryWeapon),
nameof(EquipmentSlots.FirstPrimaryWeapon),
nameof(EquipmentSlots.FirstPrimaryWeapon),
nameof(EquipmentSlots.Holster),
]
);
var randomisedWeaponCount = randomUtil.GetInt(
@@ -585,7 +585,7 @@ public class BotWeaponGenerator(
{
var id = new MongoId();
botGeneratorHelper.AddItemWithChildrenToEquipmentSlot(
new HashSet<EquipmentSlots> { EquipmentSlots.SecuredContainer },
[EquipmentSlots.SecuredContainer],
id,
ammoTpl,
new List<Item>
@@ -658,7 +658,7 @@ public class BotWeaponGenerator(
/// <param name="cartridgePool">Dictionary of all cartridges keyed by type e.g. Caliber556x45NATO</param>
/// <param name="weaponTemplate">Weapon details from database we want to pick ammo for</param>
/// <returns>Ammo template that works with the desired gun</returns>
protected string? GetWeightedCompatibleAmmo(
protected MongoId GetWeightedCompatibleAmmo(
Dictionary<string, Dictionary<string, double>> cartridgePool,
TemplateItem weaponTemplate
)
@@ -686,7 +686,7 @@ public class BotWeaponGenerator(
// Immediately returns, default ammo is guaranteed to be compatible
// it is not guaranteed to even have a default ammo
return weaponTemplate.Properties.DefAmmo;
return weaponTemplate.Properties.DefAmmo.Value;
}
// Get cartridges the weapons first chamber allow
@@ -696,7 +696,7 @@ public class BotWeaponGenerator(
if (compatibleCartridgesInTemplate.Count == 0)
// No chamber data found in weapon, send default
{
return weaponTemplate.Properties.DefAmmo;
return weaponTemplate.Properties.DefAmmo.Value;
}
// Inner join the weapons allowed + passed in cartridge pool to get compatible cartridges
@@ -719,7 +719,7 @@ public class BotWeaponGenerator(
if (compatibleCartridgesInMagazine.Count == 0)
{
// No compatible cartridges found in magazine, use default
return weaponTemplate.Properties.DefAmmo;
return weaponTemplate.Properties.DefAmmo.Value;
}
// Get the caliber data from the first compatible round in the magazine
@@ -739,7 +739,7 @@ public class BotWeaponGenerator(
// Nothing found after also checking magazines, return default ammo
if (compatibleCartridges.Count == 0)
{
return weaponTemplate.Properties.DefAmmo;
return weaponTemplate.Properties.DefAmmo.Value;
}
}
@@ -166,25 +166,16 @@ public class FenceBaseAssortGenerator(
var itemAndChildren = _cloner.Clone(defaultPreset.Items).ReplaceIDs().ToList();
// Find root item and add some properties to it
for (var i = 0; i < itemAndChildren.Count; i++)
var rootItem = itemAndChildren.FirstOrDefault(item =>
string.IsNullOrEmpty(item.ParentId)
);
rootItem.ParentId = "hideout";
rootItem.SlotId = "hideout";
rootItem.Upd = new Upd
{
var mod = itemAndChildren[i];
// Build root Item info
if (string.IsNullOrEmpty(mod.ParentId))
{
mod.ParentId = "hideout";
mod.SlotId = "hideout";
mod.Upd = new Upd
{
StackObjectsCount = 1,
SptPresetId = defaultPreset.Id, // Store preset id here so we can check it later to prevent preset dupes
};
// Updated root item, exit loop
break;
}
}
StackObjectsCount = 1,
SptPresetId = defaultPreset.Id, // Store preset id here so we can check it later to prevent preset dupes
};
// Add constructed preset to assorts
baseFenceAssort.Items.AddRange(itemAndChildren);
@@ -294,10 +285,10 @@ public class FenceBaseAssortGenerator(
foreach (var requiredSlot in requiredSlots)
{
var modItemDbDetails = itemHelper
.GetItem(requiredSlot.Props.Filters[0].Plate)
.GetItem(requiredSlot.Props.Filters[0].Plate.Value)
.Value;
var plateTpl = requiredSlot.Props.Filters[0].Plate; // `Plate` property appears to be the 'default' item for slot
if (string.IsNullOrEmpty(plateTpl))
if (plateTpl is null)
// Some bsg plate properties are empty, skip mod
{
continue;
@@ -306,7 +297,7 @@ public class FenceBaseAssortGenerator(
var mod = new Item
{
Id = new MongoId(),
Template = plateTpl,
Template = plateTpl.Value,
ParentId = armor[0].Id,
SlotId = requiredSlot.Name,
Upd = new Upd
@@ -338,12 +329,12 @@ public class FenceBaseAssortGenerator(
continue;
}
var modItemDbDetails = itemHelper.GetItem(plateTpl).Value;
var modItemDbDetails = itemHelper.GetItem(plateTpl.Value).Value;
armor.Add(
new Item
{
Id = new MongoId(),
Template = plateSlot.Props.Filters[0].Plate, // `Plate` property appears to be the 'default' item for slot
Template = plateSlot.Props.Filters[0].Plate.Value, // `Plate` property appears to be the 'default' item for slot
ParentId = armor[0].Id,
SlotId = plateSlot.Name,
Upd = new Upd
@@ -114,7 +114,9 @@ public class LootGenerator(
if (randomisedWeaponPresetCount > 0)
{
var weaponDefaultPresets = globalDefaultPresets
.Where(preset => itemHelper.IsOfBaseclass(preset.Encyclopedia, BaseClasses.WEAPON))
.Where(preset =>
itemHelper.IsOfBaseclass(preset.Encyclopedia.Value, BaseClasses.WEAPON)
)
.ToList();
if (weaponDefaultPresets.Any())
@@ -145,7 +147,7 @@ public class LootGenerator(
if (randomisedArmorPresetCount > 0)
{
var armorDefaultPresets = globalDefaultPresets.Where(preset =>
itemHelper.ArmorItemCanHoldMods(preset.Encyclopedia)
itemHelper.ArmorItemCanHoldMods(preset.Encyclopedia.Value)
);
var levelFilteredArmorPresets = armorDefaultPresets
.Where(armor => IsArmorOfDesiredProtectionLevel(armor, options))
@@ -457,7 +459,7 @@ public class LootGenerator(
}
// Get preset root item db details via its `_encyclopedia` property
var itemDbDetails = itemHelper.GetItem(chosenPreset.Encyclopedia);
var itemDbDetails = itemHelper.GetItem(chosenPreset.Encyclopedia.Value);
if (!itemDbDetails.Key)
{
if (logger.IsLogEnabled(LogLevel.Debug))
@@ -799,7 +801,7 @@ public class LootGenerator(
);
}
public record ItemRewardPoolResults
protected record ItemRewardPoolResults
{
public List<TemplateItem> ItemPool { get; set; }
@@ -5,7 +5,6 @@ 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.Notes;
using SPTarkov.Server.Core.Models.Enums;
using SPTarkov.Server.Core.Models.Spt.Config;
using SPTarkov.Server.Core.Models.Utils;
@@ -114,7 +113,7 @@ public class PlayerScavGenerator(
scavData.TaskConditionCounters =
existingScavDataClone.TaskConditionCounters
?? new Dictionary<MongoId, TaskConditionCounter>();
scavData.Notes = existingScavDataClone.Notes ?? new Notes { DataNotes = new List<Note>() };
scavData.Notes = existingScavDataClone.Notes ?? new Notes { DataNotes = [] };
scavData.WishList =
existingScavDataClone.WishList
?? new DictionaryOrList<MongoId, int>(new Dictionary<MongoId, int>(), []);
@@ -379,34 +378,29 @@ public class PlayerScavGenerator(
protected Stats GetScavStats(PmcData scavProfile)
{
if (scavProfile?.Stats != null)
{
return scavProfile.Stats;
}
return profileHelper.GetDefaultCounters();
return scavProfile.Stats ?? profileHelper.GetDefaultCounters();
}
protected int GetScavLevel(PmcData scavProfile)
{
// Info can be null on initial account creation
if (scavProfile?.Info?.Level == null)
if (scavProfile.Info?.Level == null)
{
return 1;
}
return scavProfile?.Info?.Level ?? 1;
return scavProfile.Info?.Level ?? 1;
}
protected int GetScavExperience(PmcData scavProfile)
{
// Info can be null on initial account creation
if (scavProfile?.Info?.Experience == null)
if (scavProfile.Info?.Experience == null)
{
return 0;
}
return scavProfile?.Info?.Experience ?? 0;
return scavProfile.Info?.Experience ?? 0;
}
/// <summary>
@@ -432,7 +426,7 @@ public class PlayerScavGenerator(
var scavLockDuration =
databaseService.GetGlobals().Configuration.SavagePlayCooldown * modifier;
var fullProfile = profileHelper.GetFullProfile(pmcData?.SessionId);
var fullProfile = profileHelper.GetFullProfile(pmcData.SessionId.Value);
if (
fullProfile?.ProfileInfo?.Edition?.StartsWith(
AccountTypes.SPT_DEVELOPER,
@@ -633,7 +633,7 @@ public class RepeatableQuestRewardGenerator(
return new KeyValuePair<Reward, double>(
GeneratePresetReward(
chosenPreset.Encyclopedia,
chosenPreset.Encyclopedia.Value,
1,
rewardIndex,
chosenPreset.Items
@@ -244,6 +244,7 @@ public class ScavCaseRewardGenerator(
/// </summary>
/// <param name="items">item pool to pick rewards from</param>
/// <param name="itemFilters">how the rewards should be filtered down (by item count)</param>
/// <param name="rarity">Rarity of reward</param>
/// <returns></returns>
protected List<TemplateItem> PickRandomRewards(
List<TemplateItem> items,
@@ -30,11 +30,11 @@ public class BotGeneratorHelper(
// Equipment slot ids that do not conflict with other slots
private static readonly FrozenSet<string> _slotsWithNoCompatIssues =
[
EquipmentSlots.Scabbard.ToString(),
EquipmentSlots.Backpack.ToString(),
EquipmentSlots.SecuredContainer.ToString(),
EquipmentSlots.Holster.ToString(),
EquipmentSlots.ArmBand.ToString(),
nameof(EquipmentSlots.Scabbard),
nameof(EquipmentSlots.Backpack),
nameof(EquipmentSlots.SecuredContainer),
nameof(EquipmentSlots.Holster),
nameof(EquipmentSlots.ArmBand),
];
private static readonly string[] _pmcTypes =
@@ -39,7 +39,7 @@ public class BotHelper(
/// <returns>BotType object</returns>
public BotType? GetBotTemplate(string role)
{
if (!databaseService.GetBots().Types.TryGetValue(role?.ToLowerInvariant(), out var bot))
if (!databaseService.GetBots().Types.TryGetValue(role.ToLowerInvariant(), out var bot))
{
logger.Error($"Unable to get bot of type: {role} from DB");
@@ -69,12 +69,12 @@ public class BotHelper(
public bool IsBotFollower(string botRole)
{
return botRole?.StartsWith("follower", StringComparison.CurrentCultureIgnoreCase) ?? false;
return botRole.StartsWith("follower", StringComparison.CurrentCultureIgnoreCase);
}
public bool IsBotZombie(string botRole)
{
return botRole?.StartsWith("infected", StringComparison.CurrentCultureIgnoreCase) ?? false;
return botRole.StartsWith("infected", StringComparison.CurrentCultureIgnoreCase);
}
/// <summary>
@@ -87,7 +87,7 @@ public class BotHelper(
const string friendlyBotTypesKey = "FRIENDLY_BOT_TYPES";
// Null guard
if (difficultySettings.Mind[friendlyBotTypesKey] is null)
if (!difficultySettings.Mind.ContainsKey(friendlyBotTypesKey))
{
difficultySettings.Mind[friendlyBotTypesKey] = new List<string>();
}
@@ -105,13 +105,13 @@ public class BotHelper(
const string revengePropKey = "REVENGE_BOT_TYPES";
// Nothing to add
if (typesToAdd is null)
if (typesToAdd.Length == 0)
{
return;
}
// Null guard
if (difficultySettings.Mind[revengePropKey] is null)
if (!difficultySettings.Mind.ContainsKey(revengePropKey))
{
difficultySettings.Mind[revengePropKey] = new List<string>();
}
@@ -154,7 +154,7 @@ public class BotHelper(
{
// No randomisation details found, skip
return botEquipConfig?.Randomisation?.FirstOrDefault(randDetails =>
return botEquipConfig.Randomisation?.FirstOrDefault(randDetails =>
botLevel >= randDetails.LevelRange.Min && botLevel <= randDetails.LevelRange.Max
);
}
@@ -31,7 +31,7 @@ public class BotWeaponGeneratorHelper(
{
var randomizedMagazineCount = GetRandomizedMagazineCount(magCounts);
var parentItem = itemHelper.GetItem(magTemplate.Parent).Value;
double? chamberBulletCount = 0;
double? chamberBulletCount;
if (MagazineIsCylinderRelated(parentItem.Name))
{
var firstSlotAmmoTpl =
@@ -115,10 +115,8 @@ public class BotWeaponGeneratorHelper(
HashSet<EquipmentSlots>? equipmentSlotsToAddTo = null
)
{
if (equipmentSlotsToAddTo is null)
{
equipmentSlotsToAddTo = [EquipmentSlots.TacticalVest, EquipmentSlots.Pockets];
}
// null guard input param
equipmentSlotsToAddTo ??= [EquipmentSlots.TacticalVest, EquipmentSlots.Pockets];
var ammoItems = itemHelper.SplitStack(
new Item
@@ -16,7 +16,7 @@ public class CertificateHelper(ISptLogger<CertificateHelper> logger, FileUtil fi
//Todo: Finish off to match TS server
/// <summary>
/// Currently not in use
/// Not currently in use
/// </summary>
/// <returns></returns>
/// <exception cref="Exception"></exception>
@@ -85,17 +85,17 @@ public class CertificateHelper(ISptLogger<CertificateHelper> logger, FileUtil fi
/// <returns></returns>
private bool TryLoadCertificatePfx(out X509Certificate2? certificate)
{
X509Certificate2 cert = null;
if (!File.Exists(certificatePfxPath))
{
// file doesnt exist so create straight away
cert = GenerateSelfSignedCertificate("localhost");
// file doesn't exist so create straight away
var cert = GenerateSelfSignedCertificate("localhost");
SaveCertificatePfx(cert);
logger.Success($"Generated and stored self-signed certificate ({certificatePath})");
}
try
{
// TODO:
//Archangel: For some reason despite this being deprecated this is the only way to load a certificate file
//No idea why, I want to eventually switch over to the other format so it lines up with the TS server
//But for now this works fine
@@ -107,12 +107,7 @@ public class CertificateHelper(ISptLogger<CertificateHelper> logger, FileUtil fi
throw;
}
if (certificate is not null)
{
return true;
}
return false;
return certificate is not null;
}
/// <summary>
@@ -22,7 +22,7 @@ public abstract class AbstractDialogChatBot(
public async ValueTask<string> HandleMessage(MongoId sessionId, SendMessageRequest request)
{
if ((request.Text ?? "").Length == 0)
if (request.Text.Length == 0)
{
_logger.Error(localisationService.GetText("chatbot-command_was_empty"));
@@ -242,8 +242,12 @@ public class GiveSptCommand(
{
for (var i = 0; i < quantity; i++)
{
List<Item> ammoBoxArray = [];
ammoBoxArray.Add(new Item { Id = new MongoId(), Template = checkedItem.Value.Id });
List<Item> ammoBoxArray =
[
new() { Id = new MongoId(), Template = checkedItem.Value.Id },
// DO NOT generate the ammo box cartridges, the mail service does it for us! :)
// _itemHelper.addCartridgesToAmmoBox(ammoBoxArray, checkedItem[1]);
];
// DO NOT generate the ammo box cartridges, the mail service does it for us! :)
// _itemHelper.addCartridgesToAmmoBox(ammoBoxArray, checkedItem[1]);
itemsToSend.AddRange(ammoBoxArray);
@@ -14,7 +14,7 @@ public class FishMessageHandler(MailSendService _mailSendService) : IChatMessage
return 100;
}
public bool CanHandle(string message)
public bool CanHandle(string? message)
{
return string.Equals(message, "fish", StringComparison.OrdinalIgnoreCase);
}
@@ -3,13 +3,11 @@ using SPTarkov.Server.Core.Models.Common;
using SPTarkov.Server.Core.Models.Eft.Common;
using SPTarkov.Server.Core.Models.Eft.Profile;
using SPTarkov.Server.Core.Services;
using SPTarkov.Server.Core.Utils;
namespace SPTarkov.Server.Core.Helpers.Dialogue.SPTFriend.Commands;
[Injectable]
public class GarbageMessageHandler(MailSendService _mailSendService, RandomUtil _randomUtil)
: IChatMessageHandler
public class GarbageMessageHandler(MailSendService _mailSendService) : IChatMessageHandler
{
public int GetPriority()
{
@@ -10,10 +10,10 @@ using SPTarkov.Server.Core.Utils;
namespace SPTarkov.Server.Core.Helpers.Dialogue.SPTFriend.Commands;
[Injectable]
public class HelloMessageHandler(MailSendService _mailSendService, RandomUtil _randomUtil)
public class HelloMessageHandler(MailSendService mailSendService, RandomUtil randomUtil)
: IChatMessageHandler
{
protected static readonly FrozenSet<string> _listOfGreetings =
protected static readonly FrozenSet<string> _greetings =
[
"hello",
"hi",
@@ -30,7 +30,7 @@ public class HelloMessageHandler(MailSendService _mailSendService, RandomUtil _r
public bool CanHandle(string message)
{
return _listOfGreetings.Contains(message, StringComparer.OrdinalIgnoreCase);
return _greetings.Contains(message, StringComparer.OrdinalIgnoreCase);
}
public void Process(
@@ -40,10 +40,10 @@ public class HelloMessageHandler(MailSendService _mailSendService, RandomUtil _r
object? extraInfo = null
)
{
_mailSendService.SendUserMessageToPlayer(
mailSendService.SendUserMessageToPlayer(
sessionId,
sptFriendUser,
_randomUtil.GetArrayValue(
randomUtil.GetArrayValue(
[
"Howdy",
"Hi",
@@ -84,10 +84,10 @@ public class HelloMessageHandler(MailSendService _mailSendService, RandomUtil _r
SendMessageRequest request
)
{
_mailSendService.SendUserMessageToPlayer(
mailSendService.SendUserMessageToPlayer(
sessionId,
commandHandler,
_randomUtil.GetArrayValue(
randomUtil.GetArrayValue(
[
"Howdy",
"Hi",
@@ -34,7 +34,7 @@ public class SendGiftMessageHandler(
public void Process(
MongoId sessionId,
UserDialogInfo sptFriendUser,
PmcData sender,
PmcData? sender,
object? extraInfo = null
)
{
@@ -72,10 +72,7 @@ public class DialogueHelper(ISptLogger<DialogueHelper> logger, ProfileHelper pro
// Check reward count when item being moved isn't in reward list
// If count is 0, it means after this move occurs the reward array will be empty and all rewards collected
if (message.Items.Data is null)
{
message.Items.Data = [];
}
message.Items.Data ??= [];
var messageItems = message.Items.Data?.Where(x => x.Id != itemId);
if (messageItems is null || !messageItems.Any())
@@ -213,7 +213,7 @@ public class HideoutHelper(
);
}
stashItem.Template = bonus.TemplateId;
stashItem.Template = bonus.TemplateId.Value;
break;
}
@@ -869,9 +869,7 @@ public class HideoutHelper(
var waterFilterItemInSlot = waterFilterArea.Slots[i].Items[0];
// How many units of filter are left
var resourceValue = waterFilterItemInSlot.Upd?.Resource is not null
? waterFilterItemInSlot.Upd.Resource.Value
: null;
var resourceValue = waterFilterItemInSlot.Upd?.Resource?.Value;
if (resourceValue is null)
{
// Missing, is new filter, add default and subtract usage
@@ -1184,7 +1182,7 @@ public class HideoutHelper(
// BSG finally fixed their settings, they now get loaded from the settings and used in the client
var adjustedCraftTime =
(
profileHelper.IsDeveloperAccount(pmcData.SessionId)
profileHelper.IsDeveloperAccount(pmcData.SessionId.Value)
? 40
: bitcoinProdData.ProductionTime
) / (1 + (btcFarmCGs - 1) * databaseService.GetHideout().Settings.GpuBoostRate);
@@ -1491,7 +1489,7 @@ public class HideoutHelper(
/// <summary>
/// Add/remove bonus combat skill based on number of dogtags in place of fame hideout area
/// </summary>
/// <param name="profileData">Player profile</param>
/// <param name="pmcData">Player profile</param>
public void ApplyPlaceOfFameDogtagBonus(PmcData pmcData)
{
var fameAreaProfile = pmcData.Hideout.Areas.FirstOrDefault(area =>
@@ -1171,7 +1171,7 @@ public class InventoryHelper(
HandleCartridgeMove(sourceItems, request);
// Get all children item has, they need to move with item
var idsToMove = sourceItems.FindAndReturnChildrenByItems(request.Item);
var idsToMove = sourceItems.FindAndReturnChildrenByItems(request.Item.Value);
foreach (var itemId in idsToMove)
{
var itemToMove = sourceItems.FirstOrDefault(item => item.Id == itemId);
@@ -1192,16 +1192,8 @@ public class InventoryHelper(
itemToMove.ParentId = request.To.Id;
itemToMove.SlotId = request.To.Container;
if (request.To.Location is not null)
// Update location object
{
itemToMove.Location = request.To.Location;
}
else
// No location in request, delete it
{
itemToMove.Location = null;
}
itemToMove.Location = request.To.Location ?? null; // No location in request, delete it
}
toItems.Add(itemToMove);
@@ -33,7 +33,9 @@ public class PresetHelper(DatabaseService databaseService, ItemHelper itemHelper
var weapons = GetDefaultWeaponPresets();
var equipment = GetDefaultEquipmentPresets();
return weapons.Union(equipment).ToDictionary();
return weapons
.UnionBy(equipment, kvp => kvp.Key)
.ToDictionary(kvp => kvp.Key, kvp => kvp.Value);
}
/// <summary>
@@ -64,7 +66,7 @@ public class PresetHelper(DatabaseService databaseService, ItemHelper itemHelper
_defaultWeaponPresets = tempPresets
.Where(p =>
p.Value.Encyclopedia != null
&& itemHelper.IsOfBaseclass(p.Value.Encyclopedia, BaseClasses.WEAPON)
&& itemHelper.IsOfBaseclass(p.Value.Encyclopedia.Value, BaseClasses.WEAPON)
)
.ToDictionary();
}
@@ -84,7 +86,7 @@ public class PresetHelper(DatabaseService databaseService, ItemHelper itemHelper
_defaultEquipmentPresets = tempPresets
.Where(p =>
p.Value.Encyclopedia != null
&& itemHelper.ArmorItemCanHoldMods(p.Value.Encyclopedia)
&& itemHelper.ArmorItemCanHoldMods(p.Value.Encyclopedia.Value)
)
.ToDictionary();
}
@@ -115,7 +117,8 @@ public class PresetHelper(DatabaseService databaseService, ItemHelper itemHelper
*/
public bool IsPresetBaseClass(MongoId id, MongoId baseClass)
{
return IsPreset(id) && itemHelper.IsOfBaseclass(GetPreset(id).Encyclopedia, baseClass);
return IsPreset(id)
&& itemHelper.IsOfBaseclass(GetPreset(id).Encyclopedia.Value, baseClass);
}
/// <summary>
@@ -38,7 +38,7 @@ public class ProfileHelper(
/// <summary>
/// Remove/reset a completed quest condition from players profile quest data
/// </summary>
/// <param name="sessionID">Session id</param>
/// <param name="pmcData">Player profile</param>
/// <param name="questConditionId">Quest with condition to remove</param>
public void RemoveQuestConditionFromProfile(
PmcData pmcData,
@@ -273,7 +273,7 @@ public class ProfileHelper(
{
return new SearchFriendResponse
{
Id = pmcProfile.Id,
Id = pmcProfile.Id.Value,
Aid = pmcProfile.Aid,
Info = new UserDialogDetails
{
@@ -467,9 +467,7 @@ public class QuestHelper(
// Include if quest found in profile and is started or ready to hand in
return startedQuestInProfile is not null
&& _startedOrAvailToFinish.Contains(
(QuestStatusEnum)startedQuestInProfile.Status
);
&& _startedOrAvailToFinish.Contains(startedQuestInProfile.Status);
});
return GetQuestsWithOnlyLevelRequirementStartCondition(eligibleQuests).ToList();
@@ -616,7 +614,7 @@ public class QuestHelper(
}
/// <summary>
/// Sets the item stack to new value, or delete the item if value <= 0
/// Sets the item stack to new value, or delete the item if value is less than or equal 0
/// </summary>
/// <param name="pmcData">Profile</param>
/// <param name="itemId">Id of item to adjust stack size of</param>
@@ -181,7 +181,7 @@ public class RagfairOfferHelper(
{
// Get all offers that require the desired item and filter out offers from non traders if player below ragfair unlock
var offerIDsForItem = ragfairRequiredItemsService.GetRequiredOffersById(
searchRequest.NeededSearchId
searchRequest.NeededSearchId.Value
);
var tieredFlea = _ragfairConfig.TieredFlea;
@@ -438,12 +438,7 @@ public class RagfairOfferHelper(
return false;
}
if (
!assort.Items.Any(item =>
{
return item.Id == offer.Root;
})
)
if (!assort.Items.Any(item => item.Id == offer.Root))
// skip (quest) locked items
{
return false;
@@ -561,12 +556,12 @@ public class RagfairOfferHelper(
/// <returns>true if out of stock</returns>
protected bool TraderOutOfStock(RagfairOffer offer)
{
if (offer?.Items?.Count == 0)
if (offer.Items?.Count == 0)
{
return true;
}
return offer.Items[0]?.Upd?.StackObjectsCount == 0;
return offer.Items.FirstOrDefault()?.Upd?.StackObjectsCount == 0;
}
/// <summary>
@@ -620,7 +615,7 @@ public class RagfairOfferHelper(
protected HashSet<string> GetLoyaltyLockedOffers(List<RagfairOffer> offers, PmcData pmcProfile)
{
var loyaltyLockedOffers = new HashSet<string>();
foreach (var offer in offers.Where(offer => OfferIsFromTrader(offer)))
foreach (var offer in offers.Where(OfferIsFromTrader))
{
if (
pmcProfile.TradersInfo.TryGetValue(offer.User.Id, out var traderDetails)
@@ -645,7 +640,7 @@ public class RagfairOfferHelper(
var profileOffers = GetProfileOffers(sessionId);
// No offers, don't do anything
if (profileOffers?.Count == 0)
if (!profileOffers.Any())
{
return true;
}
@@ -1078,7 +1073,7 @@ public class RagfairOfferHelper(
var offerRootTemplate = itemHelper.GetItem(offerRootItem.Template).Value;
var requiredPlateCount = offerRootTemplate
.Properties.Slots?.Where(item => item.Required.GetValueOrDefault(false))
?.Count();
.Count();
return offer.Items.Count > requiredPlateCount;
}
@@ -1,3 +1,4 @@
using System.Globalization;
using SPTarkov.DI.Annotations;
using SPTarkov.Server.Core.Models.Eft.Ragfair;
using SPTarkov.Server.Core.Models.Spt.Config;
@@ -141,7 +142,7 @@ public class RagfairSellHelper(
if (logger.IsLogEnabled(LogLevel.Debug))
{
logger.Debug(
$"Offer will sell at: {timeUtil.GetDateTimeFromTimeStamp(sellTimestamp).ToLocalTime().ToString()}, bought: {boughtAmount}"
$"Offer will sell at: {timeUtil.GetDateTimeFromTimeStamp(sellTimestamp).ToLocalTime().ToString(CultureInfo.InvariantCulture)}, bought: {boughtAmount}"
);
}
}
@@ -37,7 +37,7 @@ public class RagfairSortHelper(LocaleService localeService)
break;
case RagfairSort.OFFER_TITLE:
offers.Sort((a, b) => SortOffersByName(a, b));
offers.Sort(SortOffersByName);
break;
case RagfairSort.PRICE:
@@ -79,8 +79,8 @@ public class RagfairSortHelper(LocaleService localeService)
protected int SortOffersByRating(RagfairOffer a, RagfairOffer b)
{
double ratingA = a?.User?.Rating ?? 0.0;
double ratingB = b?.User?.Rating ?? 0.0;
var ratingA = a.User?.Rating ?? 0.0;
var ratingB = b.User?.Rating ?? 0.0;
return ratingA.CompareTo(ratingB);
}
@@ -94,7 +94,7 @@ public class RagfairSortHelper(LocaleService localeService)
var nameA = locale.GetValueOrDefault($"{tplA} Name", tplA);
var nameB = locale.GetValueOrDefault($"{tplB} Name", tplB);
return string.Compare(nameA, nameB);
return string.CompareOrdinal(nameA, nameB);
}
/**
@@ -277,7 +277,7 @@ public class TradeHelper(
return;
}
/// Pay for purchase
// Pay for purchase
paymentService.PayMoney(pmcData, buyRequestData, sessionID, output);
if (output.Warnings?.Count > 0)
{
@@ -21,7 +21,6 @@ public class TraderHelper(
DatabaseService databaseService,
ProfileHelper profileHelper,
HandbookHelper handbookHelper,
ItemHelper itemHelper,
ServerLocalisationService serverLocalisationService,
FenceService fenceService,
TraderStore traderStore,
@@ -451,6 +450,7 @@ public class TraderHelper(
/// </summary>
/// <param name="sessionID">Session id</param>
/// <param name="newPurchaseDetails">New item assort id + count</param>
/// <param name="itemPurchased">Item purchased</param>
public void AddTraderPurchasesToPlayerProfile(
MongoId sessionID,
PurchaseDetails newPurchaseDetails,
@@ -43,35 +43,15 @@ public class BundleInfo
}
[Injectable(InjectionType.Singleton)]
public class BundleLoader
public class BundleLoader(
ISptLogger<BundleLoader> logger,
JsonUtil jsonUtil,
FileUtil fileUtil,
BundleHashCacheService bundleHashCacheService,
ICloner cloner
)
{
private readonly BundleHashCacheService _bundleHashCacheService;
private readonly Dictionary<string, BundleInfo> _bundles = new();
private readonly ICloner _cloner;
private readonly FileUtil _fileUtil;
private readonly HashUtil _hashUtil;
private readonly InMemoryCacheService _inMemoryCacheService;
private readonly JsonUtil _jsonUtil;
private readonly ISptLogger<BundleLoader> _logger;
public BundleLoader(
ISptLogger<BundleLoader> logger,
HashUtil hashUtil,
JsonUtil jsonUtil,
FileUtil fileUtil,
BundleHashCacheService bundleHashCacheService,
InMemoryCacheService inMemoryCacheService,
ICloner cloner
)
{
_logger = logger;
_hashUtil = hashUtil;
_jsonUtil = jsonUtil;
_fileUtil = fileUtil;
_bundleHashCacheService = bundleHashCacheService;
_inMemoryCacheService = inMemoryCacheService;
_cloner = cloner;
}
/// <summary>
/// Handle singleplayer/bundles
@@ -91,7 +71,7 @@ public class BundleLoader
public BundleInfo? GetBundle(string bundleKey)
{
return _cloner.Clone(_bundles.GetValueOrDefault(bundleKey));
return cloner.Clone(_bundles.GetValueOrDefault(bundleKey));
}
public void AddBundles(string modPath)
@@ -99,10 +79,10 @@ public class BundleLoader
// modPath should be relative to the server exe - ./user/mods/Mod3
// TODO: make sure the mod is passing a path that is relative from the server exe
var modBundlesJson = _fileUtil.ReadFile(
var modBundlesJson = fileUtil.ReadFile(
Path.Join(Directory.GetCurrentDirectory(), modPath, "bundles.json")
);
var modBundles = _jsonUtil.Deserialize<BundleManifest>(modBundlesJson);
var modBundles = jsonUtil.Deserialize<BundleManifest>(modBundlesJson);
var bundleManifestArr = modBundles?.Manifest;
foreach (var bundleManifest in bundleManifestArr)
@@ -112,12 +92,12 @@ public class BundleLoader
var bundleLocalPath = Path.Join(relativeModPath, "bundles", bundleManifest.Key)
.Replace('\\', '/');
if (!_bundleHashCacheService.CalculateAndMatchHash(bundleLocalPath))
if (!bundleHashCacheService.CalculateAndMatchHash(bundleLocalPath))
{
_bundleHashCacheService.CalculateAndStoreHash(bundleLocalPath);
bundleHashCacheService.CalculateAndStoreHash(bundleLocalPath);
}
var bundleHash = _bundleHashCacheService.GetStoredValue(bundleLocalPath);
var bundleHash = bundleHashCacheService.GetStoredValue(bundleLocalPath);
AddBundle(
bundleManifest.Key,
@@ -131,7 +111,7 @@ public class BundleLoader
var success = _bundles.TryAdd(key, bundle);
if (!success)
{
_logger.Error($"Unable to add bundle: {key}");
logger.Error($"Unable to add bundle: {key}");
}
}
}
@@ -9,6 +9,7 @@ namespace SPTarkov.Server.Core.Migration
/// Allows for adding checks if the profile in question can migrate
/// </summary>
/// <param name="profile">The profile to check</param>
/// <param name="previouslyRanMigrations"></param>
/// <returns>Returns true if the profile can migrate, returns false if not</returns>
public bool CanMigrate(
JsonObject profile,
@@ -1,7 +1,6 @@
using System.Text.Json.Nodes;
using SPTarkov.DI.Annotations;
using SPTarkov.Server.Core.Services;
using Range = SemanticVersioning.Range;
namespace SPTarkov.Server.Core.Migration.Migrations
{
@@ -6,7 +6,6 @@ using SPTarkov.Server.Core.Models.Eft.Common.Tables;
using SPTarkov.Server.Core.Models.Eft.Profile;
using SPTarkov.Server.Core.Models.Enums;
using SPTarkov.Server.Core.Services;
using SPTarkov.Server.Core.Utils;
using Range = SemanticVersioning.Range;
namespace SPTarkov.Server.Core.Migration.Migrations
@@ -77,10 +76,7 @@ namespace SPTarkov.Server.Core.Migration.Migrations
profile.AddCustomisationUnlocksToProfile();
}
if (profile.CharacterData.PmcData.Prestige is null)
{
profile.CharacterData.PmcData.Prestige = [];
}
profile.CharacterData.PmcData.Prestige ??= [];
if (profile.CharacterData.PmcData.Inventory.HideoutCustomizationStashId is null)
{
@@ -1,4 +1,5 @@
using System.Text.Json.Serialization;
using SPTarkov.Server.Core.Models.Common;
using SPTarkov.Server.Core.Models.Eft.Common.Tables;
using SPTarkov.Server.Core.Models.Eft.Hideout;
using SPTarkov.Server.Core.Models.Enums;
@@ -5016,7 +5017,7 @@ public record Preset
/// Default presets have this property
/// </summary>
[JsonPropertyName("_encyclopedia")]
public string? Encyclopedia { get; set; }
public MongoId? Encyclopedia { get; set; }
}
public record QuestSettings
@@ -24,7 +24,7 @@ public record BotBase
/// SPT property - use to store player id - TODO - move to AID ( account id as guid of choice)
/// </summary>
[JsonPropertyName("sessionId")]
public string? SessionId { get; set; }
public MongoId? SessionId { get; set; }
[JsonIgnore(Condition = JsonIgnoreCondition.Never)]
[JsonPropertyName("savage")]
@@ -620,7 +620,7 @@ public record Aggressor
public string? AccountId { get; set; }
[JsonIgnore(Condition = JsonIgnoreCondition.Never)]
public string? ProfileId { get; set; }
public MongoId? ProfileId { get; set; }
[JsonIgnore(Condition = JsonIgnoreCondition.Never)]
public string? MainProfileNickname { get; set; }
@@ -1039,7 +1039,7 @@ public record Bonus
public BonusType? Type { get; set; }
[JsonPropertyName("templateId")]
public string? TemplateId { get; set; }
public MongoId? TemplateId { get; set; }
[JsonPropertyName("passive")]
public bool? IsPassive { get; set; }
@@ -1,4 +1,5 @@
using System.Text.Json.Serialization;
using SPTarkov.Server.Core.Models.Common;
namespace SPTarkov.Server.Core.Models.Eft.Common.Tables;
@@ -9,7 +10,7 @@ public record CustomisationStorage
// Customisation.json/itemId
[JsonPropertyName("id")]
public string Id { get; set; }
public MongoId Id { get; set; }
[JsonPropertyName("source")]
public string? Source { get; set; }
@@ -1,4 +1,5 @@
using System.Text.Json.Serialization;
using SPTarkov.Server.Core.Models.Common;
namespace SPTarkov.Server.Core.Models.Eft.Common.Tables;
@@ -56,13 +57,13 @@ public class CustomizationProps
public List<string>? Game { get; set; }
[JsonPropertyName("Hands")]
public string? Hands { get; set; }
public MongoId? Hands { get; set; }
[JsonPropertyName("Feet")]
public string? Feet { get; set; }
public MongoId? Feet { get; set; }
[JsonPropertyName("Body")]
public string? Body { get; set; }
public MongoId? Body { get; set; }
[JsonPropertyName("ProfileVersions")]
public List<string>? ProfileVersions { get; set; }
@@ -199,7 +199,7 @@ public record LockableComponent
[JsonExtensionData]
public Dictionary<string, object>? ExtensionData { get; set; }
public string[]? KeyIds { get; set; }
public List<string>? KeyIds { get; set; }
public bool? Locked { get; set; }
public LockableKeyComponent? KeyComponent { get; set; }
}
@@ -1,4 +1,5 @@
using System.Text.Json.Serialization;
using SPTarkov.Server.Core.Models.Common;
using SPTarkov.Server.Core.Models.Eft.Profile;
namespace SPTarkov.Server.Core.Models.Eft.Common.Tables;
@@ -27,7 +28,7 @@ public record TemplateSide
public PmcData? Character { get; set; }
[JsonPropertyName("suits")]
public List<string>? Suits { get; set; }
public List<MongoId>? Suits { get; set; }
[JsonPropertyName("dialogues")]
public Dictionary<string, Dialogue>? Dialogues { get; set; }
@@ -1,4 +1,5 @@
using System.Text.Json.Serialization;
using SPTarkov.Server.Core.Models.Common;
namespace SPTarkov.Server.Core.Models.Eft.Common.Tables;
@@ -150,7 +151,7 @@ public record ChangeCost
/// What item it will take to reset daily
/// </summary>
[JsonPropertyName("templateId")]
public string? TemplateId { get; set; }
public MongoId TemplateId { get; set; }
/// <summary>
/// Amount of item needed to reset
@@ -789,7 +789,7 @@ public record Props
public MongoId? DefMagType { get; set; }
[JsonPropertyName("defAmmo")]
public string? DefAmmo { get; set; }
public MongoId? DefAmmo { get; set; }
[JsonPropertyName("AdjustCollimatorsToTrajectory")]
public bool? AdjustCollimatorsToTrajectory { get; set; }
@@ -1797,7 +1797,7 @@ public record SlotFilter
public bool? Locked { get; set; }
[JsonPropertyName("Plate")]
public string? Plate { get; set; }
public MongoId? Plate { get; set; }
[JsonPropertyName("armorColliders")]
public List<string>? ArmorColliders { get; set; }
@@ -298,7 +298,7 @@ public record Suit
public Dictionary<string, object>? ExtensionData { get; set; }
[JsonPropertyName("_id")]
public string? Id { get; set; }
public MongoId Id { get; set; }
[JsonPropertyName("externalObtain")]
public bool? ExternalObtain { get; set; }
@@ -310,10 +310,10 @@ public record Suit
public bool? IsHiddenInPVE { get; set; }
[JsonPropertyName("tid")]
public string? Tid { get; set; }
public MongoId Tid { get; set; }
[JsonPropertyName("suiteId")]
public string? SuiteId { get; set; }
public MongoId SuiteId { get; set; }
[JsonPropertyName("isActive")]
public bool? IsActive { get; set; }
@@ -356,7 +356,7 @@ public record SuitRequirements
public List<ItemRequirement>? ItemRequirements { get; set; }
[JsonPropertyName("requiredTid")]
public string? RequiredTid { get; set; }
public MongoId? RequiredTid { get; set; }
}
public record ItemRequirement
@@ -368,7 +368,7 @@ public record ItemRequirement
public double? Count { get; set; }
[JsonPropertyName("_tpl")]
public string? Tpl { get; set; }
public MongoId Tpl { get; set; }
[JsonPropertyName("id")]
public string? Id { get; set; }
@@ -1,4 +1,5 @@
using System.Text.Json.Serialization;
using SPTarkov.Server.Core.Models.Common;
using SPTarkov.Server.Core.Models.Eft.Inventory;
namespace SPTarkov.Server.Core.Models.Eft.Customization;
@@ -24,7 +25,7 @@ public record PaymentItemForClothing
public bool? Del { get; set; }
[JsonPropertyName("id")]
public string? Id { get; set; }
public MongoId Id { get; set; }
[JsonPropertyName("count")]
public int? Count { get; set; }
@@ -1,4 +1,5 @@
using System.Text.Json.Serialization;
using SPTarkov.Server.Core.Models.Common;
using SPTarkov.Server.Core.Models.Eft.Inventory;
namespace SPTarkov.Server.Core.Models.Eft.Customization;
@@ -18,7 +19,7 @@ public record CustomizationSetOption
public Dictionary<string, object>? ExtensionData { get; set; }
[JsonPropertyName("id")]
public string? Id { get; set; }
public MongoId Id { get; set; }
[JsonPropertyName("type")]
public string? Type { get; set; }
@@ -77,7 +77,7 @@ public record Stage
/// Containers inventory tpl
/// </summary>
[JsonPropertyName("container")]
public string? Container { get; set; }
public MongoId? Container { get; set; }
[JsonPropertyName("description")]
public string? Description { get; set; }
@@ -91,7 +91,7 @@ public record Requirement
public int? Resource { get; set; }
[JsonPropertyName("questId")]
public string? QuestId { get; set; }
public MongoId? QuestId { get; set; }
[JsonPropertyName("isSpawnedInSession")]
public bool? IsSpawnedInSession { get; set; }
@@ -1,4 +1,5 @@
using System.Text.Json.Serialization;
using SPTarkov.Server.Core.Models.Common;
namespace SPTarkov.Server.Core.Models.Eft.Inventory;
@@ -8,7 +9,7 @@ public record InventoryFoldRequestData : InventoryBaseActionRequestData
public Dictionary<string, object>? ExtensionData { get; set; }
[JsonPropertyName("item")]
public string? Item { get; set; }
public MongoId? Item { get; set; }
[JsonPropertyName("value")]
public bool? Value { get; set; }
@@ -1,4 +1,5 @@
using System.Text.Json.Serialization;
using SPTarkov.Server.Core.Models.Common;
namespace SPTarkov.Server.Core.Models.Eft.Inventory;
@@ -8,7 +9,7 @@ public record InventoryMoveRequestData : InventoryBaseActionRequestData
public Dictionary<string, object>? ExtensionData { get; set; }
[JsonPropertyName("item")]
public string? Item { get; set; }
public MongoId? Item { get; set; }
[JsonPropertyName("to")]
public To? To { get; set; }
@@ -1,4 +1,5 @@
using System.Text.Json.Serialization;
using SPTarkov.Server.Core.Models.Common;
namespace SPTarkov.Server.Core.Models.Eft.Inventory;
@@ -11,7 +12,7 @@ public record OpenRandomLootContainerRequestData : InventoryBaseActionRequestDat
/// Container item id being opened
/// </summary>
[JsonPropertyName("item")]
public string? Item { get; set; }
public MongoId Item { get; set; }
[JsonPropertyName("to")]
public List<ItemEvent.To>? To { get; set; }
@@ -1,4 +1,5 @@
using System.Text.Json.Serialization;
using SPTarkov.Server.Core.Models.Common;
namespace SPTarkov.Server.Core.Models.Eft.Inventory;
@@ -17,8 +18,8 @@ public record RedeemProfileRequestEvent
public Dictionary<string, object>? ExtensionData { get; set; }
[JsonPropertyName("MessageId")]
public string? MessageId { get; set; }
public MongoId MessageId { get; set; }
[JsonPropertyName("EventId")]
public string? EventId { get; set; }
public MongoId EventId { get; set; }
}
@@ -1,4 +1,5 @@
using System.Text.Json.Serialization;
using SPTarkov.Server.Core.Models.Common;
using SPTarkov.Server.Core.Models.Utils;
namespace SPTarkov.Server.Core.Models.Eft.Location;
@@ -9,5 +10,5 @@ public record GetAirdropLootRequest : IRequestData
public Dictionary<string, object>? ExtensionData { get; set; }
[JsonPropertyName("containerId")]
public string? ContainerId { get; set; }
public MongoId ContainerId { get; set; }
}
@@ -1,4 +1,5 @@
using System.Text.Json.Serialization;
using SPTarkov.Server.Core.Models.Common;
using SPTarkov.Server.Core.Models.Utils;
namespace SPTarkov.Server.Core.Models.Eft.Profile;
@@ -9,5 +10,5 @@ public record ProfileChangeVoiceRequestData : IRequestData
public Dictionary<string, object>? ExtensionData { get; set; }
[JsonPropertyName("voice")]
public string? Voice { get; set; }
public MongoId Voice { get; set; }
}
@@ -1,4 +1,5 @@
using System.Text.Json.Serialization;
using SPTarkov.Server.Core.Models.Common;
using SPTarkov.Server.Core.Models.Utils;
namespace SPTarkov.Server.Core.Models.Eft.Profile;
@@ -15,10 +16,10 @@ public record ProfileCreateRequestData : IRequestData
public string? Nickname { get; set; }
[JsonPropertyName("headId")]
public string? HeadId { get; set; }
public MongoId HeadId { get; set; }
[JsonPropertyName("voiceId")]
public string? VoiceId { get; set; }
public MongoId VoiceId { get; set; }
[JsonPropertyName("sptForcePrestigeLevel")]
public int? SptForcePrestigeLevel { get; set; }
@@ -1,4 +1,5 @@
using System.Text.Json.Serialization;
using SPTarkov.Server.Core.Models.Common;
namespace SPTarkov.Server.Core.Models.Eft.Profile;
@@ -11,7 +12,7 @@ public record SearchFriendResponse
public Dictionary<string, object>? ExtensionData { get; set; }
[JsonPropertyName("_id")]
public string? Id { get; set; }
public MongoId Id { get; set; }
[JsonPropertyName("aid")]
public int? Aid { get; set; }
@@ -57,7 +57,7 @@ public record SptProfile
/// List of friend profile IDs
/// </summary>
[JsonPropertyName("friends")]
public List<string>? FriendProfileIds { get; set; }
public List<MongoId>? FriendProfileIds { get; set; }
/// <summary>
/// Stores profile-related customisation, e.g. clothing / hideout walls / floors
@@ -232,7 +232,7 @@ public record Dialogue
public List<Message>? Messages { get; set; }
[JsonPropertyName("_id")]
public string? Id { get; set; }
public MongoId Id { get; set; }
}
//TODO: @Cleanup: Maybe the same as Dialogue?
@@ -557,7 +557,7 @@ public record BtrDelivery
public Dictionary<string, object>? ExtensionData { get; set; }
[JsonPropertyName("_id")]
public string? Id { get; set; }
public MongoId Id { get; set; }
[JsonPropertyName("scheduledTime")]
public int? ScheduledTime { get; set; }
@@ -1,4 +1,5 @@
using System.Text.Json.Serialization;
using SPTarkov.Server.Core.Models.Common;
using SPTarkov.Server.Core.Models.Eft.Inventory;
namespace SPTarkov.Server.Core.Models.Eft.Quests;
@@ -9,7 +10,7 @@ public record AcceptQuestRequestData : InventoryBaseActionRequestData
public Dictionary<string, object>? ExtensionData { get; set; }
[JsonPropertyName("qid")]
public string? QuestId { get; set; }
public MongoId QuestId { get; set; }
[JsonPropertyName("type")]
public string? Type { get; set; }
@@ -10,10 +10,10 @@ public record HandoverQuestRequestData : InventoryBaseActionRequestData
public Dictionary<string, object>? ExtensionData { get; set; }
[JsonPropertyName("qid")]
public string? QuestId { get; set; }
public MongoId QuestId { get; set; }
[JsonPropertyName("conditionId")]
public string? ConditionId { get; set; }
public MongoId ConditionId { get; set; }
[JsonPropertyName("items")]
public List<IdWithCount>? Items { get; set; }
@@ -1,4 +1,5 @@
using System.Text.Json.Serialization;
using SPTarkov.Server.Core.Models.Common;
using SPTarkov.Server.Core.Models.Eft.Inventory;
namespace SPTarkov.Server.Core.Models.Eft.Quests;
@@ -9,5 +10,5 @@ public record RepeatableQuestChangeRequest : InventoryBaseActionRequestData
public Dictionary<string, object>? ExtensionData { get; set; }
[JsonPropertyName("qid")]
public string? QuestId { get; set; }
public MongoId QuestId { get; set; }
}
@@ -68,7 +68,7 @@ public record SearchRequestData : IRequestData
public string? LinkedSearchId { get; set; }
[JsonPropertyName("neededSearchId")]
public string? NeededSearchId { get; set; }
public MongoId? NeededSearchId { get; set; }
[JsonPropertyName("buildItems")]
public Dictionary<MongoId, double>? BuildItems { get; set; }
@@ -28,7 +28,7 @@ public record RepairKitsInfo
/// id of repair kit to use
/// </summary>
[JsonPropertyName("_id")]
public string? Id { get; set; }
public MongoId Id { get; set; }
/// <summary>
/// amount of units to reduce kit by
@@ -1,4 +1,5 @@
using System.Text.Json.Serialization;
using SPTarkov.Server.Core.Models.Common;
using SPTarkov.Server.Core.Models.Eft.Inventory;
namespace SPTarkov.Server.Core.Models.Eft.Repair;
@@ -9,7 +10,7 @@ public record TraderRepairActionDataRequest : InventoryBaseActionRequestData
public Dictionary<string, object>? ExtensionData { get; set; }
[JsonPropertyName("tid")]
public string? TId { get; set; }
public MongoId TraderId { get; set; }
[JsonPropertyName("repairItems")]
public List<RepairItem>? RepairItems { get; set; }
@@ -21,7 +22,7 @@ public record RepairItem
public Dictionary<string, object>? ExtensionData { get; set; }
[JsonPropertyName("_id")]
public string? Id { get; set; }
public MongoId Id { get; set; }
[JsonPropertyName("count")]
public double? Count { get; set; }
@@ -57,7 +57,7 @@ public record Weather
public double? WindSpeed { get; set; }
/// <summary>
/// < -0.4 = clear day
/// less than -0.4 = clear day
/// </summary>
[JsonPropertyName("cloud")]
public double? Cloud { get; set; }
@@ -43,7 +43,7 @@ public record GenerateWeaponRequest
/// Ammo tpl to use when generating magazines/cartridges
/// </summary>
[JsonPropertyName("ammoTpl")]
public string? AmmoTpl { get; set; }
public MongoId? AmmoTpl { get; set; }
/// <summary>
/// Bot-specific properties
@@ -79,7 +79,7 @@ public record CreateItemResult
public CreateItemResult()
{
Success = false;
Errors = new List<string>();
Errors = [];
}
[JsonPropertyName("success")]
@@ -20,5 +20,5 @@ public record InsuranceEquipmentPkg
public Item? ItemToReturnToPlayer { get; set; }
[JsonPropertyName("traderId")]
public string? TraderId { get; set; }
public MongoId TraderId { get; set; }
}
@@ -19,11 +19,11 @@ public class CustomizationItemEventRouter(
{
protected override List<HandledRoute> GetHandledRoutes()
{
return new List<HandledRoute>
{
return
[
new(ItemEventActions.CUSTOMIZATION_BUY, false),
new(ItemEventActions.CUSTOMIZATION_SET, false),
};
];
}
public override ValueTask<ItemEventRouterResponse> HandleItemEvent(
@@ -16,7 +16,7 @@ public class InsuranceItemEventRouter(InsuranceCallbacks insuranceCallbacks)
{
protected override List<HandledRoute> GetHandledRoutes()
{
return new List<HandledRoute> { new(ItemEventActions.INSURE, false) };
return [new(ItemEventActions.INSURE, false)];
}
public override ValueTask<ItemEventRouterResponse> HandleItemEvent(
@@ -15,12 +15,12 @@ public class NoteItemEventRouter(NoteCallbacks noteCallbacks) : ItemEventRouterD
{
protected override List<HandledRoute> GetHandledRoutes()
{
return new List<HandledRoute>
{
return
[
new(ItemEventActions.ADD_NOTE, false),
new(ItemEventActions.EDIT_NOTE, false),
new(ItemEventActions.DELETE_NOTE, false),
};
];
}
public override ValueTask<ItemEventRouterResponse> HandleItemEvent(

Some files were not shown because too many files have changed in this diff Show More