using System; using System.Collections.Generic; using System.Linq; using System.Threading.Tasks; using Sog; using Sog.Log; using ProtoCSStruct; namespace World { public static class MailSvc_Obsolete //(已淘汰,在MailServer中处理) { public static void OnQueryMailReq(uint remoteAppID, StructPacket packet) { ref SSQueryMailReq req = ref packet.GetMessage(); //转给db处理 uint dbServerID = DBServerIDUtils.GetGameDBServerID(req.Uid); WorldServerUtils.GetPacketSender().SendToServerByID(dbServerID, packet); } public static void OnQueryMailRes(uint remoteAppID, StructPacket packet) { ref SSQueryMailRes res = ref packet.GetMessage(); PlayerInfoWorld player = WorldServerUtils.GetPlayerTableOp().GetPlayerInfo(res.Uid); if (player == null) { TraceLog.Error("MailSvc.OnQueryMailRes can not find player uid {0}", res.Uid); return; } WorldServerUtils.GetPacketSender().SendToServerByID(player.GameServerID, (int)SSGameMsgID.QueryMailRes, ref res, res.Uid); } public static void OnMailOpReq(uint remoteAppID, StructPacket packet) { ref SSMailOpReq req = ref packet.GetMessage(); //转给db处理 uint dbServerID = DBServerIDUtils.GetGameDBServerID(req.Mail.Uid); WorldServerUtils.GetPacketSender().SendToServerByID(dbServerID, packet); } private static void OnWorldMailOpRes(SSMailOpRes res) { // world暂时只支持发送邮件操作 if (res.OpType != (int)MailOpType.Insert) { TraceLog.Debug("MailSvc.OnWorldSendMailRes invalid mailOp"); return; } TraceLog.Debug("MailSvc.OnWorldSendMailRes uniqueId {0} uid {1}, mail {2}", res.UniqueID, res.Mail.Uid, res.Mail.MailID); if (res.UniqueID != 0) { WaitAckStructRequestSender.Instance.OnReceiveSuccess(res.UniqueID); } // 发送失败时,打日志,220201表示邮件已经存在 if (res.Ret != 0 && res.Ret != 220201) { TraceLog.Error("MailSvc.OnWorldSendMailRes failed uid {0}, mail {1}", res.Mail.Uid, res.Mail.MailID); } CommBillLogUtils.LogMailOpRet(res.ClientOpUid, res.Mail, res.OpType, res.Ret); } public static void OnMailOpRes(uint remoteAppID, StructPacket packet) { ref SSMailOpRes res = ref packet.GetMessage(); // world发送的邮件 if (res.AckGameServerID == WorldServerUtils.GetAppID()) { OnWorldMailOpRes(res); } else if (res.AckGameServerID != 0) { //通知发起的那台服务器 WorldServerUtils.GetPacketSender().SendToServerByID(res.AckGameServerID, (int)SSGameMsgID.MailOpRes, ref res, res.ClientOpUid); } //新增邮件需要通知邮件的主人,如果他在线的话 //取附件和删除操作肯定是自己发起的,上面的AckGameServerID肯定不为空,可以走到(gm指令发起的不一定走到,所以都发一下) if (/*res.OpType == (int)MailOpType.Insert &&*/ res.Ret == 0 && res.ClientOpUid != res.Mail.Uid) { PlayerInfoWorld player = WorldServerUtils.GetPlayerTableOp().GetPlayerInfo(res.Mail.Uid); //不在线正常的很 if (player == null || player.GameServerID == 0) { TraceLog.Trace("MailSvc.OnMailOpRes can not find mail owner player uid {0}", res.Mail.Uid); return; } res.ClientOpUid = res.Mail.Uid; //清空这个uniqueID,只是通知而已 res.UniqueID = 0; TraceLog.Trace("MailSvc.OnMailOpRes notify mail owner player uid {0} insert new mail {1}", res.Mail.Uid, res.Mail.MailID); WorldServerUtils.GetPacketSender().SendToServerByID(player.GameServerID, (int)SSGameMsgID.MailOpRes, ref res, res.ClientOpUid); } } public static void SendMail(DBMail mail) { var req = new SSMailOpReq(); req.OpType = (int)MailOpType.Insert; req.AckGameServerID = WorldServerUtils.GetAppID(); req.UniqueID = WaitAckStructRequestSender.Instance.GeneratorUniqueID(); mail.InsertUniqueID = req.UniqueID; req.Mail = mail; TraceLog.Debug("MailSvc.SendMail uniqueId {0} mailId {1} uid {2}", req.UniqueID, mail.MailID, mail.Uid); uint dbServerID = DBServerIDUtils.GetGameDBServerID(mail.Uid); WaitAckStructRequestSender.Instance.BeginSendNeedResend(req.UniqueID, dbServerID, (int)SSGameMsgID.MailOpReq, ref req, 0); CommBillLogUtils.LogMailOpBegin(mail.Uid, mail, (int)MailOpType.Insert); } public static void GmSendMailWithRule(uint remoteAppID, StructPacket packet) { ref var req = ref packet.GetMessage(); TraceLog.Debug("MailSvc.GmSendMailWithRule begin RuleType {0} param {1}", req.RuleType, req.RuleParam1); if (req.RuleType == (int)SendMailRuleType.All) { GmSendMailWithRuleToAll(req.Mail, req.RuleParam1, (int)SendMailRuleType.All); } else if (req.RuleType == (int)SendMailRuleType.Ios) { GmSendMailWithRuleToAll(req.Mail, req.RuleParam1, (int)SendMailRuleType.Ios); } else if (req.RuleType == (int)SendMailRuleType.Android) { GmSendMailWithRuleToAll(req.Mail, req.RuleParam1, (int)SendMailRuleType.Android); } else { GmSendMailWithRuleToUidList(req); } TraceLog.Debug("MailSvc.GmSendMailWithRule end"); var res = new SSSendMailWithRuleRes(); res.Ret = 0; res.Mail = req.Mail; res.RuleType = req.RuleType; res.RuleParam1 = req.RuleParam1; res.TargetUid.SetString(req.TargetUid.ToString()); res.Seq = req.Seq; res.StrParam1 = req.StrParam1; WorldServerUtils.GetPacketSender().SendToServerByID(remoteAppID, (int)SSGameMsgID.SendMailWithRuleRes, ref res, 0); } public static void GmSendMailWithRuleToUidList(SSSendMailWithRule req) { string[] uidsplit = req.TargetUid.ToString().Split('|'); List uids = new List(); var playertable = WorldServerUtils.GetPlayerTable().m_playerTable; for (int i = 0; i < uidsplit.Length; i++) { long uidparse = 0; if (true == long.TryParse(uidsplit[i], out uidparse)) { if (uidparse > 0) { if (req.Mail.Realmlist.Count != 0) { var player = playertable.First(w => w.Key == uidparse); //玩家所在服务器不在邮件指定服务器中 if (!req.Mail.Realmlist.Contains(player.Value.RealmID)) { continue; } } uids.Add(uidparse); } } } DBMail mail = req.Mail; foreach (var uid in uids) { mail.Uid = uid; SendMail(req.Mail); } } public static void GmSendMailWithRuleToAll(DBMail mail, long durationMinute, int type) { WorldServerData serverdata = WorldServerUtils.GetWorldServerData(); serverdata.SendMailWithRuleVersionSeq++; SendMailWithRuleRecord record = new SendMailWithRuleRecord(); record.Mail = mail; record.EndTime = WorldServerUtils.GetTimeSecond() + durationMinute * 60; record.SendMailRuleType = type; record.VersionSeq = serverdata.SendMailWithRuleVersionSeq; serverdata.m_sendMailWithRuleList.Add(record); TraceLog.Debug("MailSvc.GmSendMailWithRuleToAll add record type {0} endTime {1} versionSeq {2}" , record.SendMailRuleType, record.EndTime, record.VersionSeq); var playertable = WorldServerUtils.GetPlayerTable().m_playerTable; foreach (var playerOnWorld in playertable.Values) { if(playerOnWorld.Lang.ToLower() == mail.Language.GetString().ToLower()) { continue; } if (playerOnWorld.GameServerID == 0) { continue; } if (playerOnWorld.IsOnline == false) { continue; } if (mail.Realmlist.Count != 0 && !mail.Realmlist.Contains(playerOnWorld.RealmID)) { continue; } CheckAndSendMailWithRule(playerOnWorld); } } public static void TickSendMailWithRule(long nowSecond) { foreach (var record in WorldServerUtils.GetWorldServerData().m_sendMailWithRuleList) { //超时的删除,一次一条足够了,这个列表不会有很多 if (record.EndTime > 0 && nowSecond > record.EndTime) { TraceLog.Debug("MailSvc.TickSendMailWithRule record type {0} endTime {1} versionSeq {2} timeout, delete it" , record.SendMailRuleType, record.EndTime, record.VersionSeq); WorldServerUtils.GetWorldServerData().m_sendMailWithRuleList.Remove(record); return; } //是否需要发邮件呢?,这个不要tick触发,效率低 } } public static bool IsNeedSendMailToPlayer(PlayerInfoWorld playerInfo, WorldServerData data, SendMailWithRuleRecord record) { int playerSendMailWithRuleVersionSeq = 0; if (data.m_sendMailWithRulePlayerVersion.TryGetValue(playerInfo.UserID, out playerSendMailWithRuleVersionSeq) == false) { data.m_sendMailWithRulePlayerVersion.Add(playerInfo.UserID, 0); playerSendMailWithRuleVersionSeq = 0; } //已经发过了 if (record.VersionSeq <= playerSendMailWithRuleVersionSeq) { return false; } //玩家不在邮件指定区服中 if (record.Mail.Realmlist.Count != 0 && !record.Mail.Realmlist.Contains(playerInfo.RealmID)) { return false; } if (record.SendMailRuleType == (int)SendMailRuleType.All) { return true; } if (record.SendMailRuleType == (int)SendMailRuleType.Android && playerInfo.accountInfo.PlatformType == 1) { return true; } if (record.SendMailRuleType == (int)SendMailRuleType.Ios && playerInfo.accountInfo.PlatformType == 2) { return true; } return false; } public static void CheckAndSendMailWithRule(PlayerInfoWorld playerInfo) { //TraceLog.Debug("MailSvc.CheckAndSendMailWithRule uid {0} begin", playerInfo.UserID); if (playerInfo == null) { return; } if (playerInfo.IsOnline == false) { return; } var data = WorldServerUtils.GetWorldServerData(); foreach (var record in data.m_sendMailWithRuleList) { if (IsNeedSendMailToPlayer(playerInfo, data, record) == false) { continue; } data.m_sendMailWithRulePlayerVersion[playerInfo.UserID] = record.VersionSeq; //playerInfo.SendMailWithRuleVersionSeq = record.VersionSeq; DBMail mail = record.Mail; mail.Uid = playerInfo.UserID; SendMail(mail); TraceLog.Debug("MailSvc.CheckAndSendMailWithRule mailId {0} uid {1}", mail.MailID, mail.Uid); } } } }