diff --git a/DysonNetwork.Pass/Account/AccountServiceGrpc.cs b/DysonNetwork.Pass/Account/AccountServiceGrpc.cs index d4f235a..6a0a773 100644 --- a/DysonNetwork.Pass/Account/AccountServiceGrpc.cs +++ b/DysonNetwork.Pass/Account/AccountServiceGrpc.cs @@ -53,7 +53,8 @@ public class AccountServiceGrpc( .FirstOrDefaultAsync(a => a.AutomatedId == automatedId); if (account == null) - throw new RpcException(new Grpc.Core.Status(StatusCode.NotFound, $"Account with automated ID {request.AutomatedId} not found")); + throw new RpcException(new Grpc.Core.Status(StatusCode.NotFound, + $"Account with automated ID {request.AutomatedId} not found")); var perk = await subscriptions.GetPerkSubscriptionAsync(account.Id); account.PerkSubscription = perk?.ToReference(); @@ -87,8 +88,8 @@ public class AccountServiceGrpc( response.Accounts.AddRange(accounts.Select(a => a.ToProtoValue())); return response; } - - + + public override async Task GetBotAccountBatch(GetBotAccountBatchRequest request, ServerCallContext context) { @@ -159,7 +160,8 @@ public class AccountServiceGrpc( return response; } - public override async Task SearchAccount(SearchAccountRequest request, ServerCallContext context) + public override async Task SearchAccount(SearchAccountRequest request, + ServerCallContext context) { var accounts = await _db.Accounts .AsNoTracking() @@ -232,21 +234,48 @@ public class AccountServiceGrpc( public override async Task ListFriends( ListRelationshipSimpleRequest request, ServerCallContext context) { - var accountId = Guid.Parse(request.AccountId); - var relationship = await relationships.ListAccountFriends(accountId); var resp = new ListRelationshipSimpleResponse(); - resp.AccountsId.AddRange(relationship.Select(x => x.ToString())); - return resp; + switch (request.RelationIdentifierCase) + { + case ListRelationshipSimpleRequest.RelationIdentifierOneofCase.AccountId: + var accountId = Guid.Parse(request.AccountId); + var relationship = await relationships.ListAccountFriends(accountId); + resp.AccountsId.AddRange(relationship.Select(x => x.ToString())); + return resp; + case ListRelationshipSimpleRequest.RelationIdentifierOneofCase.RelatedId: + var relatedId = Guid.Parse(request.RelatedId); + var relatedRelationship = await relationships.ListAccountFriends(relatedId, true); + resp.AccountsId.AddRange(relatedRelationship.Select(x => x.ToString())); + return resp; + break; + case ListRelationshipSimpleRequest.RelationIdentifierOneofCase.None: + default: + throw new RpcException(new Status(StatusCode.InvalidArgument, + $"The relationship identifier must be provided.")); + } } public override async Task ListBlocked( ListRelationshipSimpleRequest request, ServerCallContext context) { - var accountId = Guid.Parse(request.AccountId); - var relationship = await relationships.ListAccountBlocked(accountId); var resp = new ListRelationshipSimpleResponse(); - resp.AccountsId.AddRange(relationship.Select(x => x.ToString())); - return resp; + switch (request.RelationIdentifierCase) + { + case ListRelationshipSimpleRequest.RelationIdentifierOneofCase.AccountId: + var accountId = Guid.Parse(request.AccountId); + var relationship = await relationships.ListAccountBlocked(accountId); + resp.AccountsId.AddRange(relationship.Select(x => x.ToString())); + return resp; + case ListRelationshipSimpleRequest.RelationIdentifierOneofCase.RelatedId: + var relatedId = Guid.Parse(request.RelatedId); + var relatedRelationship = await relationships.ListAccountBlocked(relatedId, true); + resp.AccountsId.AddRange(relatedRelationship.Select(x => x.ToString())); + return resp; + case ListRelationshipSimpleRequest.RelationIdentifierOneofCase.None: + default: + throw new RpcException(new Status(StatusCode.InvalidArgument, + $"The relationship identifier must be provided.")); + } } public override async Task GetRelationship(GetRelationshipRequest request, diff --git a/DysonNetwork.Pass/Account/RelationshipService.cs b/DysonNetwork.Pass/Account/RelationshipService.cs index 248f9aa..52002f7 100644 --- a/DysonNetwork.Pass/Account/RelationshipService.cs +++ b/DysonNetwork.Pass/Account/RelationshipService.cs @@ -52,7 +52,8 @@ public class RelationshipService( return relationship; } - public async Task CreateRelationship(SnAccount sender, SnAccount target, RelationshipStatus status) + public async Task CreateRelationship(SnAccount sender, SnAccount target, + RelationshipStatus status) { if (status == RelationshipStatus.Pending) throw new InvalidOperationException( @@ -169,12 +170,14 @@ public class RelationshipService( await db.SaveChangesAsync(); - await PurgeRelationshipCache(relationship.AccountId, relationship.RelatedId, RelationshipStatus.Friends, status); + await PurgeRelationshipCache(relationship.AccountId, relationship.RelatedId, RelationshipStatus.Friends, + status); return relationshipBackward; } - public async Task UpdateRelationship(Guid accountId, Guid relatedId, RelationshipStatus status) + public async Task UpdateRelationship(Guid accountId, Guid relatedId, + RelationshipStatus status) { var relationship = await GetRelationship(accountId, relatedId); if (relationship is null) throw new ArgumentException("There is no relationship between you and the user."); @@ -189,24 +192,26 @@ public class RelationshipService( return relationship; } - public async Task> ListAccountFriends(SnAccount account) + public async Task> ListAccountFriends(SnAccount account, bool isRelated = false) { - return await ListAccountFriends(account.Id); + return await ListAccountFriends(account.Id, isRelated); } - public async Task> ListAccountFriends(Guid accountId) + public async Task> ListAccountFriends(Guid accountId, bool isRelated = false) { - return await GetCachedRelationships(accountId, RelationshipStatus.Friends, UserFriendsCacheKeyPrefix); + return await GetCachedRelationships(accountId, RelationshipStatus.Friends, UserFriendsCacheKeyPrefix, + isRelated); } - public async Task> ListAccountBlocked(SnAccount account) + public async Task> ListAccountBlocked(SnAccount account, bool isRelated = false) { - return await ListAccountBlocked(account.Id); + return await ListAccountBlocked(account.Id, isRelated); } - public async Task> ListAccountBlocked(Guid accountId) + public async Task> ListAccountBlocked(Guid accountId, bool isRelated = false) { - return await GetCachedRelationships(accountId, RelationshipStatus.Blocked, UserBlockedCacheKeyPrefix); + return await GetCachedRelationships(accountId, RelationshipStatus.Blocked, UserBlockedCacheKeyPrefix, + isRelated); } public async Task HasRelationshipWithStatus(Guid accountId, Guid relatedId, @@ -216,29 +221,26 @@ public class RelationshipService( return relationship is not null; } - private async Task> GetCachedRelationships(Guid accountId, RelationshipStatus status, string cachePrefix) + private async Task> GetCachedRelationships( + Guid accountId, + RelationshipStatus status, + string cachePrefix, + bool isRelated = false + ) { if (accountId == Guid.Empty) throw new ArgumentException("Account ID cannot be empty."); - var cacheKey = $"{cachePrefix}{accountId}"; + var cacheKey = $"{cachePrefix}{accountId}:{isRelated}"; var relationships = await cache.GetAsync>(cacheKey); if (relationships != null) return relationships; var now = Instant.FromDateTimeUtc(DateTime.UtcNow); var query = db.AccountRelationships - .Where(r => r.RelatedId == accountId) + .Where(r => isRelated ? r.RelatedId == accountId : r.AccountId == accountId) .Where(r => r.Status == status) .Where(r => r.ExpiredAt == null || r.ExpiredAt > now) - .Select(r => r.AccountId); - - if (status == RelationshipStatus.Friends) - { - var usersBlockedByMe = db.AccountRelationships - .Where(r => r.AccountId == accountId && r.Status == RelationshipStatus.Blocked) - .Select(r => r.RelatedId); - query = query.Except(usersBlockedByMe); - } + .Select(r => isRelated ? r.AccountId : r.RelatedId); relationships = await query.ToListAsync(); @@ -271,4 +273,4 @@ public class RelationshipService( var removeTasks = keysToRemove.Select(key => cache.RemoveAsync(key)); await Task.WhenAll(removeTasks); } -} +} \ No newline at end of file diff --git a/DysonNetwork.Shared/Proto/account.proto b/DysonNetwork.Shared/Proto/account.proto index 30cb6bc..b480ccd 100644 --- a/DysonNetwork.Shared/Proto/account.proto +++ b/DysonNetwork.Shared/Proto/account.proto @@ -290,8 +290,6 @@ service AccountService { rpc ListConnections(ListConnectionsRequest) returns (ListConnectionsResponse) {} // Relationship Operations - rpc ListRelationships(ListRelationshipsRequest) returns (ListRelationshipsResponse) {} - rpc GetRelationship(GetRelationshipRequest) returns (GetRelationshipResponse) {} rpc HasRelationship(GetRelationshipRequest) returns (google.protobuf.BoolValue) {} rpc ListFriends(ListRelationshipSimpleRequest) returns (ListRelationshipSimpleResponse) {} @@ -489,7 +487,10 @@ message GetRelationshipResponse { } message ListRelationshipSimpleRequest { - string account_id = 1; + oneof relation_identifier { + string account_id = 1; + string related_id = 2; + } } message ListRelationshipSimpleResponse {