using System.Text.Json; using System.Text.Json.Serialization; using Prospect.Server.Api.Models.Data; using Prospect.Server.Api.Services.Auth.Extensions; using Prospect.Server.Api.Services.UserData; namespace Prospect.Server.Api.Services.CloudScript.Functions; public class FYRequestMissionCompletedRequest { [JsonPropertyName("currentMissionId")] public string CurrentMissionID { get; set; } } public class FYRequestMissionCompletedResult { [JsonPropertyName("userId")] public string UserID { get; set; } [JsonPropertyName("currentMissionId")] public string CurrentMissionID { get; set; } [JsonPropertyName("rewards")] public List Rewards { get; set; } [JsonPropertyName("updatedCurrencies")] public FYCurrencyItem[] UpdatedCurrencies { get; set; } [JsonPropertyName("progress")] public int Progress { get; set; } } [CloudScriptFunction("RequestMissionCompleted")] public class RequestMissionCompleted : ICloudScriptFunction { private readonly IHttpContextAccessor _httpContextAccessor; private readonly UserDataService _userDataService; private readonly TitleDataService _titleDataService; public RequestMissionCompleted(IHttpContextAccessor httpContextAccessor, UserDataService userDataService, TitleDataService titleDataService) { _httpContextAccessor = httpContextAccessor; _userDataService = userDataService; _titleDataService = titleDataService; } public async Task ExecuteAsync(FYRequestMissionCompletedRequest 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{"OnboardingProgression", "Inventory", "Balance"}); var onboardingMission = JsonSerializer.Deserialize(userData["OnboardingProgression"].Value); var inventory = JsonSerializer.Deserialize>(userData["Inventory"].Value); var titleData = _titleDataService.Find(new List{"OnboardingMissions", "OnboardingRewardMissions", "Blueprints"}); var rewards = JsonSerializer.Deserialize>(titleData["OnboardingRewardMissions"]); var blueprints = JsonSerializer.Deserialize>(titleData["Blueprints"]); var missions = JsonSerializer.Deserialize>(titleData["OnboardingMissions"]); var balance = JsonSerializer.Deserialize(userData["Balance"].Value); var currentMission = missions[onboardingMission.CurrentMissionID]; var missionRewardId = currentMission.OnboardingRewards.RowName; var nextMissionId = currentMission.NextMissionRowHandle.RowName; onboardingMission.CurrentMissionID = nextMissionId; onboardingMission.Progress = 0; List rewardedItems = new List(); List changedCurrencies = []; if (rewards.ContainsKey(missionRewardId)) { var missionRewards = rewards[missionRewardId].RewardEntries; foreach (var reward in missionRewards) { if (reward.RewardRowHandle.RowName == "SoftCurrency") { balance.SoftCurrency += reward.RewardAmount; changedCurrencies.Add(new FYCurrencyItem { CurrencyName = "SoftCurrency", Amount = balance.SoftCurrency }); } else if (reward.RewardRowHandle.RowName == "Aurum") { balance.HardCurrency += reward.RewardAmount; changedCurrencies.Add(new FYCurrencyItem { CurrencyName = "Aurum", Amount = balance.HardCurrency }); } else if (reward.RewardRowHandle.RowName == "InsuranceCurrency") { balance.InsuranceCurrency += reward.RewardAmount; changedCurrencies.Add(new FYCurrencyItem { CurrencyName = "InsuranceCurrency", Amount = balance.InsuranceCurrency }); } else { // TODO: Inventory limit check var blueprintData = blueprints[reward.RewardRowHandle.RowName]; var remainingAmount = reward.RewardAmount * blueprintData.AmountPerPurchase; while (remainingAmount > 0) { var itemStackAmount = Math.Min(blueprintData.MaxAmountPerStack, remainingAmount); // TODO: Mission rewards are probably already given in stacks var itemInfo = new FYCustomItemInfo{ ItemId = Guid.NewGuid().ToString(), Amount = itemStackAmount, BaseItemId = reward.RewardRowHandle.RowName, Durability = blueprintData.DurabilityMax, Insurance = "", InsuranceOwnerPlayfabId = "", ModData = new FYModItems { M = [] }, Origin = new FYItemOriginBackend { G = "", P = "", T = "" }, InsuredAttachmentId = "", PrimaryVanityId = 0, SecondaryVanityId = 0, RolledPerks = [], }; inventory.Add(itemInfo); rewardedItems.Add(itemInfo); remainingAmount -= itemStackAmount; } } } } await _userDataService.UpdateAsync( userId, userId, new Dictionary{ ["OnboardingProgression"] = JsonSerializer.Serialize(onboardingMission), ["Inventory"] = JsonSerializer.Serialize(inventory), ["Balance"] = JsonSerializer.Serialize(balance), } ); return new FYRequestMissionCompletedResult { UserID = userId, CurrentMissionID = nextMissionId, Rewards = rewardedItems, UpdatedCurrencies = changedCurrencies.ToArray(), Progress = 0 }; } }