using Sog; using ProtoCSStruct; namespace Friend { public static class ChatSvc { // send -> target, send收到chatsvr转发过来的私聊CSChatRes, 修改sendTime后转发target所在服务器SSChatNotify // 不考虑target是否存在, 服务器聊天尽可能简单, 客户端私聊前自己发起uid查询请求 // 黑名单功能由chatsvr处理 public static void OnChatReq(uint remoteAppId, StructPacket packet) { ref CSChatReq req = ref packet.GetMessage(); PlayerInfoFriend player = FriendServerUtils.GetPlayerTableOp().GetPlayerInfo(req.Uid); if (player == null || ! player.IsOnline) { TraceLog.Error("ChatSvc.OnChatReq uid {0} not online", req.Uid); return; } // 发送者的数据肯定在缓存中 ref FriendCacheInfoStruct senderInfo = ref FriendOp.GetFriendInfoByUid(req.Uid); if (senderInfo.IsNull()) { TraceLog.Error("ChatSvc.OnChatReq uid {0} not in friendCache", req.Uid); return; } CSChatRes res = new CSChatRes {Uid = req.Uid, TargetUid = req.TargetUid}; res.Nick.SetString(senderInfo.Self.Nick.GetString()); res.Icon.SetString(senderInfo.Self.Icon.GetString()); res.IconFrameId = senderInfo.Self.IconFrameId; res.Gender = senderInfo.Self.Gender; res.ChatChannelType = req.ChatChannelType; res.Message = req.Message; res.ClientQuerySeq = req.LocalChatSeq; res.RealmId = senderInfo.Self.RealmId; // 先保存到sender的消息列表 if (SavePrivateChat(ref senderInfo, res.TargetUid, ref res) != 0) { return; } // target不在当前服务器 if (! FriendUtils.IsPlayerBelongThisServer(res.TargetUid)) { var notify = new SSPrivateChatNotify {Chat = res}; FriendServerUtils.GetPacketSender().SendToFriendServer((int) SSGameMsgID.PrivateChatNotify, ref notify, res.TargetUid); return; } ref FriendCacheInfoStruct targetInfo = ref FriendOp.GetFriendInfoByUid(res.TargetUid); // target数据不在内存 if (targetInfo.IsNull()) { TraceLog.Trace("ChatSvc.OnChatReq target {0} not in friendCache", res.TargetUid); FriendCacheSvc.SendDBQueryFriendInfoCacheBySaveChat(res.TargetUid, res.Uid, ref res); return; } //不是同一个logicWorld if(!FriendServerUtils.CheckIsSameLogicWorld(senderInfo.Self.RealmId, targetInfo.Self.RealmId)) { TraceLog.Error("ChatSvc.OnChatReq sender {0} {1} target {2} {3} not same logicWorld", senderInfo.Self.Uid, senderInfo.Self.RealmId, targetInfo.Self.Uid, targetInfo.Self.RealmId); return; } SavePrivateChat(ref targetInfo, res.Uid, ref res); } public static void OnPrivateChatNotify(uint remoteAppId, StructPacket packet) { ref SSPrivateChatNotify notify = ref packet.GetMessage(); ref CSChatRes res = ref notify.Chat; ref FriendCacheInfoStruct targetInfo = ref FriendOp.GetFriendInfoByUid(res.TargetUid); if (targetInfo.IsNull()) { TraceLog.Trace("ChatSvc.OnPrivateChatNotify target {0} no FriendCacheInfo", res.TargetUid); FriendCacheSvc.SendDBQueryFriendInfoCacheBySaveChat(res.TargetUid, res.Uid, ref res); return; } //不是同一个logicWorld if (!FriendServerUtils.CheckIsSameLogicWorld(res.RealmId, targetInfo.Self.RealmId)) { TraceLog.Error("ChatSvc.OnPrivateChatNotify sender {0} {1} target {2} {3} not same logicWorld", res.Uid, res.RealmId, targetInfo.Self.Uid, targetInfo.Self.RealmId); return; } SavePrivateChat(ref targetInfo, res.Uid, ref res); } public static void SavePrivateChatOnDBRes(ref CSChatRes res) { ref FriendCacheInfoStruct targetInfo = ref FriendOp.GetFriendInfoByUid(res.TargetUid); if (targetInfo.IsNull()) { TraceLog.Trace("ChatSvc.SavePrivateChatOnDBRes target {0} no FriendCacheInfo", res.TargetUid); return; } SavePrivateChat(ref targetInfo, res.Uid, ref res); } public static int SavePrivateChat(ref FriendCacheInfoStruct selfInfo, long targetUid, ref CSChatRes res) { long uid = selfInfo.Self.Uid; // 跳过黑名单中的发送者 for (int i = 0; i < selfInfo.Self.BlackList.Count; i++) { if (selfInfo.Self.BlackList[i] == targetUid) { TraceLog.Trace("ChatSvc.SavePrivateChat target {0} in uid {1} blacklist", targetUid, uid); return -1; } } // 以self所在服务器的时间为准 res.SendTime = FriendServerUtils.GetTimeMs(); FriendOp.DoAddNewFriendChatToMySelf(uid, ref res); TraceLog.Trace("ChatSvc.SavePrivateChat uid {0} target {1}", uid, targetUid); PlayerInfoFriend player = FriendServerUtils.GetPlayerTableOp().GetPlayerInfo(uid); if (player != null && player.IsOnline) { if (uid == res.Uid) { // 把缓存的新消息发送给sender QueryPrivateChat(player, ref selfInfo, res.ClientQuerySeq); } else { // 通知target收到新消息 var notify = new CSRecvPrivateChatNotify(); FriendServerUtils.GetPacketSender().SendToServerByID(player.ChatServerID, (int) CSGameMsgID.RecvPrivateChatNotify, ref notify, res.TargetUid); } } return 0; } public static void OnQueryChatDataReq(uint remoteAppId, StructPacket packet) { ref CSQueryChatDataReq req = ref packet.GetMessage(); long uid = packet.ObjectID; PlayerInfoFriend player = FriendServerUtils.GetPlayerTableOp().GetPlayerInfo(uid); if (player == null) { TraceLog.Error("ChatSvc.QueryPrivateChat uid {0} no player", uid); return; } if (player.ChatServerID == 0) { TraceLog.Trace("ChatSvc.QueryPrivateChat uid {0} no chatsvr id", uid); return; } ref FriendCacheInfoStruct friendInfo = ref FriendOp.GetFriendInfoByUid(uid); if (friendInfo.IsNull()) { TraceLog.Trace("ChatSvc.QueryPrivateChat uid {0} no FriendCacheInfo", uid); FriendCacheSvc.SendDBQueryFriendInfoCacheByQueryChat(uid, uid, req.Seq); return; } QueryPrivateChat(player, ref friendInfo, req.Seq); } public static void QueryPrivateChat(PlayerInfoFriend player, ref FriendCacheInfoStruct friendInfo, long seq) { long uid = friendInfo.Self.Uid; CSQueryChatDataRes res = new CSQueryChatDataRes { Uid = uid, }; for (int i = 0; i < friendInfo.FriendOpData.ChatCount; i++) { ref DBFriendChatOneStruct oneChat = ref FriendOp.GetFriendChatByIndex(ref friendInfo, i); if (oneChat.oneFriendChat.ChatSeq > seq) { var chatRes = new CSChatRes {ChatChannelType = ChatChannelType.Friend}; FriendUtils.CopyDBFriendChatToCSChat(ref oneChat.oneFriendChat, ref chatRes); res.ChatList.Add(chatRes); } } TraceLog.Trace("ChatSvc.QueryPrivateChat uid {0} query seq {1} new chat {2}", uid, seq, res.ChatList.Count); // 没有新内容了, 全部删除 if (res.ChatList.Count == 0 && friendInfo.FriendOpData.ChatCount > 0) { FriendOp.DoDeleteAllChat(ref friendInfo); } FriendServerUtils.GetPacketSender().SendToServerByID(player.ChatServerID, (int)CSGameMsgID.QueryChatDataRes, ref res, uid); } public static void OnQueryChatDataResFromDB(long uid, long chatSeq) { PlayerInfoFriend player = FriendServerUtils.GetPlayerTableOp().GetPlayerInfo(uid); if (player == null) { TraceLog.Error("ChatSvc.OnQueryChatDataResFromDB uid {0} no player", uid); return; } if (player.ChatServerID == 0) { TraceLog.Trace("ChatSvc.OnQueryChatDataResFromDB uid {0} no chatsvr id", uid); return; } ref FriendCacheInfoStruct friendInfo = ref FriendOp.GetFriendInfoByUid(uid); if (friendInfo.IsNull()) { TraceLog.Trace("ChatSvc.OnQueryChatDataResFromDB uid {0} no FriendCacheInfo", uid); return; } QueryPrivateChat(player, ref friendInfo, chatSeq); } //判断是否在黑名单,selfInfo应该之前做判断处理,这里不重复操作 public static bool IsInBlackList(ref FriendCacheInfoStruct selfInfo, long uid) { return selfInfo.Self.BlackList.Contains(uid); } } }