using System.Text.RegularExpressions; using SPTarkov.DI.Annotations; using SPTarkov.Server.Core.Models.Eft.Common; using SPTarkov.Server.Core.Models.Eft.Common.Tables; using SPTarkov.Server.Core.Models.Eft.Inventory; using SPTarkov.Server.Core.Models.Utils; namespace SPTarkov.Server.Core.Services; [Injectable] public class MapMarkerService(ISptLogger logger) { /// /// Add note to a map item in player inventory /// /// Player profile /// Add marker request /// Item public Item? CreateMarkerOnMap(PmcData pmcData, InventoryCreateMarkerRequestData request) { // Get map from inventory var mapItem = pmcData?.Inventory?.Items?.FirstOrDefault(i => i?.Id == request?.Item); if (mapItem is null) { return null; } // add marker to map item mapItem.Upd.Map = mapItem?.Upd?.Map ?? new UpdMap { Markers = [] }; // Update request note with text, then add to maps upd request.MapMarker.Note = SanitiseMapMarkerText(request.MapMarker.Note); mapItem?.Upd?.Map?.Markers?.Add(request.MapMarker); return mapItem; } /// /// Delete a map marker /// /// Player profile /// Delete marker request /// Item public Item DeleteMarkerFromMap(PmcData pmcData, InventoryDeleteMarkerRequestData request) { // Get map from inventory var mapItem = pmcData.Inventory.Items.FirstOrDefault(item => item.Id == request.Item); // remove marker var markers = mapItem.Upd.Map.Markers.Where(marker => marker.X != request.X && marker.Y != request.Y).ToList(); mapItem.Upd.Map.Markers = markers; return mapItem; } /// /// Edit an existing map marker /// /// Player profile /// Edit marker request /// Item public Item? EditMarkerOnMap(PmcData pmcData, InventoryEditMarkerRequestData request) { // Get map from inventory var mapItem = pmcData.Inventory.Items.FirstOrDefault(item => item.Id == request.Item); // edit marker // the only thing that is consistent between the old and edit is the X and Y // find the marker where X and Y match var markerToRemove = mapItem.Upd.Map.Markers.FirstOrDefault(x => x.X == request.X && x.Y == request.Y); if (markerToRemove is null) { logger.Warning($"No marker found for item {request.Item}"); return null; } request.MapMarker.Note = SanitiseMapMarkerText(request.MapMarker.Note); mapItem.Upd.Map.Markers.Remove(markerToRemove); mapItem.Upd.Map.Markers.Add(request.MapMarker); return mapItem; } /// /// Strip out characters from note string that are not: letter/numbers/unicode/spaces /// /// Marker text to sanitise /// Sanitised map marker text protected string SanitiseMapMarkerText(string mapNoteText) { return Regex.Replace(mapNoteText, @"[^\p{L}\d\s]", "", RegexOptions.CultureInvariant); } }