You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 
 

239 lines
9.6 KiB

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<CSChatReq>();
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<SSPrivateChatNotify>();
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<CSQueryChatDataReq>();
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);
}
}
}