diff --git a/Core/Controllers/CustomizationController.cs b/Core/Controllers/CustomizationController.cs
index 10b34c00..cdcc8071 100644
--- a/Core/Controllers/CustomizationController.cs
+++ b/Core/Controllers/CustomizationController.cs
@@ -1,25 +1,71 @@
using Core.Annotations;
+using Core.Helpers;
using Core.Models.Eft.Common;
using Core.Models.Eft.Common.Tables;
using Core.Models.Eft.Customization;
using Core.Models.Eft.Hideout;
using Core.Models.Eft.ItemEvent;
using Core.Models.Eft.Profile;
+using Core.Models.Enums;
+using Core.Routers;
+using Core.Servers;
+using Core.Services;
+using Core.Utils.Cloners;
+using ILogger = Core.Models.Utils.ILogger;
+using Product = Core.Models.Eft.ItemEvent.Product;
namespace Core.Controllers;
[Injectable]
public class CustomizationController
{
+ protected ILogger _logger;
+ protected EventOutputHolder _eventOutputHolder;
+ protected DatabaseService _databaseService;
+ protected SaveServer _saveServer;
+ protected LocalisationService _localisationService;
+ protected ProfileHelper _profileHelper;
+ protected ICloner _cloner;
+
+ public CustomizationController
+ (
+ ILogger logger,
+ EventOutputHolder eventOutputHolder,
+ DatabaseService databaseService,
+ SaveServer saveServer,
+ LocalisationService localisationService,
+ ProfileHelper profileHelper,
+ ICloner cloner
+ )
+ {
+ _logger = logger;
+ _eventOutputHolder = eventOutputHolder;
+ _databaseService = databaseService;
+ _saveServer = saveServer;
+ _localisationService = localisationService;
+ _profileHelper = profileHelper;
+ _cloner = cloner;
+ }
+
///
/// Get purchasable clothing items from trader that match players side (usec/bear)
///
/// trader to look up clothing for
/// Session id
/// Suit array
- public Suit GetTraderSuits(string traderId, string sessionId)
+ public List GetTraderSuits(string traderId, string sessionId)
{
- throw new NotImplementedException();
+ 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();
+ matchingSuits = matchingSuits?.Where(s => clothing[s.SuiteId].Properties.Side.Contains(pmcData.Info.Side)).ToList();
+
+ if (matchingSuits == null)
+ throw new Exception(_localisationService.GetText("customisation-unable_to_get_trader_suits", traderId));
+
+ return matchingSuits;
}
///
@@ -35,7 +81,41 @@ public class CustomizationController
BuyClothingRequestData buyClothingRequest,
string sessionId)
{
- throw new NotImplementedException();
+ var output = _eventOutputHolder.GetOutput(sessionId);
+
+ var traderOffer = GetTraderClothingOffer(sessionId, buyClothingRequest.Offer);
+ if (traderOffer == null)
+ {
+ _logger.Error(_localisationService.GetText("customisation-unable_to_find_suit_by_id", buyClothingRequest.Offer));
+ return output;
+ }
+
+ var suitId = traderOffer.SuiteId;
+ if (OutfitAlreadyPurchased(suitId, sessionId))
+ {
+ var suitDetails = _databaseService.GetCustomization()[suitId];
+ _logger.Error(_localisationService.GetText("customisation-item_already_purchased", new
+ {
+ ItemId = suitDetails.Id,
+ ItemName = suitDetails.Name,
+ }));
+ }
+
+ return output;
+ }
+
+ private bool OutfitAlreadyPurchased(object suitId, string sessionId)
+ {
+ return _saveServer.GetProfile(sessionId).Suits.Contains(suitId);
+ }
+
+ private Suit GetTraderClothingOffer(string sessionId, string? offerId)
+ {
+ var foundSuit = GetAllTraderSuits(sessionId).FirstOrDefault(s => s.Id == offerId);
+ if (foundSuit == null)
+ throw new Exception(_localisationService.GetText("customisation-unable_to_find_suit_with_id", offerId));
+
+ return foundSuit;
}
///
@@ -45,13 +125,13 @@ public class CustomizationController
/// Player profile
/// Clothing purchased
/// Client response
- private void PayForClothingItems(
- string sessionId,
- PmcData pmcData,
- List itemsToPayForClothingWith,
+ private void PayForClothingItems(string sessionId, PmcData pmcData, List itemsToPayForClothingWith,
ItemEventRouterResponse output)
{
- throw new NotImplementedException();
+ foreach (var inventoryItemToProcess in itemsToPayForClothingWith)
+ {
+ PayForClothingItem(sessionId, pmcData, inventoryItemToProcess, output);
+ }
}
///
@@ -61,13 +141,65 @@ public class CustomizationController
/// Player profile
/// Payment details
/// Client response
- private void PayForClothingItem(
- string sessionId,
- PmcData pmcData,
- PaymentItemForClothing paymentItemDetails,
- ItemEventRouterResponse output)
+ private void PayForClothingItem(string sessionId, PmcData pmcData, PaymentItemForClothing paymentItemDetails, ItemEventRouterResponse output)
{
- throw new NotImplementedException();
+ var inventoryItem = pmcData.Inventory.Items.FirstOrDefault(x => x.Id == paymentItemDetails.Id);
+ if (inventoryItem == null)
+ {
+ _logger.Error(_localisationService.GetText("customisation-unable_to_find_clothing_item_in_inventory", paymentItemDetails.Id));
+ return;
+ }
+
+ if (paymentItemDetails.Del != null)
+ {
+ output.ProfileChanges[sessionId].Items.DeletedItems.Add(new Product
+ {
+ Id = inventoryItem.Id,
+ Template = inventoryItem.Template,
+ ParentId = inventoryItem.ParentId,
+ SlotId = inventoryItem.SlotId,
+ Location = (ItemLocation)inventoryItem.Location,
+ Upd = inventoryItem.Upd
+ });
+
+ pmcData.Inventory.Items.Remove(inventoryItem);
+ }
+
+ if (inventoryItem.Upd == null)
+ inventoryItem.Upd = new() { StackObjectsCount = 1 };
+
+ if (inventoryItem.Upd.StackObjectsCount == null)
+ inventoryItem.Upd.StackObjectsCount = 1;
+
+ if (inventoryItem.Upd.StackObjectsCount == paymentItemDetails.Count)
+ {
+ output.ProfileChanges[sessionId].Items.DeletedItems.Add(new Product
+ {
+ Id = inventoryItem.Id,
+ Template = inventoryItem.Template,
+ ParentId = inventoryItem.ParentId,
+ SlotId = inventoryItem.SlotId,
+ Location = (ItemLocation)inventoryItem.Location,
+ Upd = inventoryItem.Upd
+ });
+
+ pmcData.Inventory.Items.Remove(inventoryItem);
+ return;
+ }
+
+ if (inventoryItem.Upd.StackObjectsCount > paymentItemDetails.Count)
+ {
+ inventoryItem.Upd.StackObjectsCount -= paymentItemDetails.Count;
+ output.ProfileChanges[sessionId].Items.ChangedItems.Add(new Product
+ {
+ Id = inventoryItem.Id,
+ Template = inventoryItem.Template,
+ ParentId = inventoryItem.ParentId,
+ SlotId = inventoryItem.SlotId,
+ Location = (ItemLocation)inventoryItem.Location,
+ Upd = inventoryItem.Upd
+ });
+ }
}
///
@@ -77,7 +209,16 @@ public class CustomizationController
///
private List GetAllTraderSuits(string sessionId)
{
- throw new NotImplementedException();
+ var traders = _databaseService.GetTraders();
+ var result = new List();
+
+ foreach (var trader in traders)
+ {
+ if (trader.Value.Base.CustomizationSeller.Value)
+ result.AddRange(GetTraderSuits(trader.Key, sessionId));
+ }
+
+ return result;
}
///
@@ -86,11 +227,9 @@ public class CustomizationController
///
///
///
- public HideoutCustomisation GetHideoutCustomisation(
- string sessionId,
- EmptyRequestData info)
+ public HideoutCustomisation GetHideoutCustomisation(string sessionId, EmptyRequestData info)
{
- throw new NotImplementedException();
+ return _databaseService.GetHideout().Customisation;
}
///
@@ -103,7 +242,79 @@ public class CustomizationController
string sessionId,
EmptyRequestData info)
{
- throw new NotImplementedException();
+ var customisationResultsClone = _cloner.Clone(_databaseService.GetTemplates().CustomisationStorage);
+
+ var profile = _profileHelper.GetFullProfile(sessionId);
+ switch (GetGameEdition(profile))
+ {
+ case GameEditions.EDGE_OF_DARKNESS:
+ customisationResultsClone.Add(new ()
+ {
+ Id = "6746fd09bafff85008048838",
+ Source = "default",
+ Type = "dogTag"
+ });
+ customisationResultsClone.Add(new ()
+ {
+ Id = "67471938bafff850080488b7",
+ Source = "default",
+ Type = "dogTag"
+ });
+ break;
+ case GameEditions.UNHEARD:
+ customisationResultsClone.Add(new ()
+ {
+ Id = "6746fd09bafff85008048838",
+ Source = "default",
+ Type = "dogTag"
+ });
+ customisationResultsClone.Add(new ()
+ {
+ Id = "67471938bafff850080488b7",
+ Source = "default",
+ Type = "dogTag"
+ });
+ customisationResultsClone.Add(new ()
+ {
+ Id = "67471928d17d6431550563b5",
+ Source = "default",
+ Type = "dogTag"
+ });
+ customisationResultsClone.Add(new ()
+ {
+ Id = "6747193f170146228c0d2226",
+ Source = "default",
+ Type = "dogTag"
+ });
+ break;
+ default:
+ throw new Exception($"Unknown game edition given from profile {profile}");
+ }
+
+ var prestigeLevel = profile.CharacterData.PmcData.Info.PrestigeLevel;
+ if (prestigeLevel != null)
+ {
+ if (prestigeLevel >= 1)
+ {
+ customisationResultsClone.Add(new ()
+ {
+ Id = "674dbf593bee1152d407f005",
+ Source = "default",
+ Type = "dogTag"
+ });
+ }
+ if (prestigeLevel >= 2)
+ {
+ customisationResultsClone.Add(new ()
+ {
+ Id = "675dcfea7ae1a8792107ca99",
+ Source = "default",
+ Type = "dogTag"
+ });
+ }
+ }
+
+ return customisationResultsClone;
}
///
@@ -113,7 +324,22 @@ public class CustomizationController
///
private string GetGameEdition(SptProfile profile)
{
- throw new NotImplementedException();
+ var edition = profile.CharacterData.PmcData.Info.GameVersion;
+ if (edition == null)
+ {
+ var launcherEdition = profile.ProfileInfo.Edition;
+ switch (launcherEdition.ToLower())
+ {
+ case "edge of darkness":
+ return GameEditions.EDGE_OF_DARKNESS;
+ case "unheard":
+ return GameEditions.UNHEARD;
+ default:
+ return GameEditions.STANDARD;
+ }
+ }
+
+ return edition;
}
///
@@ -123,12 +349,25 @@ public class CustomizationController
///
///
///
- public ItemEventRouterResponse SetClothing(
- string sessionId,
- CustomizationSetRequest request,
- PmcData pmcData)
+ public ItemEventRouterResponse SetClothing(string sessionId, CustomizationSetRequest request, PmcData pmcData)
{
- throw new NotImplementedException();
+ foreach (var customisation in request.Customizations)
+ {
+ switch (customisation.Id)
+ {
+ case "dogTag":
+ pmcData.Customization.DogTag = customisation.Id;
+ break;
+ case "suite":
+ ApplyClothingItemToProfile(customisation, pmcData);
+ break;
+ default:
+ _logger.Error($"Unhandled customisation type: {customisation.Type}");
+ break;
+ }
+ }
+
+ return _eventOutputHolder.GetOutput(sessionId);
}
///
@@ -136,10 +375,26 @@ public class CustomizationController
///
/// Suit to apply to profile
/// Profile to update
- private void ApplyClothingItemToProfile(
- CustomizationSetOption customization,
- PmcData pmcData)
+ private void ApplyClothingItemToProfile(CustomizationSetOption customisation, PmcData pmcData)
{
- throw new NotImplementedException();
+ var dbSuit = _databaseService.GetCustomization()[customisation.Id];
+ if (dbSuit == null)
+ {
+ _logger.Error($"Unable to find suit customisation id: {customisation.Id}, cannot apply clothing to player profile: {pmcData.Id}");
+ return;
+ }
+
+ if (dbSuit.Parent == "5cd944d01388ce000a659df9")
+ {
+ pmcData.Customization.Body = dbSuit.Properties.Body;
+ pmcData.Customization.Hands = dbSuit.Properties.Hands;
+
+ return;
+ }
+
+ if (dbSuit.Parent == "5cd944ca1388ce03a44dc2a4")
+ {
+ pmcData.Customization.Feet = dbSuit.Properties.Feet;
+ }
}
}