Push changes

This commit is contained in:
Yury
2025-02-24 01:06:32 +02:00
parent 1bfb16539f
commit 280b87314c
126 changed files with 5935 additions and 1265 deletions
@@ -1,17 +1,49 @@
using Prospect.Server.Api.Models.Client.Data;
using System.Text.Json;
using System.Text.Json.Serialization;
using Prospect.Server.Api.Models.Client.Data;
using Prospect.Server.Api.Services.Database;
namespace Prospect.Server.Api.Services.UserData;
public class UserTechTreeNodeData {
[JsonPropertyName("nodeInProgress")]
public string NodeInProgress { get; set; }
[JsonPropertyName("totalUpgrades")]
public int TotalUpgrades { get; set; }
[JsonPropertyName("nodes")]
public Dictionary<string, FYTechTreeNodeStatus> Nodes { get; set; }
}
public class CharacterTechTreeBonuses {
[JsonPropertyName("aurumCap")]
public int AurumCap { get; set; }
[JsonPropertyName("aurumRate")]
public float AurumRate { get; set; }
[JsonPropertyName("kmarksCap")]
public int KmarksCap { get; set; }
[JsonPropertyName("kmarksRate")]
public int KmarksRate { get; set; }
[JsonPropertyName("crateTier")]
public int CrateTier { get; set; }
[JsonPropertyName("addStashSize")]
public int AddStashSize { get; set; }
[JsonPropertyName("addSafePocketSize")]
public int AddSafePocketSize { get; set; }
[JsonPropertyName("upgradeSpeedFactor")]
public float UpgradeSpeedFactor { get; set; }
}
public class UserDataService
{
private readonly ILogger<UserDataService> _logger;
private readonly DbUserDataService _dbUserDataService;
private readonly TitleDataService _titleDataService;
public UserDataService(ILogger<UserDataService> logger, DbUserDataService dbUserDataService)
public UserDataService(ILogger<UserDataService> logger, DbUserDataService dbUserDataService, TitleDataService titleDataService)
{
_logger = logger;
_dbUserDataService = dbUserDataService;
_titleDataService = titleDataService;
}
/// <summary>
@@ -19,15 +51,82 @@ public class UserDataService
/// </summary>
public async Task InitAsync(string playFabId)
{
// TODO: Do not call this on each InitAsync
var titleData = _titleDataService.Find(new List<string>{"TechTreeNodes", "Blueprints"});
var techTreeNodes = JsonSerializer.Deserialize<Dictionary<string, TitleDataTechTreeNodeInfo>>(titleData["TechTreeNodes"]);
UserTechTreeNodeData userTechTreeNodesData = new UserTechTreeNodeData {
NodeInProgress = "",
TotalUpgrades = 0,
Nodes = [],
};
foreach (var nodeData in techTreeNodes) {
userTechTreeNodesData.Nodes[nodeData.Key] = new FYTechTreeNodeStatus {
NodeID = nodeData.Key,
Level = 0,
UpgradeStartedTime = new CloudScript.Models.Data.FYTimestamp {
Seconds = 0,
}
};
}
// TODO: Proper objects.
var defaultData = new Dictionary<string, (bool isPublic, string value)>
{
["Generators__2021_09_09"] = (true, "[{\"generatorId\":\"playerquarters_gen_aurum\",\"lastClaimTime\":{\"seconds\":0}},{\"generatorId\":\"playerquarters_gen_kmarks\",\"lastClaimTime\":{\"seconds\":0}},{\"generatorId\":\"playerquarters_gen_crate\",\"lastClaimTime\":{\"seconds\":0}}]"),
["InventoryInfo"] = (true, "{\"inventoryStashLimit\":75,\"inventoryBagLimit\":300,\"inventorySafeLimit\":5}"),
["LOADOUT"] = (true, $"{{\"id\":\"\",\"userId\":\"{playFabId}\",\"kit\":\"\",\"shield\":\"\",\"helmet\":\"\",\"weaponOne\":\"\",\"weaponTwo\":\"\",\"bag\":null,\"bagItemsAsJsonStr\":\"\",\"safeItemsAsJsonStr\":\"\"}}"),
["OnboardingProgression"] = (true, "{\"currentMissionID\":\"TalkToBadum\",\"progress\":0,\"showPopup\":true}"),
["PickaxeUpgradeLevel"] = (true, "0"),
["PlayerQuartersLevel"] = (true, "{\"level\":1,\"upgradeStartedTime\":{\"seconds\":0}}"),
// GET /Client/GetUserData & GET /Client/GetUserReadOnlyData
// TODO: Contracts and factions progression
["FactionProgressionKorolev"] = (false, "0"),
["FactionProgressionICA"] = (false, "0"),
["FactionProgressionOsiris"] = (false, "0"),
["ContractsActive"] = (false, $"{{\"userId\":\"{playFabId}\",\"error\":\"\",\"contracts\":[]}}"),
["ContractsOneTimeCompleted"] = (false, "{\"contractsIds\":[]}"),
["OnboardingProgression"] = (false, $"{{\"userId\":\"{playFabId}\",\"currentMissionID\":\"TalkToBadum\",\"progress\":0,\"showPopup\":true}}"),
// TODO: Notifications
["Notifications"] = (false, "{\"notifications\":[]}"), // FYNotificationDescription?
["Notifications_Account"] = (false, "{\"notifications\":[]}"), // FYNotificationDescription?
// TODO: Fortuna Pass Season 2
["FortunaPass2_DailyCompletedActions"] = (false, "{\"actions\":{},\"lastDailyCapResetTimeUtc\":{\"seconds\":0}}"),
["FortunaPass2_ClaimedRewards"] = (false, "{\"rewardsIds\":[]}"),
["FortunaPass2_PremiumUnlock"] = (false, "false"),
["FortunaPass2_SeasonXp"] = (false, "0"),
// TODO: Fortuna Pass Season 3
["FortunaPass3_DailyCompletedActions"] = (false, "{\"actions\":{},\"lastDailyCapResetTimeUtc\":{\"seconds\":0}}"),
["FortunaPass3_ClaimedRewards"] = (false, "{\"rewardsIds\":[]}"),
["FortunaPass3_PremiumUnlock"] = (false, "false"),
["FortunaPass3_SeasonXp"] = (false, "0"),
// TODO: Quarters
["TechTreeNodeData"] = (false, JsonSerializer.Serialize(userTechTreeNodesData)),
["CraftingTimer__2022_05_12"] = (false, "{\"itemId\":\"\",\"utcTimestampWhenCraftingStarted\":{\"seconds\":0}}"),
["Generators__2021_09_09"] = (false, "[{\"generatorId\":\"playerquarters_gen_aurum\",\"lastClaimTime\":{\"seconds\":0}},{\"generatorId\":\"playerquarters_gen_kmarks\",\"lastClaimTime\":{\"seconds\":0}},{\"generatorId\":\"playerquarters_gen_crate\",\"lastClaimTime\":{\"seconds\":0}}]"),
["ClaimableStarterPacks"] = (false, "{\"packages\":[]}"), // FYClaimableStarterPackPackageResult?
["ClaimableVictimCompensations"] = (false, "{\"packages\":[]}"), // FYBackendClaimableVictimCompensationWrapper?
["PlayerQuartersLevel"] = (false, "{\"level\":1,\"upgradeStartedTime\":{\"seconds\":0}}"),
["TwitchDropRewards"] = (false, "{\"grantedItems\":[]}"), // FYInventoryItem
["InsuranceInvoice"] = (false, "{}"),
["InsuranceClaims"] = (false, "{\"packages\":[]}"), // FYBackendInsurancePayoutPackage. Limited to 20.
// TODO: Player data
["LOADOUT"] = (false, $"{{\"shield\":\"\",\"helmet\":\"\",\"weaponOne\":\"\",\"weaponTwo\":\"\",\"bag\":\"\",\"bagItemsAsJsonStr\":\"\",\"safeItemsAsJsonStr\":\"\"}}"),
["SessionData"] = (false, "{}"),
["SeasonWipe"] = (false, "{}"),
["VeteranPoints"] = (false, "{}"),
["FreeLoadout"] = (false, "{}"), // Season 3
// Function-specific data
// Used to optimize bonuses calculation and further validations without getting the user data and computing bonuses in runtime.
["CharacterTechTreeBonuses"] = (false, "{\"aurumCap\":0,\"aurumRate\":0,\"kmarksCap\":0,\"kmarksRate\":0,\"crateTier\":0,\"stashSize\":0,\"safePocketSize\":0,\"upgradeSpeed\":1.0}"),
["GlobalVanity"] = (false, $"{{\"activeGlobalVanityIds\":[\"Season03_Spray_13\",\"Banner_MIne\",\"Emote_Chill_01\",\"\",\"\",\"\",\"\",\"\"], \"droppodId\": \"VDP_Omega02\"}}"),
// NOTE: Default CharacterVanity is based on Season 2 IDs.
["CharacterVanity"] = (false, $"{{\"userId\":\"{playFabId}\",\"head_item\":{{\"id\":\"E01_G02_Head01\",\"materialIndex\":0}},\"boots_item\":{{\"id\":\"StarterOutfit01_Boots_M\",\"materialIndex\":0}},\"chest_item\":{{\"id\":\"StarterOutfit01_Chest_M\",\"materialIndex\":0}},\"glove_item\":{{\"id\":\"StarterOutfit01_Gloves_M\",\"materialIndex\":0}},\"base_suit_item\":{{\"id\":\"StarterOutfit01M_BaseSuit\",\"materialIndex\":0}},\"melee_weapon_item\":{{\"id\":\"Melee_Omega\",\"materialIndex\":0}},\"body_type\":1,\"archetype_id\":\"E01_G02\",\"slot_index\":0}}"),
// ["Inventory"] = (false, "[]"),
["Inventory"] = (false, "[]"),
["VanityItems"] = (false, "[]"),
["RetentionBonus"] = (false, "{\"claimedAll\":false,\"daysClaimed\":0,\"lastClaimTime\":{\"seconds\":0}}"),
["Balance"] = (false, "{\"IN\": 0,\"AU\": 800,\"SC\": 30000}"),
};
foreach (var (key, (isPublic, value)) in defaultData)
@@ -40,7 +139,7 @@ public class UserDataService
}
/// <summary>
///
///
/// </summary>
/// <param name="currentUserId">
/// The authenticated user id.
@@ -51,23 +150,26 @@ public class UserDataService
/// <param name="keys"></param>
/// <returns></returns>
public async Task<Dictionary<string, FUserDataRecord>> FindAsync(
string currentUserId,
string requestUserId,
string currentUserId,
string requestUserId,
List<string> keys)
{
if (string.IsNullOrEmpty(currentUserId))
{
throw new ArgumentNullException(nameof(currentUserId));
}
if (requestUserId == null)
{
requestUserId = currentUserId;
}
var other = currentUserId != requestUserId;
if (other) {
Console.WriteLine("aboba");
}
var result = new Dictionary<string, FUserDataRecord>();
if (keys != null && keys.Count > 0)
{
foreach (var key in keys)
@@ -84,17 +186,19 @@ public class UserDataService
// TODO: Error?
continue;
}
result.Add(data.Key, new FUserDataRecord
{
LastUpdated = data.LastUpdated,
Permission = data.Public ? UserDataPermission.Public : UserDataPermission.Private,
Value = data.Value
});
}
}
}
else
{
// TODO: Getting ALL user data seems to be required only for fetching the player's passive generators data.
// This is not OK and normally should not be allowed.
var cursor = await _dbUserDataService.AllAsync(requestUserId, other);
while (await cursor.MoveNextAsync())
@@ -115,7 +219,7 @@ public class UserDataService
}
/// <summary>
///
///
/// </summary>
/// <param name="currentUserId">
/// The authenticated user id.
@@ -126,20 +230,20 @@ public class UserDataService
/// <param name="changes"></param>
/// <returns></returns>
public async Task UpdateAsync(
string currentUserId,
string? targetUserId,
string currentUserId,
string? targetUserId,
Dictionary<string, string> changes)
{
if (changes.Count == 0)
{
return;
}
if (string.IsNullOrEmpty(currentUserId))
{
throw new ArgumentNullException(nameof(currentUserId));
}
if (targetUserId == null)
{
targetUserId = currentUserId;
@@ -147,7 +251,7 @@ public class UserDataService
// Whether we are updating someone else.
var other = currentUserId != targetUserId;
foreach (var (key, value) in changes)
{
var data = await _dbUserDataService.FindAsync(currentUserId, key);
@@ -162,16 +266,16 @@ public class UserDataService
_logger.LogDebug("User {PlayFabId} created key {Key}", currentUserId, key);
await _dbUserDataService.InsertAsync(currentUserId, key, value, false);
}
continue;
}
if (!data.Public && other)
{
_logger.LogWarning("User {PlayFabId} attempted to update non-public key {Key} of another user {PlayFabIdOther}", currentUserId, key, data.PlayFabId);
continue;
}
await _dbUserDataService.UpdateValueAsync(data.Id, value);
}
}