Skip to content

Commit e11138b

Browse files
Fix co-op error when using static helpers (#1353)
When playing co-op, if you view details for another player, the client will make a call to /friend/get_support_chara_detail with their ID. If you have static helpers enabled, this will fail. We should fall back to real helper data to handle this case. We expect this particular case to always hit this path rather than a static helper shadowing a real player, because all the static helper IDs are near ulong.MaxValue. So there is a clear separation, unless we get a LOT of new players. Note: it shouldn't be necessary to do this for GetHelper above as that is only called from /friend/id_search.
1 parent 4b7634a commit e11138b

2 files changed

Lines changed: 44 additions & 2 deletions

File tree

DragaliaAPI/DragaliaAPI.Integration.Test/Features/Friends/SupportCharaTest.cs

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -291,6 +291,32 @@ await this.Client.PostMsgpack<FriendGetSupportCharaDetailResponse>(
291291
response.SupportUserDataDetail.IsFriend.Should().BeTrue();
292292
}
293293

294+
[Fact]
295+
public async Task GetSupportCharaDetail_StaticEnabled_SendsRealViewerId_GetsCorrectCharacter()
296+
{
297+
// See comment in StaticHelperDataService explaining why this is a valid scenario
298+
299+
this.ApiContext.PlayerSettings.Add(
300+
new()
301+
{
302+
ViewerId = this.ViewerId,
303+
SettingsJson = new() { UseLegacyHelpers = true },
304+
}
305+
);
306+
await this.ApiContext.SaveChangesAsync(TestContext.Current.CancellationToken);
307+
308+
DragaliaResponse<FriendGetSupportCharaDetailResponse> response = (
309+
await this.Client.PostMsgpack<FriendGetSupportCharaDetailResponse>(
310+
"/friend/get_support_chara_detail",
311+
new FriendGetSupportCharaDetailRequest() { SupportViewerId = (ulong)this.ViewerId },
312+
cancellationToken: TestContext.Current.CancellationToken,
313+
ensureSuccessHeader: false
314+
)
315+
);
316+
317+
response.DataHeaders.ResultCode.Should().Be(ResultCode.Success);
318+
}
319+
294320
[Fact]
295321
public async Task GetSupportCharaDetail_RealViewerId_GetsSupportCharaDetail()
296322
{

DragaliaAPI/DragaliaAPI/Features/Friends/StaticHelperDataService.cs

Lines changed: 18 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,10 @@
44

55
namespace DragaliaAPI.Features.Friends;
66

7-
public class StaticHelperDataService(IBonusService bonusService) : IHelperDataService
7+
internal sealed class StaticHelperDataService(
8+
IBonusService bonusService,
9+
RealHelperDataService realHelperDataService
10+
) : IHelperDataService
811
{
912
public Task<QuestGetSupportUserListResponse> GetHelperList(CancellationToken cancellationToken)
1013
{
@@ -32,7 +35,20 @@ CancellationToken cancellationToken
3235

3336
if (staticHelperInfo is null)
3437
{
35-
return null;
38+
// When playing co-op, if you view details for another player, the client will make a call to
39+
// /friend/get_support_chara_detail with their ID. If you have static helpers enabled, this will fail. We
40+
// should fall back to real helper data to handle this case.
41+
// We expect this particular case to always hit this path rather than a static helper shadowing a real
42+
// player, because all the static helper IDs are near ulong.MaxValue. So there is a clear separation, unless
43+
// we get a LOT of new players.
44+
//
45+
// Note: it shouldn't be necessary to do this for GetHelper above as that is only called from
46+
// /friend/id_search.
47+
//
48+
return await realHelperDataService.GetHelperDataDetail(
49+
helperViewerId,
50+
cancellationToken
51+
);
3652
}
3753

3854
FortBonusList bonusList = await bonusService.GetBonusList(cancellationToken);

0 commit comments

Comments
 (0)