Compare commits
17
Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
e5ab911dfd | ||
|
|
042f806697 | ||
|
|
a4c8cf5955 | ||
|
|
d1f3fd1125 | ||
|
|
b05782d4e9 | ||
|
|
d7c89327a7 | ||
|
|
03048b793d | ||
|
|
1d9cf795dd | ||
|
|
7dbab1aab8 | ||
|
|
078d2f80be | ||
|
|
c986a98471 | ||
|
|
57a45d91df | ||
|
|
c6b2330e1d | ||
|
|
9737316dbc | ||
|
|
a4e006f84f | ||
|
|
3cdf8bc7e2 | ||
|
|
67f3095896 |
@@ -9,14 +9,6 @@ public class RequestLoggerMiddleware
|
||||
private readonly ILogger<RequestLoggerMiddleware> _logger;
|
||||
private readonly RequestDelegate _next;
|
||||
|
||||
// Keywords used to surface social/squad/invite traffic while reverse-engineering the
|
||||
// squad-invite flow (see SQUAD-EMULATION.md). Matched against the path AND the body
|
||||
// (the CloudScript function name lives in the body of /Client/ExecuteFunction).
|
||||
private static readonly string[] SocialKeywords =
|
||||
{
|
||||
"group", "party", "lobby", "squad", "invite", "friend", "social", "matchmak",
|
||||
};
|
||||
|
||||
public RequestLoggerMiddleware(ILogger<RequestLoggerMiddleware> logger, RequestDelegate next)
|
||||
{
|
||||
_logger = logger;
|
||||
@@ -40,27 +32,6 @@ public class RequestLoggerMiddleware
|
||||
}
|
||||
|
||||
await _next(context);
|
||||
|
||||
// ── Capture pass (squad-invite RE, see SQUAD-EMULATION.md) ──────────────
|
||||
// Runs AFTER the pipeline so we know whether the request was actually routed.
|
||||
if (context.Request.Method == "POST")
|
||||
{
|
||||
var path = context.Request.Path.Value ?? "";
|
||||
var haystack = (path + " " + body).ToLowerInvariant();
|
||||
|
||||
// Any POST that fell through to a 404 = an endpoint the emulator does NOT implement
|
||||
// (e.g. a native PlayFab /Group/CreateGroup or /Lobby/* the client tried to call).
|
||||
if (context.Response.StatusCode == 404)
|
||||
{
|
||||
_logger.LogWarning("[CAPTURE UNROUTED] {Method} {Url} -> 404 | Body {Body}",
|
||||
context.Request.Method, context.Request.GetDisplayUrl(), body);
|
||||
}
|
||||
else if (SocialKeywords.Any(k => haystack.Contains(k)))
|
||||
{
|
||||
_logger.LogInformation("[CAPTURE SOCIAL] {Url} ({Status}) | Body {Body}",
|
||||
context.Request.GetDisplayUrl(), context.Response.StatusCode, body);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private static async Task<string> RequestAsync(HttpRequest request)
|
||||
|
||||
@@ -32,8 +32,9 @@ public class GetFriendList : ICloudScriptFunction<FYBaseSocialRequest, object?>
|
||||
}
|
||||
var userId = context.User.FindAuthUserId();
|
||||
|
||||
// Imported Steam friends (persisted by ClientsideFriendsImport), resolved to players
|
||||
// that actually exist on this private server.
|
||||
// Resolve the imported Steam friends (persisted by ClientsideFriendsImport) to the
|
||||
// players that actually exist on this server. It's a private server, so only friends
|
||||
// who have logged in here will show up.
|
||||
var steamIds = new List<string>();
|
||||
var userData = await _userDataService.FindAsync(userId, userId, new List<string> { "ImportedSteamFriends" });
|
||||
if (userData.TryGetValue("ImportedSteamFriends", out var rec) && !string.IsNullOrWhiteSpace(rec.Value))
|
||||
@@ -51,10 +52,8 @@ public class GetFriendList : ICloudScriptFunction<FYBaseSocialRequest, object?>
|
||||
{
|
||||
if (player.Id == userId) continue; // never list yourself
|
||||
|
||||
var steamId = player.Auth?.FirstOrDefault(a => a.Type == PlayFabUserAuthType.Steam)?.Key ?? "";
|
||||
var displayName = string.IsNullOrWhiteSpace(player.DisplayName) ? "Prospector" : player.DisplayName;
|
||||
|
||||
// 0 = offline, 1 = online, 2 = in match. Online if seen in the last 3 minutes.
|
||||
// Presence persisted by UpdatePlayerPresenceState: online if seen in the last
|
||||
// 3 minutes. EYUserState best-effort: 0 = offline, 1 = online, 2 = in match.
|
||||
var onlineState = 0;
|
||||
var presenceData = await _userDataService.FindAsync(player.Id, player.Id, new List<string> { "PresenceState" });
|
||||
if (presenceData.TryGetValue("PresenceState", out var presenceRec) && !string.IsNullOrWhiteSpace(presenceRec.Value))
|
||||
@@ -70,50 +69,22 @@ public class GetFriendList : ICloudScriptFunction<FYBaseSocialRequest, object?>
|
||||
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
|
||||
{
|
||||
// identity
|
||||
friendPlayFabId = player.Id,
|
||||
FriendPlayFabId = player.Id,
|
||||
profile = new
|
||||
{
|
||||
playerId = player.Id,
|
||||
PlayerId = player.Id,
|
||||
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,
|
||||
isOnline = onlineState > 0,
|
||||
inMatch = onlineState == 2,
|
||||
presence = new { onlineState, state = onlineState },
|
||||
displayName = player.DisplayName,
|
||||
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>(),
|
||||
},
|
||||
onlineState,
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
// Return the list under both the camelCase and PlayFab-cased container keys.
|
||||
var result = new { friends, Friends = friends, count = friends.Count };
|
||||
_logger.LogInformation("GetFriendList for {User}: {Count} friend(s); payload={Json}", userId, friends.Count, JsonSerializer.Serialize(result));
|
||||
return result;
|
||||
// NOTE: the exact response shape the client expects is not yet confirmed; this is a
|
||||
// best-effort structure. The log lets us verify resolution while we validate in game.
|
||||
_logger.LogInformation("GetFriendList for {User}: {Count} friend(s) resolved on server", userId, friends.Count);
|
||||
return new { friends };
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user