chore(game-server): merge main (emulator fixes: contracts, shop, fortuna, friends, admin, presence) #16
@@ -32,9 +32,8 @@ public class GetFriendList : ICloudScriptFunction<FYBaseSocialRequest, object?>
|
|||||||
}
|
}
|
||||||
var userId = context.User.FindAuthUserId();
|
var userId = context.User.FindAuthUserId();
|
||||||
|
|
||||||
// Resolve the imported Steam friends (persisted by ClientsideFriendsImport) to the
|
// Imported Steam friends (persisted by ClientsideFriendsImport), resolved to players
|
||||||
// players that actually exist on this server. It's a private server, so only friends
|
// that actually exist on this private server.
|
||||||
// who have logged in here will show up.
|
|
||||||
var steamIds = new List<string>();
|
var steamIds = new List<string>();
|
||||||
var userData = await _userDataService.FindAsync(userId, userId, new List<string> { "ImportedSteamFriends" });
|
var userData = await _userDataService.FindAsync(userId, userId, new List<string> { "ImportedSteamFriends" });
|
||||||
if (userData.TryGetValue("ImportedSteamFriends", out var rec) && !string.IsNullOrWhiteSpace(rec.Value))
|
if (userData.TryGetValue("ImportedSteamFriends", out var rec) && !string.IsNullOrWhiteSpace(rec.Value))
|
||||||
@@ -52,8 +51,10 @@ public class GetFriendList : ICloudScriptFunction<FYBaseSocialRequest, object?>
|
|||||||
{
|
{
|
||||||
if (player.Id == userId) continue; // never list yourself
|
if (player.Id == userId) continue; // never list yourself
|
||||||
|
|
||||||
// Presence persisted by UpdatePlayerPresenceState: online if seen in the last
|
var steamId = player.Auth?.FirstOrDefault(a => a.Type == PlayFabUserAuthType.Steam)?.Key ?? "";
|
||||||
// 3 minutes. EYUserState best-effort: 0 = offline, 1 = online, 2 = in match.
|
var displayName = string.IsNullOrWhiteSpace(player.DisplayName) ? "Prospector" : player.DisplayName;
|
||||||
|
|
||||||
|
// 0 = offline, 1 = online, 2 = in match. Online if seen in the last 3 minutes.
|
||||||
var onlineState = 0;
|
var onlineState = 0;
|
||||||
var presenceData = await _userDataService.FindAsync(player.Id, player.Id, new List<string> { "PresenceState" });
|
var presenceData = await _userDataService.FindAsync(player.Id, player.Id, new List<string> { "PresenceState" });
|
||||||
if (presenceData.TryGetValue("PresenceState", out var presenceRec) && !string.IsNullOrWhiteSpace(presenceRec.Value))
|
if (presenceData.TryGetValue("PresenceState", out var presenceRec) && !string.IsNullOrWhiteSpace(presenceRec.Value))
|
||||||
@@ -69,22 +70,50 @@ public class GetFriendList : ICloudScriptFunction<FYBaseSocialRequest, object?>
|
|||||||
catch { /* ignore malformed presence */ }
|
catch { /* ignore malformed presence */ }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// The exact model the UE client binds is not documented, so expose the identity
|
||||||
|
// under every plausible field name (camelCase + PlayFab PascalCase) and both a
|
||||||
|
// flat and nested profile — whichever the client reads, the tile gets populated.
|
||||||
friends.Add(new
|
friends.Add(new
|
||||||
{
|
{
|
||||||
profile = new
|
// identity
|
||||||
{
|
friendPlayFabId = player.Id,
|
||||||
|
FriendPlayFabId = player.Id,
|
||||||
playerId = player.Id,
|
playerId = player.Id,
|
||||||
displayName = player.DisplayName,
|
PlayerId = player.Id,
|
||||||
avatarUrl = "",
|
playFabId = player.Id,
|
||||||
},
|
PlayFabId = player.Id,
|
||||||
|
// name
|
||||||
|
displayName,
|
||||||
|
DisplayName = displayName,
|
||||||
|
titleDisplayName = displayName,
|
||||||
|
TitleDisplayName = displayName,
|
||||||
|
name = displayName,
|
||||||
|
username = displayName,
|
||||||
|
Username = displayName,
|
||||||
|
// steam
|
||||||
|
steamId,
|
||||||
|
SteamId = steamId,
|
||||||
|
steamInfo = new { steamId, SteamId = steamId },
|
||||||
|
SteamInfo = new { SteamId = steamId, steamId },
|
||||||
|
// presence
|
||||||
onlineState,
|
onlineState,
|
||||||
|
OnlineState = onlineState,
|
||||||
|
isOnline = onlineState > 0,
|
||||||
|
inMatch = onlineState == 2,
|
||||||
|
presence = new { onlineState, state = onlineState },
|
||||||
|
avatarUrl = "",
|
||||||
|
// nested profiles
|
||||||
|
profile = new { playerId = player.Id, displayName, avatarUrl = "" },
|
||||||
|
Profile = new { PlayerId = player.Id, DisplayName = displayName, PlayerProfileModel = new { DisplayName = displayName } },
|
||||||
|
tags = Array.Empty<string>(),
|
||||||
|
Tags = Array.Empty<string>(),
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// NOTE: the exact response shape the client expects is not yet confirmed; this is a
|
// Return the list under both the camelCase and PlayFab-cased container keys.
|
||||||
// best-effort structure. The log lets us verify resolution while we validate in game.
|
var result = new { friends, Friends = friends, count = friends.Count };
|
||||||
_logger.LogInformation("GetFriendList for {User}: {Count} friend(s) resolved on server", userId, friends.Count);
|
_logger.LogInformation("GetFriendList for {User}: {Count} friend(s); payload={Json}", userId, friends.Count, JsonSerializer.Serialize(result));
|
||||||
return new { friends };
|
return result;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user