From 9db7ff25d1ac4b44d02a39e7c2040cb2de52684b Mon Sep 17 00:00:00 2001 From: Cj <161484149+CJ-SPT@users.noreply.github.com> Date: Tue, 8 Jul 2025 13:30:23 -0400 Subject: [PATCH] Implement websocket stash row change notification (#462) * implement stash rows notification * rename class --- .../Commands/GiveMeSpaceMessageHandler.cs | 46 +++++++++++-------- .../Helpers/ProfileHelper.cs | 17 +++++-- .../Helpers/RewardHelper.cs | 16 ++++++- .../Models/Eft/Ws/WsProfileChangeEvent.cs | 9 ++++ 4 files changed, 64 insertions(+), 24 deletions(-) create mode 100644 Libraries/SPTarkov.Server.Core/Models/Eft/Ws/WsProfileChangeEvent.cs diff --git a/Libraries/SPTarkov.Server.Core/Helpers/Dialogue/SPTFriend/Commands/GiveMeSpaceMessageHandler.cs b/Libraries/SPTarkov.Server.Core/Helpers/Dialogue/SPTFriend/Commands/GiveMeSpaceMessageHandler.cs index 95a17d64..01a8f678 100644 --- a/Libraries/SPTarkov.Server.Core/Helpers/Dialogue/SPTFriend/Commands/GiveMeSpaceMessageHandler.cs +++ b/Libraries/SPTarkov.Server.Core/Helpers/Dialogue/SPTFriend/Commands/GiveMeSpaceMessageHandler.cs @@ -1,6 +1,8 @@ using SPTarkov.DI.Annotations; +using SPTarkov.Server.Core.Models.Common; using SPTarkov.Server.Core.Models.Eft.Common; using SPTarkov.Server.Core.Models.Eft.Profile; +using SPTarkov.Server.Core.Models.Eft.Ws; using SPTarkov.Server.Core.Models.Spt.Config; using SPTarkov.Server.Core.Servers; using SPTarkov.Server.Core.Services; @@ -10,14 +12,15 @@ namespace SPTarkov.Server.Core.Helpers.Dialogue.SPTFriend.Commands; [Injectable] public class GiveMeSpaceMessageHandler( - ProfileHelper _profileHelper, - ServerLocalisationService _serverLocalisationService, - MailSendService _mailSendService, - RandomUtil _randomUtil, - ConfigServer _configServer + ProfileHelper profileHelper, + NotificationSendHelper notificationSendHelper, + ServerLocalisationService serverLocalisationService, + MailSendService mailSendService, + RandomUtil randomUtil, + ConfigServer configServer ) : IChatMessageHandler { - private readonly CoreConfig _coreConfig = _configServer.GetConfig(); + private readonly CoreConfig _coreConfig = configServer.GetConfig(); public int GetPriority() { @@ -40,40 +43,47 @@ public class GiveMeSpaceMessageHandler( var maxGiftsToSendCount = _coreConfig.Features.ChatbotFeatures.CommandUseLimits[stashRowGiftId] ?? 5; if ( - _profileHelper.PlayerHasReceivedMaxNumberOfGift( + profileHelper.PlayerHasReceivedMaxNumberOfGift( sessionId, stashRowGiftId, maxGiftsToSendCount ) ) { - _mailSendService.SendUserMessageToPlayer( + mailSendService.SendUserMessageToPlayer( sessionId, sptFriendUser, - _serverLocalisationService.GetText("chatbot-cannot_accept_any_more_of_gift"), + serverLocalisationService.GetText("chatbot-cannot_accept_any_more_of_gift"), [], null ); } else { - _profileHelper.AddStashRowsBonusToProfile(sessionId, 2); + const int rowsToAdd = 2; + var bonusId = profileHelper.AddStashRowsBonusToProfile(sessionId, rowsToAdd); - _mailSendService.SendUserMessageToPlayer( + notificationSendHelper.SendMessage( + sessionId, + new WsProfileChangeEvent + { + EventIdentifier = new MongoId(), + EventType = NotificationEventType.StashRows, + Changes = new Dictionary { { bonusId, rowsToAdd } }, + } + ); + + mailSendService.SendUserMessageToPlayer( sessionId, sptFriendUser, - _randomUtil.GetArrayValue( - [_serverLocalisationService.GetText("chatbot-added_stash_rows_please_restart")] + randomUtil.GetArrayValue( + [serverLocalisationService.GetText("chatbot-added_stash_rows_please_restart")] ), [], null ); - _profileHelper.FlagGiftReceivedInProfile( - sessionId, - stashRowGiftId, - maxGiftsToSendCount - ); + profileHelper.FlagGiftReceivedInProfile(sessionId, stashRowGiftId, maxGiftsToSendCount); } } } diff --git a/Libraries/SPTarkov.Server.Core/Helpers/ProfileHelper.cs b/Libraries/SPTarkov.Server.Core/Helpers/ProfileHelper.cs index 3509a3d2..0a4243b9 100644 --- a/Libraries/SPTarkov.Server.Core/Helpers/ProfileHelper.cs +++ b/Libraries/SPTarkov.Server.Core/Helpers/ProfileHelper.cs @@ -569,21 +569,26 @@ public class ProfileHelper( /// /// Profile id to give rows to /// How many rows to give profile - public void AddStashRowsBonusToProfile(MongoId sessionId, int rowsToAdd) + /// The stash rows bonus id, this is needed for ws notification if we send one + public MongoId? AddStashRowsBonusToProfile(MongoId sessionId, int rowsToAdd) { var profile = GetPmcProfile(sessionId); if (profile?.Bonuses is null) { // Something is very wrong with profile to lack bonuses array, likely broken profile, exit early - return; + return null; } - var existingBonus = profile?.Bonuses.FirstOrDefault(b => b.Type == BonusType.StashRows); + + var existingBonus = profile.Bonuses.FirstOrDefault(b => b.Type == BonusType.StashRows); + + var bonusId = existingBonus?.Id; if (existingBonus is null) { - profile!.Bonuses.Add( + bonusId = new MongoId(); + profile.Bonuses.Add( new Bonus { - Id = new MongoId(), + Id = bonusId.Value, Value = rowsToAdd, Type = BonusType.StashRows, IsPassive = true, @@ -596,6 +601,8 @@ public class ProfileHelper( { existingBonus.Value += rowsToAdd; } + + return bonusId!.Value; } public bool HasAccessToRepeatableFreeRefreshSystem(PmcData pmcProfile) diff --git a/Libraries/SPTarkov.Server.Core/Helpers/RewardHelper.cs b/Libraries/SPTarkov.Server.Core/Helpers/RewardHelper.cs index df9c19cb..1359961f 100644 --- a/Libraries/SPTarkov.Server.Core/Helpers/RewardHelper.cs +++ b/Libraries/SPTarkov.Server.Core/Helpers/RewardHelper.cs @@ -107,7 +107,21 @@ public class RewardHelper( AddAchievementToProfile(fullProfile, reward.Target); break; case RewardType.StashRows: - profileHelper.AddStashRowsBonusToProfile(sessionId.Value, (int)reward.Value); // Add specified stash rows from reward - requires client restart + var bonusId = profileHelper.AddStashRowsBonusToProfile( + sessionId.Value, + (int)reward.Value + ); // Add specified stash rows from reward - requires client restart + + notificationSendHelper.SendMessage( + sessionId.Value, + new WsProfileChangeEvent + { + EventIdentifier = new MongoId(), + EventType = NotificationEventType.StashRows, + Changes = new Dictionary { { bonusId, reward.Value } }, + } + ); + break; case RewardType.ProductionScheme: FindAndAddHideoutProductionIdToProfile( diff --git a/Libraries/SPTarkov.Server.Core/Models/Eft/Ws/WsProfileChangeEvent.cs b/Libraries/SPTarkov.Server.Core/Models/Eft/Ws/WsProfileChangeEvent.cs new file mode 100644 index 00000000..1da38edd --- /dev/null +++ b/Libraries/SPTarkov.Server.Core/Models/Eft/Ws/WsProfileChangeEvent.cs @@ -0,0 +1,9 @@ +using System.Text.Json.Serialization; + +namespace SPTarkov.Server.Core.Models.Eft.Ws; + +public record WsProfileChangeEvent : WsNotificationEvent +{ + [JsonPropertyName("Changes")] + public Dictionary Changes { get; set; } +}