using System.Text.Json; using Prospect.Server.Api.Services.Auth.Extensions; using Prospect.Server.Api.Services.CloudScript.Models; using Prospect.Server.Api.Services.CloudScript.Models.Data; using Prospect.Server.Api.Services.UserData; namespace Prospect.Server.Api.Services.CloudScript.Functions; [CloudScriptFunction("UpdateRetentionBonus")] public class UpdateRetentionBonus : ICloudScriptFunction { private readonly IHttpContextAccessor _httpContextAccessor; private readonly UserDataService _userDataService; private readonly TitleDataService _titleDataService; public UpdateRetentionBonus(IHttpContextAccessor httpContextAccessor, UserDataService userDataService, TitleDataService titleDataService) { _httpContextAccessor = httpContextAccessor; _userDataService = userDataService; _titleDataService = titleDataService; } public async Task ExecuteAsync(FYRetentionBonusRequest request) { var context = _httpContextAccessor.HttpContext; if (context == null) { throw new CloudScriptException("CloudScript was not called within a http request"); } var userId = context.User.FindAuthUserId(); var userData = await _userDataService.FindAsync( userId, userId, new List{"RetentionBonus", "Inventory"} ); var retentionBonus = JsonSerializer.Deserialize(userData["RetentionBonus"].Value); if (retentionBonus.ClaimedAll) { return new FYRetentionBonusResult { UserId = userId, Error = "", PlayerData = retentionBonus, }; } var now = (int)DateTimeOffset.UtcNow.ToUnixTimeSeconds(); var nextClaimTime = retentionBonus.LastClaimTime.Seconds + 60 * 60 * 24 * 2; if (now < nextClaimTime) { return new FYRetentionBonusResult { UserId = userId, Error = "", PlayerData = retentionBonus, }; } var titleData = _titleDataService.Find(new List{"Blueprints", "RetentionBonusData"}); var bonusData = JsonSerializer.Deserialize>(titleData["RetentionBonusData"]); retentionBonus.DaysClaimed++; retentionBonus.LastClaimTime.Seconds = now; retentionBonus.ClaimedAll = retentionBonus.DaysClaimed >= 14; // TODO: Currently only CB2 bonuses are considered var bonuses = bonusData["CB2"]; var inventory = JsonSerializer.Deserialize>(userData["Inventory"].Value); var rewardItemID = bonuses.Rewards[retentionBonus.DaysClaimed - 1]; if (rewardItemID != "None") { var blueprints = JsonSerializer.Deserialize>(titleData["Blueprints"]); var itemInfo = blueprints[rewardItemID]; inventory.Add(new FYCustomItemInfo{ ItemId = Guid.NewGuid().ToString(), Amount = 1, BaseItemId = rewardItemID, Durability = itemInfo.DurabilityMax, Insurance = "", InsuranceOwnerPlayfabId = "", ModData = new FYModItems { M = [] }, Origin = new FYItemOriginBackend { G = "", P = "", T = "" }, InsuredAttachmentId = "", PrimaryVanityId = 0, SecondaryVanityId = 0, RolledPerks = [], }); } await _userDataService.UpdateAsync( userId, userId, new Dictionary{ ["RetentionBonus"] = JsonSerializer.Serialize(retentionBonus), ["Inventory"] = JsonSerializer.Serialize(inventory), } ); // TODO: This request does not update inventory items. Maybe a SignalR event must be sent? return new FYRetentionBonusResult { UserId = userId, Error = "", PlayerData = retentionBonus, }; } }