1616
1717
1818using GameFrameX . Apps . Player . Friend ;
19+ using GameFrameX . Apps . Player . Friend . Entity ;
20+ using GameFrameX . Apps . Player . Player . Entity ;
1921using GameFrameX . NetWork . RemoteMessaging . Contracts ;
2022using GameFrameX . NetWork . RemoteMessaging . Unified ;
2123
@@ -86,6 +88,16 @@ public async Task OnAddFriend(INetWorkChannel netWorkChannel, ReqFriendByAdd req
8688 {
8789 var reqInnerAddFriend = MessageObjectPoolHelper . Get < ReqInnerFriendByAdd > ( ) ;
8890 reqInnerAddFriend . PlayerId = request . PlayerId ;
91+ if ( string . Equals ( GlobalSettings . CurrentSetting ? . ServerType , GameServerConst . Social . Name , StringComparison . OrdinalIgnoreCase ) )
92+ {
93+ var innerResponse = new RespInnerFriendByAdd ( ) ;
94+ await OnInnerAddFriend ( netWorkChannel , reqInnerAddFriend , innerResponse ) ;
95+ response . Success = innerResponse . Success ;
96+ response . ErrorCode = innerResponse . ErrorCode ;
97+ MessageObjectPoolHelper . Return ( reqInnerAddFriend ) ;
98+ return ;
99+ }
100+
89101 try
90102 {
91103 var options = ServerSendOptions . Command ( RpcTimeoutMilliseconds ) ;
@@ -95,16 +107,19 @@ public async Task OnAddFriend(INetWorkChannel netWorkChannel, ReqFriendByAdd req
95107 if ( result . IsSuccess && result . Response != null )
96108 {
97109 response . Success = result . Response . Success ;
110+ response . ErrorCode = NormalizeBusinessErrorCode ( result . Response . Success , result . Response . ErrorCode , request . PlayerId , "OnAddFriend" ) ;
98111 return ;
99112 }
100113
101114 response . Success = false ;
115+ response . ErrorCode = MapToBusinessErrorCode ( result . StatusCode ) ;
102116 LogHelper . Error ( "FriendComponentAgent.OnAddFriend 统一消息发送失败, StatusCode: {statusCode}, Error: {errorMessage}, TraceId: {traceId}" ,
103117 result . StatusCode , result . ErrorMessage , result . TraceId ) ;
104118 }
105119 catch ( Exception exception )
106120 {
107121 response . Success = false ;
122+ response . ErrorCode = - 2 ;
108123 LogHelper . Error ( exception , "FriendComponentAgent.OnAddFriend 统一消息发送异常" ) ;
109124 }
110125 finally
@@ -113,24 +128,197 @@ public async Task OnAddFriend(INetWorkChannel netWorkChannel, ReqFriendByAdd req
113128 }
114129 }
115130
131+ /// <summary>
132+ /// 删除好友(通过统一消息发送器调用 Social 服务)。
133+ /// 删除好友为非幂等操作,不允许重试。
134+ /// </summary>
135+ /// <param name="netWorkChannel">网络通道</param>
136+ /// <param name="request">请求</param>
137+ /// <param name="response">响应</param>
138+ public async Task OnDeleteFriend ( INetWorkChannel netWorkChannel , ReqDeleteFriend request , RespDeleteFriend response )
139+ {
140+ var reqInnerDeleteFriend = MessageObjectPoolHelper . Get < ReqInnerFriendByDelete > ( ) ;
141+ reqInnerDeleteFriend . PlayerId = request . PlayerId ;
142+ if ( string . Equals ( GlobalSettings . CurrentSetting ? . ServerType , GameServerConst . Social . Name , StringComparison . OrdinalIgnoreCase ) )
143+ {
144+ var innerResponse = new RespInnerFriendByDelete ( ) ;
145+ await OnInnerDeleteFriend ( netWorkChannel , reqInnerDeleteFriend , innerResponse ) ;
146+ response . Success = innerResponse . Success ;
147+ response . ErrorCode = innerResponse . ErrorCode ;
148+ MessageObjectPoolHelper . Return ( reqInnerDeleteFriend ) ;
149+ return ;
150+ }
151+
152+ try
153+ {
154+ var options = ServerSendOptions . Command ( RpcTimeoutMilliseconds ) ;
155+ var result = await UnifiedMessageSenderHolder . Sender . SendToServerAsync < RespInnerFriendByDelete > (
156+ GameServerConst . Social . Name , reqInnerDeleteFriend , options ) ;
157+
158+ if ( result . IsSuccess && result . Response != null )
159+ {
160+ response . Success = result . Response . Success ;
161+ response . ErrorCode = NormalizeBusinessErrorCode ( result . Response . Success , result . Response . ErrorCode , request . PlayerId , "OnDeleteFriend" ) ;
162+ return ;
163+ }
164+
165+ response . Success = false ;
166+ response . ErrorCode = MapToBusinessErrorCode ( result . StatusCode ) ;
167+ LogHelper . Error ( "FriendComponentAgent.OnDeleteFriend 统一消息发送失败, StatusCode: {statusCode}, Error: {errorMessage}, TraceId: {traceId}" ,
168+ result . StatusCode , result . ErrorMessage , result . TraceId ) ;
169+ }
170+ catch ( Exception exception )
171+ {
172+ response . Success = false ;
173+ response . ErrorCode = - 2 ;
174+ LogHelper . Error ( exception , "FriendComponentAgent.OnDeleteFriend 统一消息发送异常" ) ;
175+ }
176+ finally
177+ {
178+ MessageObjectPoolHelper . Return ( reqInnerDeleteFriend ) ;
179+ }
180+ }
181+
182+ /// <summary>
183+ /// Social 进程内的添加好友处理。
184+ /// 将好友关系写入数据库。
185+ /// </summary>
186+ public async Task OnInnerAddFriend ( INetWorkChannel netWorkChannel , ReqInnerFriendByAdd request , RespInnerFriendByAdd response )
187+ {
188+ var ownerPlayerId = ActorId ;
189+ var targetPlayerId = request . PlayerId ;
190+
191+ // 参数校验
192+ if ( ownerPlayerId <= 0 || targetPlayerId <= 0 )
193+ {
194+ response . Success = false ;
195+ response . ErrorCode = - 100 ;
196+ return ;
197+ }
198+
199+ // 不能加自己为好友
200+ if ( ownerPlayerId == targetPlayerId )
201+ {
202+ response . Success = false ;
203+ response . ErrorCode = - 101 ;
204+ return ;
205+ }
206+
207+ // 确认目标玩家存在
208+ var targetPlayer = await GameDb . FindAsync < PlayerState > ( targetPlayerId ) ;
209+ if ( targetPlayer == null )
210+ {
211+ response . Success = false ;
212+ response . ErrorCode = - 102 ;
213+ return ;
214+ }
215+
216+ // 构建关系(确保 PlayerIdA < PlayerIdB 保证唯一性)
217+ long playerIdA = Math . Min ( ownerPlayerId , targetPlayerId ) ;
218+ long playerIdB = Math . Max ( ownerPlayerId , targetPlayerId ) ;
219+
220+ // 检查是否已存在好友关系
221+ var existingRelation = await GameDb . FindAsync < FriendRelationState > (
222+ m => m . PlayerIdA == playerIdA && m . PlayerIdB == playerIdB && m . Status == 0 , false ) ;
223+
224+ if ( existingRelation != null )
225+ {
226+ response . Success = false ;
227+ response . ErrorCode = - 103 ; // 已是好友
228+ return ;
229+ }
230+
231+ // 插入新的好友关系
232+ var newRelation = new FriendRelationState
233+ {
234+ Id = ActorIdGenerator . GetActorId ( GlobalConst . ActorTypePlayer ) ,
235+ PlayerIdA = playerIdA ,
236+ PlayerIdB = playerIdB ,
237+ CreateTime = DateTime . UtcNow ,
238+ CreatedBy = ownerPlayerId ,
239+ Status = 0
240+ } ;
241+
242+ await GameDb . AddOrUpdateAsync ( newRelation ) ;
243+ response . Success = true ;
244+ response . ErrorCode = 0 ;
245+ }
246+
116247 /// <summary>
117248 /// Social 进程内的好友列表处理。
249+ /// 从数据库查询所有有效好友关系,并填充好友详情。
118250 /// </summary>
119251 /// <param name="netWorkChannel">网络通道</param>
120252 /// <param name="request">请求</param>
121253 /// <param name="response">响应</param>
122254 public async Task OnInnerFriendList ( INetWorkChannel netWorkChannel , ReqInnerFriendList request , RespInnerFriendList response )
123255 {
124- response . Friends = new List < FriendInfo >
256+ var ownerPlayerId = request . PlayerId > 0 ? request . PlayerId : ActorId ;
257+
258+ // 查询所有包含自己的有效好友关系
259+ var relations = await GameDb . FindListAsync < FriendRelationState > (
260+ m => ( m . PlayerIdA == ownerPlayerId || m . PlayerIdB == ownerPlayerId ) && m . Status == 0 ) ;
261+
262+ var friends = new List < FriendInfo > ( ) ;
263+ foreach ( var relation in relations )
125264 {
126- new FriendInfo
265+ // 找出对方玩家的ID
266+ long friendPlayerId = relation . PlayerIdA == ownerPlayerId ? relation . PlayerIdB : relation . PlayerIdA ;
267+
268+ // 查找对方玩家详情
269+ var friendPlayer = await GameDb . FindAsync < PlayerState > ( friendPlayerId ) ;
270+ if ( friendPlayer != null )
127271 {
128- PlayerId = request . PlayerId <= 0 ? 1 : request . PlayerId ,
129- PlayerName = "SocialLocalFriend"
272+ friends . Add ( new FriendInfo
273+ {
274+ PlayerId = friendPlayer . Id ,
275+ PlayerName = friendPlayer . Name
276+ } ) ;
130277 }
131- } ;
278+ }
279+
280+ response . Friends = friends ;
281+ response . ErrorCode = 0 ;
282+ }
283+
284+ /// <summary>
285+ /// Social 进程内的删除好友处理。
286+ /// 软删除好友关系(设置 Status = 1)。
287+ /// </summary>
288+ public async Task OnInnerDeleteFriend ( INetWorkChannel netWorkChannel , ReqInnerFriendByDelete request , RespInnerFriendByDelete response )
289+ {
290+ var ownerPlayerId = ActorId ;
291+ var targetPlayerId = request . PlayerId ;
292+
293+ // 参数校验
294+ if ( ownerPlayerId <= 0 || targetPlayerId <= 0 )
295+ {
296+ response . Success = false ;
297+ response . ErrorCode = - 100 ;
298+ return ;
299+ }
300+
301+ // 构建关系键
302+ long playerIdA = Math . Min ( ownerPlayerId , targetPlayerId ) ;
303+ long playerIdB = Math . Max ( ownerPlayerId , targetPlayerId ) ;
304+
305+ // 查找好友关系
306+ var relation = await GameDb . FindAsync < FriendRelationState > (
307+ m => m . PlayerIdA == playerIdA && m . PlayerIdB == playerIdB && m . Status == 0 , false ) ;
308+
309+ if ( relation == null )
310+ {
311+ response . Success = false ;
312+ response . ErrorCode = - 104 ; // 好友关系不存在
313+ return ;
314+ }
315+
316+ // 软删除
317+ relation . Status = 1 ;
318+ await GameDb . AddOrUpdateAsync ( relation ) ;
319+
320+ response . Success = true ;
132321 response . ErrorCode = 0 ;
133- await Task . CompletedTask ;
134322 }
135323
136324 /// <summary>
@@ -162,4 +350,16 @@ private static int MapToBusinessErrorCode(RemoteStatusCode statusCode)
162350 return - 99 ;
163351 }
164352 }
353+
354+ private static int NormalizeBusinessErrorCode ( bool success , int errorCode , long requestPlayerId , string actionName )
355+ {
356+ if ( success || errorCode != 0 )
357+ {
358+ return errorCode ;
359+ }
360+
361+ LogHelper . Error ( "FriendComponentAgent.{actionName} 返回语义异常: Success=false 且 ErrorCode=0, PlayerId={playerId}" ,
362+ actionName , requestPlayerId ) ;
363+ return - 101 ;
364+ }
165365}
0 commit comments