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.
 
 
 
 
 
 

1255 lines
50 KiB

using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using Sog;
using Sog.Log;
using ProtoCSStruct;
namespace Game
{
public class MailHandler : BasePacketHandler
{
public override int GetServiceType()
{
return GameServiceType.MailHandler;
}
//销毁的时候置空
public override void Dispose()
{
}
public MailHandler()
{
}
public override void HandlerClientPacket(PlayerSession playerSession, StructPacket packet)
{
PlayerOnGame player = playerSession.Player;
if (player == null)
{
TraceLog.Error("MailHandler.HandlerClientPacket can not find PlayerOnGame sessionid {0}", playerSession.SessionID);
return;
}
switch (packet.MsgID)
{
case (int)CSGameMsgID.QueryMailReq:
OnCliQueryMailReq(player, packet);
break;
case (int)CSGameMsgID.MailOpReq:
OnCliMailOpReq(player, packet);
break;
case (int)CSGameMsgID.MailSendToPlayerReq:
OnCliSendMailToPlayerReq(player, packet);
break;
default:
break;
}
}
public override void HandlerServerPacket(uint serverID, StructPacket packet)
{
switch (packet.MsgID)
{
case (int)SSGameMsgID.QueryMailRes:
OnSvrQueryMailRes(serverID, packet);
break;
case (int)SSGameMsgID.MailOpRes:
OnSvrMailOpRes(serverID, packet);
break;
case (int)CSGameMsgID.MailSendToPlayerRes:
OnSvrMailSendToPlayerRes(serverID, packet);
break;
case (int)SSGameMsgID.OperationMailDeleteReq:
OnOperationDeleteMail(serverID, packet);
break;
default:
break;
}
}
private void OnCliQueryMailReq(PlayerOnGame player, StructPacket packet)
{
if (player.DBMailDataLoadedTime != 0)
{
player.Trace("MailHandler.OnCliQueryMailReq uid {0} mail data already in memory", player.UserID);
long nowTime = GameServerUtils.GetTimeSecond();
bool needDelMail = false;
List<long> list = new List<long>();
ref CSQueryMailRes res = ref CSStructPool<CSQueryMailRes>.Instance.GetObjRef();
for (int i = 0; i < player.MailInfo.Count; i++)
{
ref var mail = ref player.MailInfo[i];
if (mail.ExpirationTime > 0 && mail.ExpirationTime <= nowTime)
{
//删除过期的邮件(缓存)
list.Add(mail.MailID);
needDelMail = true;
continue;
}
if (mail.DeleteTime > 0)
{
continue;
}
res.MailList.Add(ref mail);
}
SendToPlayer(player, (int)CSGameMsgID.QueryMailRes, ref res);
//删除过期邮件
if (needDelMail)
{
DBMail mail = new DBMail();
mail.Uid = player.UserID;
MailSender.SendMailOpReqToDB(0, MailOpType.AllDelete, ref mail, list);
}
return;
}
player.Trace("MailHandler.OnCliQueryMailReq uid {0} no mail data already in memory, query from db", player.UserID);
MailSvc.QueryRoleMail(player);
}
private void OnSvrQueryMailRes(uint serverID, StructPacket packet)
{
ref SSQueryMailRes ssres = ref packet.GetMessage<SSQueryMailRes>();
PlayerOnGame player = GameServerUtils.GetPlayerTableOp().GetPlayerByUid(ssres.Uid);
if (player == null)
{
player.Error("MailHandler.OnSvrQueryMailRes no player object uid {0}", ssres.Uid);
return;
}
bool loadMailDataFirst = false;
if (player.DBMailDataLoadedTime == 0)
{
player.DBMailDataLoadedTime = GameServerUtils.GetTimeSecond();
loadMailDataFirst = true;
}
player.MailInfo.Clear();
player.MailInfo.CopyFrom(ref ssres.MailList);
player.Trace("MailHandler.OnSvrQueryMailRes player uid {0} have mail count {1}, LastVersionUpdateCompensate {2}"
, player.UserID, player.MailInfo.Count, player.RoleData.OtherData.LastVersionUpdateCompensate);
MailSvc.ProcessSpecialMailOnQueryRes(player);
//通知一下客户端
ref CSQueryMailRes res = ref CSStructPool<CSQueryMailRes>.Instance.GetObjRef();
res.MailList.CopyFrom(ref player.MailInfo);
SendToPlayer(player, (int)CSGameMsgID.QueryMailRes, ref res);
if (loadMailDataFirst)
{
//上次领取操作未完成
if (player.RoleData.MailOp.GetItemMailID != 0)
{
player.Error("MailHandler.OnSvrQueryMailRes last getItem op no finished, mailid {0} uid {1} check it ..."
, player.RoleData.MailOp.GetItemMailID, player.UserID);
int mailIndex = MailSvc.GetMailIndexFromPlayer(player, player.RoleData.MailOp.GetItemMailID);
if (mailIndex != -1)
{
ref DBMail mail = ref MailSvc.GetMailByIndex(player, mailIndex);
if (mail.GetItemTime != 0)
{
player.Error("MailHandler.OnSvrQueryMailRes mail getitem success in db, so get item to palyer now.");
OnGetMailItemSuccessAddItemToPlayer(player, ref mail,MailOpType.GetItem);
}
else
{
player.Error("MailHandler.OnSvrQueryMailRes mail getitem not finish in db, so resend request");
MailSender.SendMailOpReqToDB(player.UserID, MailOpType.GetItem, ref mail);
}
}
else
{
player.Error("MailHandler.OnSvrQueryMailRes mail getitem not finish in db, but mail not exist now !skip");
player.RoleData.MailOp.GetItemMailID = 0; //算了
player.MakeDirty();
}
}
//放到tick里去,这样发不停服版本可以支持
//VersionUpdateCompensateSvc.TryCompensatePlayerAfterGetMailData(player);
}
//MailSvc.ProcessSpecialMailOnQueryRes(player);
}
private void OnCliMailOpReq(PlayerOnGame player, StructPacket packet)
{
ref CSMailOpReq req = ref packet.GetMessage<CSMailOpReq>();
//if (req.Mail.MailID == 0 || player.DBMailDataLoadedTime == 0)
//{
// //外挂
// player.Error("OnCliMailOpReq uid {0} no maildata", player.UserID);
// return;
//}
//领取附件
if (req.OpType == (int)MailOpType.GetItem)
{
if (req.MailID == 0)
{
player.Error("OnCliMailOpReq uid {0} mailid = 0, invalid", player.UserID);
return;
}
int mailIndex = MailSvc.GetMailIndexFromPlayer(player, req.MailID);
if (mailIndex == -1)
{
AckPlayerMailOpError(player, ref req, (int)CSErrCode.MailNotExist);
return;
}
ref DBMail mail = ref MailSvc.GetMailByIndex(player, mailIndex);
if ( mail.AddGoods.Count == 0)
{
//外挂?没附件领个毛
player.Error("OnCliMailOpReq uid {0} no item in mail", player.UserID);
return;
}
//已经领取过了
if (mail.GetItemTime != 0)
{
AckPlayerMailOpError(player, ref req, (int)CSErrCode.MailAlreadyGot);
return;
}
//上次领取操作未完成
if (player.RoleData.MailOp.GetItemMailID != 0)
{
AckPlayerMailOpError(player, ref req, (int)CSErrCode.MailOpNotFinish);
return;
}
//未达到领取版本条件
if (AppVersion.ToIntVersion(mail.ApkVersion.GetString()) > AppVersion.ToIntVersion(player.apkVersion))
{
AckPlayerMailOpError(player, ref req, (int)CSErrCode.MailConditionNotFinish);
return;
}
//检测邮件是否有领取限制
UnifyOp bagOp = new UnifyOp(player, BillChangeItemReason.GetItemMail, mail.MailType.ToString());
bagOp.InitGoodTypeLimit(player); //初始化类型限制
for (int i = 0; i < mail.AddGoods.Count; i++)
{
if (mail.AddGoods[i].Type > 0 && !string.IsNullOrEmpty(mail.AddGoods[i].Id.ToString()) && mail.AddGoods[i].Value > 0)
{
bagOp.AddGoods(mail.AddGoods[i].Type, mail.AddGoods[i].Id.ToString(), mail.AddGoods[i].Value);
bagOp.ChgGoodTypeLimit(mail.AddGoods[i].Type, mail.AddGoods[i].Value); //增加类型限制
}
}
CSErrCode code = bagOp.CheckOp();
if (code != CSErrCode.None)
{
AckPlayerMailOpError(player, ref req, (int)code);
return;
}
code = bagOp.CheckGoodTypeLimit(player);//进行类型限制检测
if (code != CSErrCode.None)
{
AckPlayerMailOpError(player, ref req, (int)code);
return;
}
//开始领取操作,先设置标记
player.RoleData.MailOp.GetItemMailID = mail.MailID;
player.MakeDirty();
player.Trace("MailHandler.OnCliMailOpReq begin get item from mail {0} uid {1}", mail.MailID, player.UserID);
MailSender.SendMailOpReqToDB(player.UserID, MailOpType.GetItem, ref mail);
}
else if (req.OpType == (int)MailOpType.Delete)
{
if (req.MailID == 0)
{
player.Error("OnCliMailOpReq uid {0} mailid = 0, invalid", player.UserID);
return;
}
int mailIndex = MailSvc.GetMailIndexFromPlayer(player, req.MailID);
if (mailIndex == -1)
{
AckPlayerMailOpError(player, ref req, (int)CSErrCode.MailNotExist);
return;
}
ref DBMail mail = ref MailSvc.GetMailByIndex(player, mailIndex);
player.Trace("MailHandler.OnCliMailOpReq begin delete mail {0} uid {1}", mail.MailID, player.UserID);
MailSender.SendMailOpReqToDB(player.UserID, MailOpType.Delete, ref mail);
}
else if (req.OpType == (int)MailOpType.GetItemDel)
{
if (req.MailID == 0)
{
player.Error("OnCliMailOpReq uid {0} mailid = 0 optype {1}, invalid", player.UserID, req.OpType);
return;
}
int mailIndex = MailSvc.GetMailIndexFromPlayer(player, req.MailID);
if (mailIndex == -1)
{
AckPlayerMailOpError(player, ref req, (int)CSErrCode.MailNotExist);
return;
}
ref DBMail mail = ref MailSvc.GetMailByIndex(player, mailIndex);
if (mail.AddGoods.Count == 0)
{
//外挂?没附件领个毛
player.Error("OnCliMailOpReq uid {0} optype {1} no item in mail", player.UserID, req.OpType);
return;
}
//已经领取过了
if (mail.GetItemTime != 0)
{
AckPlayerMailOpError(player, ref req, (int)CSErrCode.MailAlreadyGot);
return;
}
//上次领取操作未完成
if (player.RoleData.MailOp.GetItemMailID != 0)
{
AckPlayerMailOpError(player, ref req, (int)CSErrCode.MailOpNotFinish);
return;
}
//未达到领取版本条件
if (AppVersion.ToIntVersion(mail.ApkVersion.GetString()) > AppVersion.ToIntVersion(player.apkVersion))
{
AckPlayerMailOpError(player, ref req, (int)CSErrCode.MailConditionNotFinish);
return;
}
//开始领取操作,先设置标记
player.RoleData.MailOp.GetItemMailID = mail.MailID;
player.MakeDirty();
player.Trace("MailHandler.OnCliMailOpReq begin get item & del from mail {0} uid {1}", mail.MailID, player.UserID);
MailSender.SendMailOpReqToDB(player.UserID, MailOpType.GetItemDel, ref mail);
}
else if (req.OpType == (int)MailOpType.Read)
{
if (req.MailID == 0)
{
player.Error("OnCliMailOpReq uid {0} mailid = 0, invalid", player.UserID);
return;
}
int mailIndex = MailSvc.GetMailIndexFromPlayer(player, req.MailID);
if (mailIndex == -1)
{
AckPlayerMailOpError(player, ref req, (int)CSErrCode.MailNotExist);
return;
}
ref DBMail mail = ref MailSvc.GetMailByIndex(player, mailIndex);
//已经读了
if (mail.Status != 0)
{
AckPlayerMailOp(player, (int) MailOpType.Read, ref mail);
return;
}
player.Trace("MailHandler.OnCliMailOpReq begin Read mail {0} uid {1}", mail.MailID, player.UserID);
MailSender.SendMailOpReqToDB(player.UserID, MailOpType.Read, ref mail);
}
else if (req.OpType == (int)MailOpType.AllDelete)
{
List<long> list = new List<long>();
for (int i = 0; i < player.MailInfo.Count; i++)
{
int AddGoodsCount = 0;
ref var one = ref player.MailInfo[i];
for (int k = 0; k < one.AddGoods.Count; k++)
{
if ((one.AddGoods[k].Type > 0 && !string.IsNullOrEmpty(one.AddGoods[k].Id.GetString())) && one.AddGoods[k].Value > 0)
{
AddGoodsCount++;
}
}
if (one.Status > 0 || one.GetItemTime > 0)
{
if (one.GetItemTime > 0)
{
list.Add(one.MailID);
}
}
}
DBMail mail = new DBMail();
mail.Uid = player.UserID;
//player.MakeDirty();
//player.Trace("MailHandler.OnCliMailOpReq begin Read mail {0} uid {1}", mail.MailID, player.UserID);
MailSender.SendMailOpReqToDB(player.UserID, MailOpType.AllDelete, ref mail, list);
}
else if (req.OpType == (int)MailOpType.AllGetItem)
{
UnifyOp bagAllOp = new UnifyOp(player, BillChangeItemReason.GetItemMail, "");
bagAllOp.InitGoodTypeLimit(player);
List<long> list = new List<long>();
for (int i = 0; i < player.MailInfo.Count; i++)
{
int AddCurrencyCount = 0;
int AddGoodsCount = 0;
ref var one = ref player.MailInfo[i];
if(one.GetItemTime > 0)
{
continue;
}
//未达到领取版本条件
if (AppVersion.ToIntVersion(one.ApkVersion.GetString()) > AppVersion.ToIntVersion(player.apkVersion))
{
continue;
}
//检测邮件是否有领取限制
UnifyOp bagOp = new UnifyOp(player, BillChangeItemReason.GetItemMail, one.MailType.ToString());
for (int k = 0; k < one.AddGoods.Count; k++)
{
if ((one.AddGoods[k].Type > 0 || !string.IsNullOrEmpty(one.AddGoods[k].Id.GetString())) && one.AddGoods[k].Value > 0)
{
bagOp.AddGoods(one.AddGoods[k].Type, one.AddGoods[k].Id.ToString(), one.AddGoods[k].Value);
bagAllOp.ChgGoodTypeLimit(one.AddGoods[k].Type, one.AddGoods[k].Value); //增加类型限制
AddGoodsCount++;
}
}
if (one.GetItemTime == 0 && (AddCurrencyCount != 0 || AddGoodsCount != 0))
{
if(AddGoodsCount != 0)
{
CSErrCode code = bagOp.CheckOp();
if (code != CSErrCode.None)
{
continue;
}
code = bagAllOp.CheckGoodTypeLimit(player);//进行类型限制检测
if (code != CSErrCode.None)
{
for (int k = 0; k < one.AddGoods.Count; k++) //将本次的限制退回
{
if ((one.AddGoods[k].Type > 0 || !string.IsNullOrEmpty(one.AddGoods[k].Id.GetString())) && one.AddGoods[k].Value > 0)
{
bagAllOp.ChgGoodTypeLimit(one.AddGoods[k].Type, one.AddGoods[k].Value * -1); //减少类型限制
}
}
continue;
}
}
list.Add(one.MailID);
}
}
DBMail mail = new DBMail();
mail.Uid = player.UserID;
//player.MakeDirty();
//player.Trace("MailHandler.OnCliMailOpReq begin Read mail {0} uid {1}", mail.MailID, player.UserID);
MailSender.SendMailOpReqToDB(player.UserID, MailOpType.AllGetItem, ref mail, list);
}
else
{
player.Error("OnCliMailOpReq uid {0} unsupport op type {1}", player.UserID, req.OpType);
return;
}
}
private void AckPlayerMailOpError(PlayerOnGame player, ref CSMailOpReq req, int iErrorCode)
{
player.Trace("MailHandler.AckPlayerMailOpError uid {0} opType {1} error {2}"
, player.UserID, req.OpType, iErrorCode);
CSMailOpRes res = new CSMailOpRes();
res.Ret = iErrorCode;
res.OpType = req.OpType;
res.Mail.MailID = req.MailID;
SendToPlayer(player, (int)CSGameMsgID.MailOpRes, ref res);
}
private void AckPlayerMailOpError(PlayerOnGame player, ref SSMailOpRes ssres, int iErrorCode, List<long> list = null)
{
player.Trace("MailHandler.AckPlayerMailOpError uid {0} opType {1} error {2}"
, player.UserID, ssres.OpType, iErrorCode);
if(ssres.ClientOpUid == 0 )
{//只有客户端发送的才返回给客户端
return;
}
CSMailOpRes res = new CSMailOpRes();
res.Ret = iErrorCode;
res.OpType = ssres.OpType;
res.Mail = ssres.Mail;
// 目前只有AllDelete会传入list, 即一键删除才会填ListMId
if(list != null && list.Count > 0)
{
for(int i = 0; i < list.Count; i++)
{
res.ListMId.Add(list[i]);
}
}
// if(res.OpType == (int)MailOpType.AllDelete || res.OpType == (int)MailOpType.AllGetItem)
// {
// if(list == null && list.Count == 0)
// {
//
// }
// }
SendToPlayer(player, (int)CSGameMsgID.MailOpRes, ref res);
}
private void AckPlayerMailOp(PlayerOnGame player, int opType, ref DBMail mail)
{
player.Trace("MailHandler.AckPlayerMailOp uid {0} opType {1} mailId {2}"
, player.UserID, opType, mail.MailID);
var res = new CSMailOpRes();
res.OpType = opType;
res.Mail = mail;
SendToPlayer(player, (int)CSGameMsgID.MailOpRes, ref res);
}
private void OnSvrMailOpRes(uint serverID, StructPacket packet)
{
ref SSMailOpRes ssres = ref packet.GetMessage<SSMailOpRes>();
//最开始一定要设置这个,删除超时重发
if (ssres.UniqueID != 0)
{
WaitAckStructRequestSender.Instance.OnReceiveSuccess(ssres.UniqueID);
CommBillLogUtils.LogMailOpRet(ssres.ClientOpUid, ref ssres.Mail, ssres.OpType, ssres.Ret);
}
if (ssres.ClientOpUid == 0)
{
TraceLog.Debug("MailHandler.OnSvrMailOpRes no clientOpUid, skip");
return;
}
//如果2个不相等,不往下处理了
if (ssres.ClientOpUid != ssres.Mail.Uid)
{
TraceLog.Debug("MailHandler.OnSvrMailOpRes clientOpUid {0} != mail.uid {1}, skip"
, ssres.ClientOpUid, ssres.Mail.Uid);
return;
}
//不在线也正常
PlayerOnGame player = GameServerUtils.GetPlayerTableOp().GetPlayerByUid(ssres.Mail.Uid);
if (player == null)
{
TraceLog.Debug("MailHandler.OnSvrMailOpRes no player object uid {0}"
, ssres.Mail.Uid);
return;
}
if (player.DBMailDataLoadedTime == 0)
{
player.Error("MailHandler.OnSvrMailOpRes no player mailinfo uid {0}"
, ssres.Mail.Uid);
return;
}
if (ssres.DelFirst.Count > 0)
{
CSMailChgNotify chgNotify = new CSMailChgNotify();
for (int i = 0; i < ssres.DelFirst.Count; i++)
{
MailSvc.DeleteMailMemory(player, ssres.DelFirst[i]);
chgNotify.DelMailId.Add(ssres.DelFirst[i]);
}
if (chgNotify.DelMailId.Count > 0)
{
player.SendToClient<CSMailChgNotify>((int)CSGameMsgID.MailChgNotify, ref chgNotify);
}
}
//删除邮件只要回包一定成功,数据库不存在也算删除成功
if (ssres.OpType == (int)MailOpType.Delete)
{
if (ssres.Ret != 0)
{
AckPlayerMailOpError(player, ref ssres, -1);
return;
}
MailSvc.DeleteMailMemory(player, ssres.Mail.MailID);
//成功
AckPlayerMailOpError(player, ref ssres, 0);
return;
}
else if(ssres.OpType == (int)MailOpType.AllDelete)
{
if (ssres.Ret != 0)
{
AckPlayerMailOpError(player, ref ssres, -1);
return;
}
List<long> list = new List<long>();
for (int i = 0; i < player.MailInfo.Count; i++)
{
ref var one = ref player.MailInfo[i];
if (!ssres.ListMId.Contains(one.MailID))
{
continue;
}
int AddGoodsCount = 0;
for (int k = 0; k < one.AddGoods.Count; k++)
{
if ((one.AddGoods[k].Type > 0 || !string.IsNullOrEmpty(one.AddGoods[k].Id.GetString())) && one.AddGoods[k].Value > 0)
{
AddGoodsCount++;
}
}
if (one.Status > 0 || one.GetItemTime > 0)
{
if (one.GetItemTime > 0)
{
list.Add(one.MailID);
}
else if ( AddGoodsCount == 0)
{
list.Add(one.MailID);
}
}
}
MailSvc.DeleteAllMailMemory(player, list);
//成功
AckPlayerMailOpError(player, ref ssres, 0, list);
return;
}
else if (ssres.OpType == (int)MailOpType.GetItem)
{
//已经取过了也算成功,重复性保证在player
if (ssres.Ret == 220202 || ssres.Ret == 0)
{
int mailIndex = MailSvc.GetMailIndexFromPlayer(player, ssres.Mail.MailID);
if (mailIndex == -1)
{
player.Error("MailHandler.OnSvrMailOpRes getitem mail uid {0}, mail {1} no mail in memory!", ssres.ClientOpUid, ssres.Mail.MailID);
return;
}
ref DBMail mail = ref MailSvc.GetMailByIndex(player, mailIndex);
if (mail.GetItemTime != 0)
{
player.Error("MailHandler.OnSvrMailOpRes getitem mail uid {0}, mail {1} mail in memory already getitem at time {2}!"
, ssres.ClientOpUid, ssres.Mail.MailID, mail.GetItemTime);
AckPlayerMailOpError(player, ref ssres, (int)CSErrCode.MailAlreadyGot);
return;
}
//设置玩家身上的mail数据的领取时间
mail.GetItemTime = GameServerUtils.GetTimeSecond();
//回档了,怎么办呢,这个需要在玩家第一次拉取角色数据的时候处理完成,这里我们不处理了,请再次发起请求
if (player.RoleData.MailOp.GetItemMailID != mail.MailID
&& player.RoleData.MailOp.GetItemMailID != 0)
{
player.Error("MailHandler.OnSvrMailOpRes getitem mail uid {0}, mail {1} != role.GetItemMailID {2}!"
, ssres.ClientOpUid, ssres.Mail.MailID, mail.GetItemTime);
return;
}
//已经领过了,亲
if (player.RoleData.MailOp.GetItemMailID == 0)
{
player.Error("MailHandler.OnSvrMailOpRes getitem mail uid {0}, mail {1} mail in memory already getitem at time {2}!"
, ssres.ClientOpUid, ssres.Mail.MailID, mail.GetItemTime);
AckPlayerMailOpError(player, ref ssres, (int)CSErrCode.MailAlreadyGot);
return;
}
OnGetMailItemSuccessAddItemToPlayer(player, ref mail, (MailOpType)ssres.OpType);
return;
}
}
else if (ssres.OpType == (int)MailOpType.Read)
{
//已经取过了也算成功,重复性保证在player
if (ssres.Ret == 220202 || ssres.Ret == 0)
{
int mailIndex = MailSvc.GetMailIndexFromPlayer(player, ssres.Mail.MailID);
if (mailIndex == -1)
{
player.Error("MailHandler.OnSvrMailOpRes getitem mail uid {0}, mail {1} no mail in memory!", ssres.ClientOpUid, ssres.Mail.MailID);
return;
}
ref DBMail mail = ref MailSvc.GetMailByIndex(player, mailIndex);
if (mail.Status != 0)
{
player.Error("MailHandler.OnSvrMailOpRes read mail uid {0}, mail {1} mail in memory already read!"
, ssres.ClientOpUid, ssres.Mail.MailID);
AckPlayerMailOpError(player, ref ssres, (int)CSErrCode.MailAlreadyGot);
return;
}
//设置玩家身上的mail数据的领取时间
mail.Status = 1;
if(ssres.Mail.GetItemTime > 0 && mail.GetItemTime == 0)
{
mail.GetItemTime = ssres.Mail.GetItemTime;
}
//成功
AckPlayerMailOpError(player, ref ssres, 0);
return;
}
}
else if (ssres.OpType == (int)MailOpType.Insert)
{
//已经存在
if (ssres.Ret == 220201 || ssres.Ret == 0)
{
MailSvc.InsertMailMemory(player, ref ssres.Mail);
//处理一下特殊邮件
MailSvc.ProcessSpecialMailOnQueryRes(player);
////成功
//if (ssres.Mail.MailType == (int)MailType.ArenaDefence)//竞技场攻击邮件就不通知客户端了
//{
// return;
//}
////成功
//if (ssres.Mail.MailType == (int)MailType.ArenaPeakPromotion)
//{
// return;
//}
AckPlayerMailOpError(player, ref ssres, 0);
return;
}
//这种情况呢
if (ssres.Ret != 0)
{
player.Error("MailHandler.OnSvrMailOpRes insert mail failed uid {0}, mail {1}"
, ssres.ClientOpUid, ssres.Mail.MailID);
return;
}
}
else if (ssres.OpType == (int)MailOpType.GetItemDel)
{
//已经取过了也算成功,重复性保证在player
if (ssres.Ret == 220202 || ssres.Ret == 0)
{
int mailIndex = MailSvc.GetMailIndexFromPlayer(player, ssres.Mail.MailID);
if (mailIndex == -1)
{
player.Error("MailHandler.OnSvrMailOpRes getitem mail uid {0}, mail {1} no mail in memory!", ssres.ClientOpUid, ssres.Mail.MailID);
return;
}
ref DBMail mail = ref MailSvc.GetMailByIndex(player, mailIndex);
if (mail.GetItemTime != 0)
{
player.Error("MailHandler.OnSvrMailOpRes getitem mail uid {0}, mail {1} mail in memory already getitem at time {2}!"
, ssres.ClientOpUid, ssres.Mail.MailID, mail.GetItemTime);
AckPlayerMailOpError(player, ref ssres, (int)CSErrCode.MailAlreadyGot);
return;
}
if (mail.DeleteTime != 0)
{
player.Error("MailHandler.OnSvrMailOpRes getitem mail uid {0}, mail {1} mail in memory already getitem at time {2}!"
, ssres.ClientOpUid, ssres.Mail.MailID, mail.GetItemTime);
AckPlayerMailOpError(player, ref ssres, (int)CSErrCode.MailAlreadyGot);
return;
}
//设置玩家身上的mail数据的领取时间
mail.GetItemTime = GameServerUtils.GetTimeSecond();
//回档了,怎么办呢,这个需要在玩家第一次拉取角色数据的时候处理完成,这里我们不处理了,请再次发起请求
if (player.RoleData.MailOp.GetItemMailID != mail.MailID
&& player.RoleData.MailOp.GetItemMailID != 0)
{
player.Error("MailHandler.OnSvrMailOpRes getitem mail uid {0}, mail {1} != role.GetItemMailID {2}!"
, ssres.ClientOpUid, ssres.Mail.MailID, mail.GetItemTime);
return;
}
//已经领过了,亲
if (player.RoleData.MailOp.GetItemMailID == 0)
{
player.Error("MailHandler.OnSvrMailOpRes getitem mail uid {0}, mail {1} mail in memory already getitem at time {2}!"
, ssres.ClientOpUid, ssres.Mail.MailID, mail.GetItemTime);
AckPlayerMailOpError(player, ref ssres, (int)CSErrCode.MailAlreadyGot);
return;
}
OnGetMailItemSuccessAddItemToPlayer(player, ref mail, (MailOpType)ssres.OpType);
MailSvc.DeleteMailMemory(player, ssres.Mail.MailID);
return;
}
}
else if (ssres.OpType == (int)MailOpType.AllGetItem)
{
//已经取过了也算成功,重复性保证在player
if (ssres.Ret == 220202 || ssres.Ret == 0)
{
List<long> list = new List<long>();
for (int i = 0; i < ssres.ListMId.Count; i++)
{
int mailIndex = MailSvc.GetMailIndexFromPlayer(player, ssres.ListMId[i]);
if (mailIndex == -1)
{
player.Error("MailHandler.OnSvrMailOpRes getitem mail uid {0}, mail {1} no mail in memory!", ssres.ClientOpUid, ssres.Mail.MailID);
return;
}
ref DBMail mail = ref MailSvc.GetMailByIndex(player, mailIndex);
if (mail.GetItemTime != 0)
{
player.Error("MailHandler.OnSvrMailOpRes getitem mail uid {0}, mail {1} mail in memory already getitem at time {2}!"
, ssres.ClientOpUid, ssres.Mail.MailID, mail.GetItemTime);
AckPlayerMailOpError(player, ref ssres, (int)CSErrCode.MailAlreadyGot);
return;
}
//设置玩家身上的mail数据的领取时间
mail.GetItemTime = GameServerUtils.GetTimeSecond();
if(mail.AddGoods.Count > 0)
{
mail.Status = 1;
}
list.Add(ssres.ListMId[i]);
}
OnGetAllMailItemSuccessAddItemToPlayer(player, ref ssres.Mail, (MailOpType)ssres.OpType, list);
return;
}
else if (ssres.OpType == (int)MailOpType.Update)
{
//
}
else
{
AckPlayerMailOpError(player, ref ssres, (int)CSErrCode.MailAlreadyGot);
}
}
}
private void OnGetAllMailItemSuccessAddItemToPlayer(PlayerOnGame player, ref DBMail one,
MailOpType opType = MailOpType.None, List<long> list = null)
{
if (list == null || list.Count == 0)
{
return;
}
player.MakeDirty();
CSMailOpRes res = new CSMailOpRes();
res.Ret = 0;
res.OpType = (int)opType;
res.Mail = one;
int vipExp = 0;
//领取物品
UnifyOp bagOp = new UnifyOp(player, BillChangeItemReason.GetItemMail, one.MailType.ToString());
List<int> titleList = new List<int>();
for (int k = 0; k < list.Count; k++)
{
int mailIndex = MailSvc.GetMailIndexFromPlayer(player, list[k]);
if (mailIndex == -1)
{
TraceLog.Error("OnGetAllMailItemSuccessAddItemToPlayer error,no Mail {0}", list[k]);
return;
}
ref DBMail mail = ref MailSvc.GetMailByIndex(player, mailIndex);
res.ListMId.Add(mail.MailID);
for (int i = 0; i < mail.AddGoods.Count; i++)
{
if (mail.AddGoods[i].Type > 0 && !string.IsNullOrEmpty(mail.AddGoods[i].Id.GetString()) && mail.AddGoods[i].Value > 0)
{
{
bagOp.AddGoods(mail.AddGoods[i].Type, mail.AddGoods[i].Id.ToString(), mail.AddGoods[i].Value);
}
}
}
if ((k + 1) % 30 == 0 && list.Count > (k + 1))
{
CSErrCode tempRet = bagOp.DoOp();
if (tempRet != CSErrCode.None)
{
player.Error("MailHandler.OnGetMailItemSuccessAddItemToPlayer getitem uid {0} bagOp.DoOp failed ret {1}", player.UserID, tempRet);
}
bagOp = new UnifyOp(player, BillChangeItemReason.GetItemMail, one.MailType.ToString());
}
}
CSErrCode iRet = bagOp.DoOp(true, true, true);
if (iRet != 0)
{
player.Error("MailHandler.OnGetMailItemSuccessAddItemToPlayer getitem uid {0} bagOp.DoOp failed ret {1}"
, player.UserID, iRet);
return;
}
player.Trace("MailHandler.OnGetMailItemSuccessAddItemToPlayer uid {0} get Allitem success"
, player.UserID);
SendToPlayer(player, (int)CSGameMsgID.MailOpRes, ref res);
}
private void OnGetMailItemSuccessAddItemToPlayer(PlayerOnGame player, ref DBMail mail, MailOpType opType = MailOpType.None)
{
player.RoleData.MailOp.GetItemMailID = 0;
player.MakeDirty();
int vipExp = 0;
//领取物品
UnifyOp bagOp = new UnifyOp(player, BillChangeItemReason.GetItemMail, mail.MailType.ToString());
for (int i = 0; i < mail.AddGoods.Count; i++)
{
if (mail.AddGoods[i].Type > 0 && !string.IsNullOrEmpty(mail.AddGoods[i].Id.GetString()) && mail.AddGoods[i].Value > 0)
{
bagOp.AddGoods(mail.AddGoods[i].Type, mail.AddGoods[i].Id.ToString(), mail.AddGoods[i].Value);
//if (mail.AddGoods[i].Type == (int)CurrencyType.VipExp)
//{
// vipExp += mail.AddGoods[i].Value;
//}
}
}
CSErrCode iRet = bagOp.DoOp(true, true, true);
if (iRet != 0)
{
player.Error("MailHandler.OnGetMailItemSuccessAddItemToPlayer getitem uid {0} mail {1} bagOp.DoOp failed ret {2}"
, player.UserID, mail.MailID, iRet);
return;
}
player.Trace("MailHandler.OnGetMailItemSuccessAddItemToPlayer uid {0} mail {1} get item success"
, player.UserID, mail.MailID);
CSMailOpRes res = new CSMailOpRes();
res.Ret = 0;
res.OpType = (int)opType;
res.Mail = mail;
SendToPlayer(player, (int)CSGameMsgID.MailOpRes, ref res);
}
private int CheckCliCanSendMailToPlayer(PlayerOnGame player, long sendChip, int shopItemId,out long costChip, out long tax, out int costDiamond ,out string sendItemId)
{
costChip = 0;
tax = 0;
costDiamond = 0;
sendItemId = "";
if(sendChip == 0 && shopItemId == 0)
{
player.Error("MailHandler.CheckCliCanSendMailToPlayer uid {0} chip {1} shopItemId {2}"
, player.UserID, sendChip, shopItemId);
return -1;
}
if (sendChip > 0)
{
int minChip = 0; // CommParamDescUtils.GetCommParam().sendMailToPlayerMinChip;
if (sendChip < minChip)
{
player.Error("MailHandler.CheckCliCanSendMailToPlayer uid {0} chip {1} invalid minChip {2}"
, player.UserID, sendChip, minChip);
return -1;
}
}
//税率写死了10%
tax = sendChip * 0; //CommParamDescUtils.GetCommParam().sendMailToPlayerChipTax / 100;
if (tax < 1)
{
tax = 1;
}
//校验钱够不够
costChip = sendChip + tax;
if (shopItemId > 0)
{
}
//如果送钱的话送完钱后需要有剩余
long checkNeedChip = costChip;
if (sendChip > 0)
{
checkNeedChip += 0; // CommParamDescUtils.GetCommParam().sendMailToPlayerMinChipLeft;
}
if (checkNeedChip > player.GetGold())
{
player.Error("MailHandler.CheckCliCanSendMailToPlayer uid {0} not enought chip, cost {1} need {2}"
, player.UserID, costChip, checkNeedChip);
return -5;
}
if (costDiamond > player.GetDiamond())
{
player.Error("MailHandler.CheckCliCanSendMailToPlayer uid {0} not enought diamond, cost {1}"
, player.UserID, costDiamond);
return -6;
}
return 0;
}
private void OnCliSendMailToPlayerReq(PlayerOnGame player, StructPacket packet)
{
ref CSMailSendToPlayerReq req = ref packet.GetMessage<CSMailSendToPlayerReq>();
if (req.TargetUid == 0 || req.TargetUid == player.UserID)
{
player.Error("MailHandler.OnCliSendMailToPlayerReq uid {0} invalid targetuid {1}", player.UserID, req.TargetUid);
return;
}
CSMailSendToPlayerRes res = new CSMailSendToPlayerRes();
res.TargetUid = req.TargetUid;
res.Chip = req.Chip;
res.ShopItemId = req.ShopItemId;
long costChip;
long tax;
int costDiamond;
string sendItemId;
int ret = CheckCliCanSendMailToPlayer(player
, req.Chip
, req.ShopItemId
, out costChip
, out tax
, out costDiamond
, out sendItemId);
if (ret != 0)
{
player.Error("MailHandler.OnCliSendMailToPlayerReq uid {0} CheckCliCanSendMailToPlayer failed ret {1}"
, player.UserID, ret);
res.Ret = ret;
player.SendToClient((int)CSGameMsgID.MailSendToPlayerRes, ref res);
return;
}
player.Debug("MailHandler.OnCliSendMailToPlayerReq uid {0} send to world check,send chip {1}"
, player.UserID, req.Chip);
//发给world转去friend校验一下target是否是好友
GameServerUtils.GetPacketSender().SendToWorldServer<CSMailSendToPlayerReq>(packet, player.UserID);
return;
}
private void OnSvrMailSendToPlayerRes(uint serverID, StructPacket packet)
{
PlayerOnGame player = GameServerUtils.GetPlayerTableOp().GetPlayerByUid(packet.ObjectID);
if (player == null)
{
player.Error("MailHandler.OnSvrMailSendToPlayerRes no player object uid {0}", packet.ObjectID);
return;
}
ref CSMailSendToPlayerRes res = ref packet.GetMessage<CSMailSendToPlayerRes>();
if(res.Ret != 0)
{
player.Error("MailHandler.OnSvrMailSendToPlayerRes uid {0} world ack ret {1}", player.UserID, res.Ret);
player.SendToClient<CSMailSendToPlayerRes>(packet);
return;
}
long costChip;
long tax;
int costDiamond;
string sendItemId;
int ret = CheckCliCanSendMailToPlayer(player, res.Chip, res.ShopItemId
, out costChip
, out tax
, out costDiamond
, out sendItemId);
if (ret != 0)
{
player.Error("MailHandler.OnSvrMailSendToPlayerRes uid {0} CheckCliCanSendMailToPlayer failed ret {1}", player.UserID, ret);
res.Ret = ret;
player.SendToClient((int)CSGameMsgID.MailSendToPlayerRes, ref res);
return;
}
//扣chip
UnifyOp bagOp = new UnifyOp(player, BillChangeItemReason.SendMailToPlayer);
bagOp.CostGold(costChip);
bagOp.CostDiamond(costDiamond);
CSErrCode iRet = bagOp.DoOp();
if (iRet != 0)
{
player.Error("MailHandler.OnSvrMailSendToPlayerRes uid {0} bagOp.DoOp failed ret {1}", player.UserID, iRet);
return;
}
//发邮件
DBMail mail = new DBMail();
mail.Uid = res.TargetUid;
mail.MailType = (int)MailType.SendToPlayer;
// var currency = new IDValue64() {Id = (long) CurrencyType.Chip, Value = res.Chip};
//mail.AddCurrency.Add(ref currency);
mail.SendTime = GameServerUtils.GetTimeSecond();
mail.SenderUid = player.UserID;
mail.SenderName.SetString(player.GetNick());
mail.SenderIcon.SetString(player.GetIcon());
mail.Title = res.Title;
mail.Content = res.Content;
//送物品
if(string.IsNullOrEmpty(sendItemId))
{
var typeIdValue = new TypeIDValueString(){Type = (int)GoodsType.Items, Id = new FixedStructString64(sendItemId), Value = 1 };
mail.AddGoods.Add(ref typeIdValue);
}
MailSender.SendNewMailToPlayer(player.UserID, ref mail);
GameBillLogUtils.LogSendMailToPlayer(player.UserID, res.TargetUid, player.GetVipLevel(), res.Chip, tax);
/*这个不算,因为这个送钱是收税的,随便送
//统计数据变化操作
RoleStatChgOp statChgOp = new RoleStatChgOp(player);
statChgOp.AddIDDaily((int)CSRoleStatisticsID.GiveFriendChipCount, 1);
//可以不通知
statChgOp.NotifyClient();
*/
res.Ret = 0;
player.SendToClient((int)CSGameMsgID.MailSendToPlayerRes, ref res);
//通知好友聊天,好友送你钱了
SSFriendSomeOpNotifyChat notify = new SSFriendSomeOpNotifyChat();
notify.ChatType = (int)ChatType.FriendSendChip;
notify.Uid = res.TargetUid;
notify.FriendUid = player.UserID;
notify.Param1.SetString( res.Chip.ToString());
if (!string.IsNullOrEmpty(sendItemId) )
{
notify.Param2.SetString(sendItemId.ToString());
}
//ChatSvc.NotifyFriendSomeOpToChat(ref notify);
NotifyFriendSomeOpToChat(ref notify);
player.Debug("MailHandler.OnSvrMailSendToPlayerRes uid {0} send mail to targetuid {1} success with chip {2} tax {3}"
, player.UserID, res.TargetUid, res.Chip, tax);
}
public static void NotifyFriendSomeOpToChat(ref SSFriendSomeOpNotifyChat notify)
{
TraceLog.Trace("MailHandler.NotifyFriendSomeOpToChat player uid {0} friend uid {1} chatType {2} "
, notify.Uid, notify.FriendUid, notify.ChatType);
GameServerUtils.GetPacketSender().SendToWorldServer((int)SSGameMsgID.FriendSomeOpNotifyChat, ref notify, 0);
}
public static void OnOperationDeleteMail(uint serverID, StructPacket packet)
{
SSOperationDeleteMailReq sreq = packet.GetMessage<SSOperationDeleteMailReq>();
SSOperationDeleteMailRes res = new SSOperationDeleteMailRes();
res.Id = sreq.Id;
res.Uid = sreq.Uid;
res.Ret = 0;
PlayerOnGame player = GameServerUtils.GetPlayerTableOp().GetPlayerByUid(sreq.Uid);
DBMail mail = new DBMail();
mail.Uid = sreq.Uid;
mail.MailID = (uint)sreq.MailId;
if (player == null)
{
//离线处理
MailSender.SendMailOpReqToDB(0, MailOpType.Delete, ref mail);
TraceLog.Debug("MailHandler.OnOperationDeleteMail no player object uid {0}", sreq.Uid);
GameServerUtils.GetPacketSender().SendToWorldServer((int)SSGameMsgID.OperationMailDeleteRes, ref res, packet.ObjectID);
return;
}
int index = -1;
for (int i = 0; i < player.MailInfo.Count; i++)
{
ref var mailInfo = ref player.MailInfo[i];
if (mailInfo.MailID == sreq.MailId)
{
index = i;
break;
}
}
if (index < 0)
{
res.Ret = -1;//mail not found
GameServerUtils.GetPacketSender().SendToWorldServer((int)SSGameMsgID.OperationMailDeleteRes, ref res, packet.ObjectID);
return;
}
MailSender.SendMailOpReqToDB(sreq.Uid, MailOpType.Delete, ref mail);
GameServerUtils.GetPacketSender().SendToWorldServer((int)SSGameMsgID.OperationMailDeleteRes, ref res, packet.ObjectID);
}
}
}