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.
 
 
 
 
 
 

1598 lines
65 KiB

/*
Sog 游戏基础库
2016 by zouwei
*/
using System;
using System.Collections.Generic;
using Sog;
using ProtoCSStruct;
using LitJson;
namespace Game
{
// 支付消息
public class PayHandler : BasePacketHandler
{
public override int GetServiceType()
{
return GameServiceType.PayHandler;
}
//销毁的时候置空
public override void Dispose()
{
}
public override void HandlerClientPacket(PlayerSession playerSession, StructPacket packet)
{
switch (packet.MsgID)
{
case (int)CSGameMsgID.PayGoogleReq:
ProcessPayGoogleReq(playerSession, packet, false);
break;
case (int)CSGameMsgID.PayGoogleSuccessReq:
ProcessPayGoogleSuccessReq(playerSession, packet, false);
break;
case (int)CSGameMsgID.PayGetFreeItemReq:
ProcessPayGetFreeItemReq(playerSession, packet);
break;
case (int)CSGameMsgID.ClientTriggerItemArriveReq:
ProcessClientTriggerItemArriveReq(playerSession, packet);
break;
case (int)CSGameMsgID.PayItemStockInfoReq:
OnPayItemStockInfoReq(playerSession, packet);
break;
case (int)CSGameMsgID.CardGetDailyAwardReq:
MonthlyCardSvc.GetDailyReward(playerSession.Player, packet);
break;
case (int)CSGameMsgID.BattlePassAwardReq:
BattlePassSvc.Award(playerSession.Player, packet);
break;
case (int)CSGameMsgID.SignGetAwardReq:
SignSvc.Award(playerSession.Player, packet);
break;
case (int)CSGameMsgID.SignReSingReq:
SignSvc.ReSingDaily(playerSession.Player, packet);
break;
case (int)CSGameMsgID.FistPaymentAwardReq:
FistPaymentEvent.Award(playerSession.Player, packet);
break;
case (int)CSGameMsgID.FreeRewardReq:
FreeRewardSvc.OnFreeDayReq(playerSession.Player, packet);
break;
default:
TraceLog.Error("PayHandler.HandlerClientPacket msg {0} not handle", packet.MsgID);
break;
}
}
public override void HandlerServerPacket(uint serverID, StructPacket packet)
{
switch (packet.MsgID)
{
case (int)SSGameMsgID.PayGoogleRes:
ProcessPayGoogleRes(serverID, packet);
break;
case (int)SSGameMsgID.PayGoogleSuccessRes:
ProcessPayGoogleSuccessRes(serverID, packet);
break;
case (int)SSGameMsgID.PayDbAddDiamondStatusRes:
ProcessDBAddDiamondStatusRes(serverID, packet);
break;
case (int)SSGameMsgID.PayItemStockInfoRes:
OnPayItemStockInfoRes(serverID, packet);
break;
case (int)SSGameMsgID.NotifyItemStockInfo:
OnNotifyItemStockInfo(serverID, packet);
break;
case (int)SSGameMsgID.OperationFakepay:
ProcessFakePay(serverID, packet);
break;
default:
TraceLog.Error("PayHandler.HandlerServerPacket msg {0} not handle", packet.MsgID);
break;
}
}
public int ProcessPayGoogleReq(PlayerSession playerSession, StructPacket packet, bool gmTestPay)
{
ref CSPayGoogleReq payReq = ref packet.GetMessage<CSPayGoogleReq>();
//开启代币支付
//var tokenSwitch=CommParamDescMgr.Instance.AdTokenSwitch.int_val;
// if (tokenSwitch == 1)
// {
// payReq.PayChannel = PayChannel.GameToken;
// }
if (payReq.Uid != playerSession.UserID)
{
TraceLog.Error("PayHandler.ProcessPayGoogleReq invalid uid {0}", payReq.Uid);
return -1;
}
PlayerOnGame player = playerSession.Player;
if (player == null)
{
TraceLog.Error("PayHandler.ProcessPayGoogleReq no player object uid {0}", payReq.Uid);
return -1;
}
PayType payType = PlayerPayUtil.GetPlayerPayType(player);
PayDiamondDesc desc = PayCommSvc.GetPayDiamondDesc(payReq.ItemID);
string paymentId = PayCommSvc.GetPaymentId(desc);
if (string.IsNullOrEmpty(paymentId))
{
//判断是否是扣物品
if (desc.consumeItemId != "" && desc.consumeItemCount > 0)
{
}
else
{
player.Error("PayHandler.ProcessPayGoogleReq item {0} currency {1} money {2} no paymentId"
, desc.itemID, desc.currencyId, desc.currencyRes);
return -1;
}
}
// 检查下是否有未完成订单
int index = PlayerPayUtil.GetPaySuccLockIndex(player, desc.itemID);
if (index != -1)
{
ref var lockData = ref PlayerPayUtil.GetPaySuccLockByIndex(player, index);
// svr成功后可以直接删除
if (lockData.SvrSuccTime != 0)
{
player.Trace("PayHandler.ProcessPayGoogleReq itemId {0} unlock by svr succ", desc.itemID);
player.RoleData.PayData.PaySuccLock.RemoveAt(index);
}
// clt成功后最多锁定24小时
else if (lockData.CltSuccTime != 0 && GameServerUtils.GetTimeSecond() >= lockData.CltSuccTime + 86400)
{
player.Trace("PayHandler.ProcessPayGoogleReq itemId {0} unlock by timeout", desc.itemID);
player.RoleData.PayData.PaySuccLock.RemoveAt(index);
}
else
{
player.Trace("PayHandler.ProcessPayGoogleReq itemId {0} is lock, order {1} order3rd {2} not finish"
, desc.itemID, lockData.OrderId.GetString(), lockData.OrderId3rd.GetString());
CSPayGoogleRes res = new CSPayGoogleRes { Ret = (int)CSErrCode.PayItemOrderNotFinish, ItemID = payReq.ItemID };
player.SendToClient((int)CSGameMsgID.PayGoogleRes, ref res);
return -1;
}
}
// 有多笔成功订单没有加到背包
if (player.RoleData.PayData.PaySuccWaitAddRole.Count >= player.RoleData.PayData.PaySuccWaitAddRole.GetMaxCount())
{
player.Debug("PayHandler.ProcessPayGoogleReq uid {0} wait list is full, try delete finish order", player.UserID);
// 尝试删除最早成功的订单信息
PlayerPayUtil.DeleteEarliestPaySuccWaitAddRole(player);
// 没有队列空间, 先不让玩家继续购买
if (player.RoleData.PayData.PaySuccWaitAddRole.Count >= player.RoleData.PayData.PaySuccWaitAddRole.GetMaxCount())
{
player.Error("PayHandler.ProcessPayGoogleReq uid {0} wait list is full", player.UserID);
CSPayGoogleRes res = new CSPayGoogleRes { Ret = -1, ItemID = payReq.ItemID };
player.SendToClient((int)CSGameMsgID.PayGoogleRes, ref res);
return -1;
}
}
//检查代币数量是否足够,切代币支付模式
var needTokenNum = desc.currencyRes;
var costItemId = ItemId.Token;
if (!string.IsNullOrEmpty(desc.consumeItemId) && desc.consumeItemCount > 0)
{
costItemId = desc.consumeItemId;
needTokenNum = (uint)desc.consumeItemCount;
}
var token = UnifyOp.GetItemCount(player, GoodsType.Items, costItemId);
if (desc.goodsType != PayGoodsType.Token && token >= needTokenNum)
{
payReq.PayChannel = PayChannel.GameToken;
}
//不能用代币买代币
if (desc.goodsType == PayGoodsType.Token)
{
payReq.PayChannel = PayChannel.TrdSdk;
}
if (payReq.Param1 >= 0)
{
int iRet = PayCommSvc.CheckPayLimit(player, desc);
if (iRet != 0)
{
player.Error("PayHandler.ProcessPayGoogleReq CheckPayLimit failed, itemId {0} uid {1} ret {2}"
, payReq.ItemID, payReq.Uid, iRet);
CSPayGoogleRes res = new CSPayGoogleRes { Ret = iRet, ItemID = payReq.ItemID };
player.SendToClient((int)CSGameMsgID.PayGoogleRes, ref res);
return -1;
}
}
// 记录物品购买信息
int recordIndex = PlayerPayUtil.AddPaySuccRecordIfNotExist(player, desc);
if (recordIndex == -1)
{
TraceLog.Error("PayHandler.ProcessPayGoogleReq uid {0} itemId {1} add pay record failed"
, player.UserID, desc.itemID);
return -1;
}
// 限制下TestPay的使用
gmTestPay =payReq.IsTestPay == 1 && GmCmdSvc.IsGM(player.UserID);
//发给WorldServer,由WorldServer校验
SSPayGoogleReq ssReq = new SSPayGoogleReq();
ssReq.Uid = player.UserID;
ssReq.PayType = (uint)payType;
ssReq.ItemID = payReq.ItemID;
ssReq.Diamond = desc.diamond;
ssReq.Money = desc.currencyRes;
ssReq.GmTestPay = gmTestPay;
ssReq.JsApiPay = payReq.JsApiPay;
// gm测试时, 使用server逻辑时间(含gm指令增加的时间)做支付时间
long payTime = gmTestPay ? GameServerUtils.GetTimeSecond() : 0;
string orderId = "";
if (payType == PayType.MiniPay)
{//时间戳去2024-1-1 00:00:00的秒数到现在
payTime = GameServerUtils.GetTimeSecond() - 1704038400;
orderId = PayUtils.GenSimpleOrderIdForUser(player.UserID, desc.itemID, payTime);
}
else
{
orderId = PayUtils.GenOrderIdForUser(player.UserID, GameServerUtils.GetApp().ServerID,
desc.itemID, payReq.Param1, payReq.Param2, paymentId, payTime);
}
ssReq.OrderId.SetString(orderId);
ssReq.PaymentId.SetString(paymentId);
TraceLog.Debug("PayHandler.ProcessPayGoogleReq uid {0} itemId {1} orderId {2} moneyUSD {3} gm {4}"
, player.UserID, desc.itemID, ssReq.OrderId, desc.currencyRes, gmTestPay);
GameBillLogUtils.LogPayGoogleReq(ref ssReq);
switch (payReq.PayChannel)
{
case PayChannel.TrdSdk:
{
ssReq.Account.CopyFrom(ref player.AccountInfo);
GameServerUtils.GetPacketSender().SendToWorldServer((int)SSGameMsgID.PayGoogleReq, ref ssReq, player.UserID);
break;
}
break;
case PayChannel.GameToken:
PayCommSvc.TokenPay(player, payReq, ssReq);
break;
}
return 0;
}
private void ProcessPayGoogleRes(uint serverID, StructPacket packet)
{
ref SSPayGoogleRes ssRes = ref packet.GetMessage<SSPayGoogleRes>();
TraceLog.Debug("PayHandler.ProcessPayGoogleRes uid {0} itemId {1} orderId {2} ret {3}"
, ssRes.Uid, ssRes.ItemID, ssRes.OrderId, ssRes.Ret);
GameBillLogUtils.LogPayGoogleRes(ref ssRes);
//没有玩家对象可以不处理,订单也许废了,按理不应该发生
PlayerOnGame player = GameServerUtils.GetPlayerTableOp().GetPlayerByUid(ssRes.Uid);
if (player == null)
{
player.Error("PayHandler.ProcessPayGoogleRes no player uid {0}", ssRes.Uid);
return;
}
CSPayGoogleRes csRes = new CSPayGoogleRes
{
Ret = ssRes.Ret,
Uid = ssRes.Uid,
ItemID = ssRes.ItemID,
OrderId = ssRes.OrderId,
JsApiPay = ssRes.JsApiPay
};
string paymentId = PayCommSvc.GetPaymentId(ssRes.ItemID);
if (paymentId != null)
{
csRes.PaymentId.SetString(paymentId);
}
else
{
player.Error("PayHandler.ProcessPayGoogleRes item {0} invalid money {1}", ssRes.ItemID, ssRes.Money);
csRes.Ret = ssRes.Ret = -1;
}
//拼装小程序支付信息
if (ssRes.PayType == (int)PayType.MiniPay) SetMiniPayData(ref ssRes, ref csRes);
if (ssRes.Ret == 0 && ssRes.GmTestPay)
{
GmCmdSvc.OnGmTestPayReqSuccess(player, ref ssRes);
}
SendToPlayer(player, (int)CSGameMsgID.PayGoogleRes, ref csRes);
if(ssRes.Ret == 0 && ssRes.JsApiPay == 1 )
{
PayDiamondDesc desc = PayCommSvc.GetPayDiamondDesc(ssRes.ItemID);
//处理jsapi支付
JsonData jsonData = new JsonData();
jsonData["description"] = desc.comm;
jsonData["out_trade_no"] = "" + ssRes.OrderId.GetString();
JsonData jamount = new JsonData();
jamount["total"] = ssRes.Money * 100;//分
jamount["currency"] = "CNY";
jsonData["amount"] = jamount;
JsonData jpayer = new JsonData();
jpayer["openid"] = ""+player.AccountInfo.AccountID.GetString();
jsonData["payer"] = jpayer;
ref var req = ref CSWXJSPayReq.Parser.GetMessageClear();
req.DataJson.SetString(jsonData.ToJson());
req.Uid = player.UserID;
//send to world->httpPay
GameServerUtils.GetPacketSender().SendToWorldServer<CSWXJSPayReq>((int)CSGameMsgID.PayWsjsapiReq, ref req, player.UserID);
}
}
//获取mini支付参数
void SetMiniPayData(ref SSPayGoogleRes ssRes, ref CSPayGoogleRes res)
{
var conf = PayDiamondDescMgr.Instance.GetConfig(ssRes.ItemID);
var jsonData = new System.Text.Json.Nodes.JsonObject();
jsonData.Add("mode", "goods");
jsonData.Add("offerId", ssRes.OfferId.GetString());
jsonData.Add("buyQuantity", 1);
jsonData.Add("currencyType", "CNY");
jsonData.Add("productId", conf.productID);
jsonData.Add("goodsPrice", ssRes.Money * 100);//分
jsonData.Add("outTradeNo", ssRes.OrderId.GetString());
//非必要参数
/*
jsonData.Add("env", 0);
jsonData.Add("platform", "android");
jsonData.Add("zoneId", "1");
jsonData.Add("attach", "");
*/
var signData = jsonData.ToJsonString();
// 将method和signData通过&符号连接起来
string needEncodeBody = "requestMidasPaymentGameItem" + "&" + signData;
var paySig = HashHelper.GetHMACSHA256(ssRes.Appkey.GetString(), needEncodeBody);
var signature = HashHelper.GetHMACSHA256(ssRes.SessionKey.GetString(), signData);
res.SignData.SetString(signData);
res.PaySig.SetString(paySig);
res.Signature.SetString(signature);
TraceLog.Error("PayHandler.ProcessPayGoogleRes.SetMiniPayData signData:{0} paySig:{1}, signature:{2}", res.SignData.GetString(), res.PaySig.GetString(), res.Signature.GetString());
}
public void ProcessPayGoogleSuccessReq(PlayerSession playerSession, StructPacket packet, bool gmTestPay)
{
ref CSPayGoogleSuccessReq payReq = ref packet.GetMessage<CSPayGoogleSuccessReq>();
if (payReq.Uid != playerSession.UserID)
{
TraceLog.Error("PayHandler.ProcessPayGoogleSuccessReq invalid uid {0}", payReq.Uid);
return;
}
PlayerOnGame player = playerSession.Player;
if (player == null)
{
TraceLog.Error("PayHandler.ProcessPayGoogleSuccessReq no player uid {0}", payReq.Uid);
return;
}
PayType payType = PlayerPayUtil.GetPlayerPayType(player);
if (payType == PayType.Google)
{
GooglePaySvc.OnPaySuccessReq(player, ref payReq, gmTestPay);
}
else if (payType == PayType.IAP)
{
IAPPaySvc.OnPaySuccessReq(player, ref payReq, gmTestPay);
}
else if (payType == PayType.Hero)
{
OnHeroPayClientSuccReq(player, ref payReq, gmTestPay);
}
else if (payType == PayType.Huawei)
{
HuaweiPaySvc.OnCltPaySuccessReq(player, ref payReq, gmTestPay);
}
else
{
player.Error("PayHandler.ProcessPayGoogleSuccessReq payType {0} can not send PaySuccReq by client", payType);
}
}
private static void OnHeroPayClientSuccReq(PlayerOnGame player, ref CSPayGoogleSuccessReq req, bool gmTestPay)
{
if (req.OrderId.Length == 0)
{
return;
}
// uid-time-orderIdSeq-serverId-payitemId-payParam1-payParam2-paymentId
string orderId = req.OrderId.GetString();
string[] split = orderId.Split('-');
if (split.Length < 8)
{
TraceLog.Error("PayHandler.OnHeroPayClientSuccReq invalid orderId {0}", orderId);
return;
}
GameBillLogUtils.LogPayGoogleSuccessReq(ref req, (int)PayType.Hero);
int itemId = int.Parse(split[4]);
int index = PlayerPayUtil.GetPaySuccLockIndex(player, itemId);
// 没有lock, 创建lock并记录客户端成功的时间
if (index == -1)
{
index = PlayerPayUtil.CreatePaySuccLockIfNotExist(player, itemId, orderId, req.OrderId3rd.GetString());
if (index == -1)
{
TraceLog.Error("PayHandler.OnHeroPayClientSuccReq orderId {0} add lock failed", orderId);
}
else
{
TraceLog.Trace("PayHandler.OnHeroPayClientSuccReq item {0} create lock by clt", itemId);
ref var lockData = ref PlayerPayUtil.GetPaySuccLockByIndex(player, index);
lockData.CltSuccTime = GameServerUtils.GetTimeSecond();
}
return;
}
// lock存在, 但是订单号不一致? 按道理应该不可能, 现在一旦client或者svr有一边成功后就被锁住了
ref var lockOne = ref PlayerPayUtil.GetPaySuccLockByIndex(player, index);
if (!lockOne.OrderId.Equals(orderId))
{
TraceLog.Error("PayHandler.OnHeroPayClientSuccReq order not equal, orderId local {0} req {1}"
, lockOne.OrderId.GetString(), orderId);
return;
}
if (!lockOne.OrderId3rd.Equals(req.OrderId3rd.GetPtr()))
{
TraceLog.Error("PayHandler.OnHeroPayClientSuccReq order not equal, orderId3rd local {0} req {1}"
, lockOne.OrderId3rd.GetString(), req.OrderId3rd.GetString());
return;
}
// svr已经成功, 可以删除lock
if (lockOne.SvrSuccTime != 0)
{
TraceLog.Trace("PayHandler.OnHeroPayClientSuccReq item {0} order {1} svr succ at {2}, delete lock now"
, itemId, orderId, lockOne.SvrSuccTime);
player.RoleData.PayData.PaySuccLock.RemoveAt(index);
}
else
{
TraceLog.Trace("PayHandler.OnHeroPayClientSuccReq item {0} lock by clt", itemId);
lockOne.CltSuccTime = GameServerUtils.GetTimeSecond();
}
player.MakeDirty();
}
public int ProcessPayGoogleSuccessRes(uint serverID, StructPacket packet)
{
ref SSPayGoogleSuccessRes ssRes = ref packet.GetMessage<SSPayGoogleSuccessRes>();
TraceLog.Error("PayHandler.ProcessPayGoogleSuccessRes uid {0} itemId {1} orderId {2} pay status {3} ret {4}",
ssRes.Uid, ssRes.ItemID, ssRes.OrderId, ssRes.Status, ssRes.Ret);
// 没有玩家对象可以不处理, 下次上线时统一把支付成功未加钻石的订单全部处理一遍
PlayerOnGame player = GameServerUtils.GetPlayerTableOp().GetPlayerByUid(ssRes.Uid);
if (player == null)
{
TraceLog.Error("PayHandler.ProcessPayGoogleSuccessRes uid {0} no player", ssRes.Uid);
GameBillLogUtils.LogPayGoogleSuccessRes(ref ssRes, 0, 0, 0, 0, false, null);
return -1;
}
CSPayGoogleSuccessRes csRes = new CSPayGoogleSuccessRes();
csRes.Ret = ssRes.Ret;
csRes.Uid = ssRes.Uid;
csRes.OrderId = ssRes.OrderId;
csRes.ItemID = ssRes.ItemID;
PayType payType = PlayerPayUtil.GetPlayerPayType(player);
PayDiamondDesc desc = PayCommSvc.GetPayDiamondDesc(ssRes.ItemID);
if (desc == null)
{
player.Error("PayHandler.ProcessPayGoogleSuccessRes invalid itemId {0}", ssRes.ItemID);
ssRes.Ret = -1;
GameBillLogUtils.LogPayGoogleSuccessRes(ref ssRes, 0, 0, 0, 0, false, player);
csRes.Ret = -1;
SendToPlayer(player, (int)CSGameMsgID.PayGoogleSuccessRes, ref csRes);
return -1;
}
// 支付出错
if (ssRes.Ret != 0)
{
player.Error("PayHandler.ProcessPayGoogleSuccessRes uid {0} orderId {1} ret {2}"
, ssRes.Uid, ssRes.OrderId, ssRes.Ret);
GameBillLogUtils.LogPayGoogleSuccessRes(ref ssRes, (int)desc.currencyRes, 0, 0, 0, false, player);
SendToPlayer(player, (int)CSGameMsgID.PayGoogleSuccessRes, ref csRes);
return -1;
}
// 订单状态出错, 可能是处理同一笔订单产生的消息
if (ssRes.Status != 1)
{
player.Error("PayHandler.ProcessPayGoogleSuccessRes uid {0} orderId {1} pay status {2}"
, ssRes.Uid, ssRes.OrderId, ssRes.Status);
GameBillLogUtils.LogPayGoogleSuccessRes(ref ssRes, (int)desc.currencyRes, 0, 0, 0, false, player);
return -1;
}
// mycard支付金额由用户输入, 支持支付金额不等于商品价格时, 需要根据规则兑换成钻石
bool isReplaceItem = false;
uint diamondExchange = 0, amountExchange = 0;
if (ssRes.PayType == (uint)PayType.Hero && PayCommSvc.IsMycardPay(ssRes.SubPayType)
&& ssRes.Amount != desc.currencyRes)
{
ExchangeDiamondByPayMoney(player, ref ssRes, desc, out amountExchange, out diamondExchange, out var newDesc);
// 替换了玩家之前选择的item !!!
if (desc.itemID != newDesc.itemID)
{
player.Debug("PayHandler.ProcessPayGoogleSuccessRes uid {0} item {1} change to {2}"
, player.UserID, desc.itemID, newDesc.itemID);
desc = newDesc;
isReplaceItem = true;
PlayerPayUtil.AddPaySuccRecordIfNotExist(player, desc);
}
}
int recordIndex = PlayerPayUtil.GetPaySuccessRecordIndex(player, desc.itemID);
if (recordIndex == -1)
{
player.Error("PayHandler.ProcessPayGoogleSuccessRes uid {0} itemId {1} no pay record", player.UserID,
desc.itemID);
return -1;
}
// 收到支付成功请求, 插入待添加列表
ref DBRolePayItemRecord record = ref PlayerPayUtil.GetPayItemRecordByIndex(player, recordIndex);
int idx = InsertPaySuccWaitAddRole(player, desc, ref ssRes, ref record, amountExchange, diamondExchange, isReplaceItem);
if (idx == -1)
{
return -1;
}
// 已经发货成功, 等待超时后删除
ref var addData = ref player.RoleData.PayData.PaySuccWaitAddRole[idx];
if (addData.AddItemSuccTime > 0)
{
player.Debug("PayHandler.ProcessPayGoogleSuccessRes uid {0} order {1} already add item {2}"
, player.UserID, addData.OrderId.GetString(), addData.AddItemSuccTime);
return -1;
}
// 成功后请求数据库修改支付订单状态, 先修改DB订单状态再添加物品
var addReq = new SSPayDBAddDiamondStatusReq
{
Uid = player.UserID,
AmountExchange = amountExchange,
DiamondExchange = diamondExchange,
Money = addData.Money
};
addReq.OrderId.SetString(ssRes.OrderId.GetPtr());
if (isReplaceItem)
{
addReq.ReplaceItemId = desc.itemID;
}
addData.LastSendDBTime = (int)GameServerUtils.GetTimeSecond();
player.Debug("PayHandler.ProcessPayGoogleSuccessRes uid {0} send DB add diamond status", player.UserID);
if (ssRes.PayChannel == PayChannel.TrdSdk)
{
GameServerUtils.GetPacketSender().SendToWorldServer((int)SSGameMsgID.PayDbAddDiamondStatusReq, ref addReq, player.UserID);
}
return 0;
}
public void ExchangeDiamondByPayMoney(PlayerOnGame player, ref SSPayGoogleSuccessRes ssRes, PayDiamondDesc desc,
out uint amountExchange, out uint diamondExchange, out PayDiamondDesc replaceItemDesc)
{
amountExchange = 0;
diamondExchange = 0;
replaceItemDesc = null;
// 购买钻石礼包
if (desc.bdc_product_type == 1)
{
// 大买小
if (ssRes.Amount > desc.currencyRes)
{
replaceItemDesc = desc;
}
else
{
// 根据付款金额找一档最接近的, 然后把差额换算成钻石
replaceItemDesc = PayDiamondDescMgr.Instance.GetDiamondByMoney(ssRes.Amount);
}
if (replaceItemDesc != null)
{
amountExchange = ssRes.Amount - replaceItemDesc.currencyRes;
}
else
{
// 找不到金额最接近的钻石档位, 全部换算成钻石
//replaceItemDesc = PayDiamondDescMgr.Instance.GetConfig((int)PayType.Hero, "gp_dynamicDiamond");
replaceItemDesc = PayDiamondDescMgr.Instance.GetConfig(99999);
amountExchange = ssRes.Amount;
}
}
else
{
// 非钻石礼包, 付款超过商品价格时, 超出部分转换成钻石
if (ssRes.Amount > desc.currencyRes)
{
replaceItemDesc = desc;
amountExchange = ssRes.Amount - desc.currencyRes;
}
else if (desc.currencyRes > ssRes.Amount)
{
// 付款少于商品价格时, 全部兑换成钻石
//replaceItemDesc = PayDiamondDescMgr.Instance.GetConfig((int)PayType.Hero, "gp_dynamicDiamond");
replaceItemDesc = PayDiamondDescMgr.Instance.GetConfig(99999);
amountExchange = ssRes.Amount;
}
}
if (amountExchange > 0)
{
diamondExchange = amountExchange * 6 / 10;
}
player.Debug("PayHandler.ExchangeDiamondByPayMoney uid {0} amount {1} exchange amount {2} diamond {3} origin item {4} replace item {5}"
, player.UserID, ssRes.Amount, amountExchange, diamondExchange, desc.itemID, replaceItemDesc.itemID);
}
public int InsertPaySuccWaitAddRole(PlayerOnGame player, PayDiamondDesc desc,
ref SSPayGoogleSuccessRes res, ref DBRolePayItemRecord record, uint amountExchange, uint diamondExchange, bool isReplaceItem)
{
// 删除超过保留时间的发货成功的waitAddRole数据
PlayerPayUtil.DeletePaySuccWaitAddRole(player);
for (int i = 0; i < player.RoleData.PayData.PaySuccWaitAddRole.Count; i++)
{
ref var item = ref player.RoleData.PayData.PaySuccWaitAddRole[i];
// 重复收到了支付成功的消息
if (item.OrderId.Equals(res.OrderId.GetPtr()))
{
player.Debug("PayHandler.InsertPaySuccWaitAddRole uid {0} orderId {1} already exist"
, player.UserID, res.OrderId.GetString());
return i;
}
}
// 删除最早一笔发货成功的waitAddRole数据
if (player.RoleData.PayData.PaySuccWaitAddRole.Count >= player.RoleData.PayData.PaySuccWaitAddRole.GetMaxCount())
{
PlayerPayUtil.DeleteEarliestPaySuccWaitAddRole(player);
}
// 数据库出问题了? 否则为什么累计了这么多笔订单未添加呢, 没关系, 每次上线时会重新处理未完成的订单
if (player.RoleData.PayData.PaySuccWaitAddRole.Count >= player.RoleData.PayData.PaySuccWaitAddRole.GetMaxCount())
{
player.Error("PayHandler.InsertPaySuccWaitAddRole uid {0} wait add list is full", player.UserID);
return -1;
}
string orderId = res.OrderId.GetString();
string orderId3rd = res.OrderId3rd.GetString();
// 支付成功时处理item锁, 要使用res.ItemID, 否则在点卡支付时可能会被替换成其他itemId
ProcItemLockOnSvrSucc(player, res.ItemID, orderId, orderId3rd);
var data = new DBPaySuccWaitAddRole
{
Money = desc.currencyRes > 0 ? desc.currencyRes : res.Amount,
Amount = res.Amount,
PayType = (int)res.PayType,
IsPlayerFirstPay = PlayerPayUtil.IsFirstPayUser(player),
PayTime3rd = res.PayTime3rd,
IsTestPay = res.GmTestPay ? 1 : 0,
AmountExchange = amountExchange,
DiamondExchange = diamondExchange,
IsReplaceItem = isReplaceItem,
Sandbox = res.Sandbox,
};
// item不能使用res.ItemID, 点卡支付时可能会替换成实际能购买的itemId
data.ItemID = desc.itemID;
data.OrderId.SetString(res.OrderId.GetPtr());
data.OrderId3rd.SetString(res.OrderId3rd.GetPtr());
data.Currency.SetString(res.Currency.GetPtr());
data.PurchaseToken.SetString(res.PurchaseToken.GetPtr());
player.RoleData.PayData.PaySuccWaitAddRole.Add(ref data);
// 插入PaySuccWaitAddRole列表就算支付成功
record.PaySuccessCount++;
record.PayCountToday++;
record.PayCountWeek++;
record.PayCountMonth++;
if (res.PayChannel == PayChannel.TrdSdk)
{
player.RoleData.PayData.TotalPayMoney += res.Amount;
player.RoleData.PayData.TotalPayMoneyUSD += res.Amount;
SystemUnlockEvent.CheckUnlockSystem(player);
}
if (res.GmTestPay)
{
player.RoleData.PayData.GmTotalPayMoneyUSD += res.Amount;
}
// 支付成功时记录首冲礼包的版本号, 后续用于首冲礼包领取
PayDiamondDesc firstPayDesc = null;
// 当天的购买记录保存在第一个
if (res.Amount > player.RoleData.PayData.MaxPayMoneyLast7Days[0])
{
player.RoleData.PayData.MaxPayMoneyLast7Days[0] = (int)res.Amount;
}
// 充值统计
RoleStatChgOp statChgOp = new RoleStatChgOp(player);
statChgOp.AddIDDaily((int)CSRoleStatisticsID.PayMoney, res.Amount);
statChgOp.NotifyClient();
player.MakeDirty();
player.Debug("PayHandler.InsertPaySuccWaitAddRole uid {0} itemId {1} orderId {2} pay count total {3} today {4} week {5} month {6} pay money {7} dollar {8} playerFirstPay {9}"
, player.UserID, desc.itemID, data.OrderId.GetString(), record.PaySuccessCount, record.PayCountToday
, record.PayCountWeek, record.PayCountMonth, player.RoleData.PayData.TotalPayMoney
, player.RoleData.PayData.TotalPayMoneyUSD, data.IsPlayerFirstPay);
return player.RoleData.PayData.PaySuccWaitAddRole.Count - 1;
}
private void ProcItemLockOnSvrSucc(PlayerOnGame player, int itemId, string orderId, string orderId3rd)
{
int index = PlayerPayUtil.GetPaySuccLockIndex(player, itemId);
// 没有lock, 创建lock并记录svr成功时间
if (index == -1)
{
index = PlayerPayUtil.CreatePaySuccLockIfNotExist(player, itemId, orderId, orderId3rd);
if (index == -1)
{
TraceLog.Error("PayHandler.ProcItemLockOnSvrSucc item {0} order {1} add lock failed", itemId, orderId);
}
else
{
TraceLog.Trace("PayHandler.ProcItemLockOnSvrSucc item {0} create lock by svr", itemId);
ref var lockData = ref PlayerPayUtil.GetPaySuccLockByIndex(player, index);
lockData.SvrSuccTime = GameServerUtils.GetTimeSecond();
}
}
else
{
ref var lockOne = ref PlayerPayUtil.GetPaySuccLockByIndex(player, index);
if (lockOne.OrderId.Equals(orderId) && lockOne.OrderId3rd.Equals(orderId3rd))
{
// 支付完成删除锁
if (lockOne.CltSuccTime != 0)
{
TraceLog.Trace("PayHandler.ProcItemLockOnSvrSucc item {0} clt succ at {1}, delete lock now", itemId, lockOne.CltSuccTime);
player.RoleData.PayData.PaySuccLock.RemoveAt(index);
}
else
{
TraceLog.Trace("PayHandler.ProcItemLockOnSvrSucc item {0} lock by svr", itemId);
lockOne.SvrSuccTime = GameServerUtils.GetTimeSecond();
}
}
else
{
TraceLog.Error("PayHandler.ProcItemLockOnSvrSucc item {0} orderId local {1} res {2}, orderId3rd local {3} res {4} not equal"
, itemId, lockOne.OrderId.GetString(), orderId, lockOne.OrderId3rd.GetString(), orderId3rd);
}
}
}
public void ProcessDBAddDiamondStatusRes(uint serverID, StructPacket packet)
{
ref SSPayDBAddDiamondStatusRes res = ref packet.GetMessage<SSPayDBAddDiamondStatusRes>();
long uid = packet.ObjectID;
OnDBAddDiamondStatusRes(uid, ref res, true);
}
public void OnDBAddDiamondStatusRes(long uid, ref SSPayDBAddDiamondStatusRes res, bool realPay)
{
//没有玩家对象可以不处理, 下次上线时会统一处理
PlayerOnGame player = GameServerUtils.GetPlayerTableOp().GetPlayerByUid(uid);
if (player == null)
{
TraceLog.Error("PayHandler.OnDBAddDiamondStatusRes uid {0} no player", uid);
return;
}
int idx = -1;
for (int i = 0; i < player.RoleData.PayData.PaySuccWaitAddRole.Count; i++)
{
ref var item = ref player.RoleData.PayData.PaySuccWaitAddRole[i];
if (item.OrderId.Equals(res.OrderId.GetPtr()))
{
idx = i;
break;
}
}
// 没有可能是收到了重复的消息, 已经添加过钻石了
if (idx == -1)
{
player.Error("PayHandler.OnDBAddDiamondStatusRes uid {0} orderId {1} not in wait add list"
, uid, res.OrderId.GetString());
return;
}
ref DBPaySuccWaitAddRole addData = ref player.RoleData.PayData.PaySuccWaitAddRole[idx];
// 已经添加成功, 无需再处理
if (addData.AddItemSuccTime > 0)
{
player.Error("PayHandler.OnDBAddDiamondStatusRes uid {0} orderId {1} already add succ {2}"
, uid, res.OrderId.GetString(), addData.AddItemSuccTime);
return;
}
// 如果DB状态是支付成功1或者添加钻石2, 则会统一更新成状态2
if (res.Status != 2)
{
addData.DbResFailCount++;
TraceLog.Error("PayHandler.OnDBAddDiamondStatusRes uid {0} orderId {1} pay status {2} fail count {3}"
, uid, res.OrderId, res.Status, addData.DbResFailCount);
return;
}
int itemId = addData.ItemID;
string orderId = addData.OrderId.GetString();
player.Debug("PayHandler.OnDBAddDiamondStatusRes uid {0} orderId {1} firstPay {2}",
player.UserID, orderId, addData.IsPlayerFirstPay);
PayType payType = PlayerPayUtil.GetPlayerPayType(player);
PayDiamondDesc desc = PayCommSvc.GetPayDiamondDesc(itemId);
if (desc == null)
{
player.Error("PayHandler.OnDBAddDiamondStatusRes invalid itemId {0} uid {1}", itemId, player.UserID);
return;
}
var dailyPackDiamond = PayCommSvc.GetBuyOneClickDailyPackDiamond(player, desc.itemID);
var csRes = new CSPayGoogleSuccessRes();
csRes.Uid = player.UserID;
csRes.OrderId.SetString(res.OrderId.GetPtr());
csRes.ItemID = itemId;
csRes.PurchaseToken.SetString(addData.PurchaseToken.GetPtr());
csRes.Money = addData.Amount;
csRes.Diamond = desc.diamond;
csRes.PayDiamond = desc.payDiamond;
csRes.Diamond += (uint)dailyPackDiamond;
uint addDiamond = addData.DiamondExchange;
var isFirstPay = PlayerPayUtil.IsFirstPayThisItem(player, desc);
List<TypeIDValueString> selfItems = new List<TypeIDValueString>();
{
// if (SelfSelectBagScv.IsSelfSelectBag(desc.goodsType))
// {
// selfItems = SelfSelectBagScv.GetPaySelectBagItems(player, desc.itemID);
// }
int vipEx = addData.DiamondExchange > 0 ? (int)addData.DiamondExchange : 0;
var itemEx = GetPayAddItemEx(ref res);
// if (PayCommSvc.IsLifeLongMenberCard(desc.vipCardType))
// {
// int index = PlayerPayUtil.GetMonthlyCardDataIndex(player, desc.vipCardType);
// if (index < 0)
// {
// csRes.Ret = CheckAddPayItemToPlayer(player, orderId, addDiamond, desc, vipEx, ref csRes, itemEx);
// }
// else
// {
// player.Error("PayHandler.OnDBAddDiamondStatusRes repay long card,uid={0},card={1},order={2}", player.UserID, desc.itemID, res.OrderId.GetString());
// csRes.Ret = 0;
// SendToPlayer(player, (int)CSGameMsgID.PayGoogleSuccessRes, ref csRes);
// return;
// }
// }
// else
{
csRes.Ret = CheckAddPayItemToPlayer(player, orderId, addDiamond, desc, vipEx, ref csRes, itemEx, res.PayChannel);
}
}
//正常来说不会存在这种情况吧,数据库成功,玩家身上不成功
if (csRes.Ret != 0)
{
SendToPlayer(player, (int)CSGameMsgID.PayGoogleSuccessRes, ref csRes);
return;
}
// 首冲
bool isPlayerFirstPay = addData.IsPlayerFirstPay;
long payTime3rd = addData.PayTime3rd;
try
{
if (realPay)
{
if(addData.PayType != (int)PayType.MiniPay)
{
NotifyHttpPaySvrAddItemSucc(player, ref addData);
}
GameBillLogUtils.LogPayGoogleSuccessRes(ref addData, 0, addData.IsPlayerFirstPay, player);
GameBDCLogUtils.ChargeInfo(player, ref addData, desc.bdc_product_type, addData.IsPlayerFirstPay);
GameTALogUtils.UseSetCharge(player, ref addData);
GameTALogUtils.UseSetOnceFirstPay(player, ref addData);
GameTALogUtils.LogChargeInfo(player, ref addData, 0, ref res, selfItems);
}
else
{
if (string.IsNullOrEmpty(desc.consumeItemId))//砖石礼包不打
{
GameTALogUtils.LogVoucherChargeInfo(player, ref addData, ref res, selfItems);
}
}
}
catch (Exception e)
{
TraceLog.Exception(e);
var app = GameServerUtils.GetApp();
if (app != null)
{
app.Alerter.AlertException(e,uid);
}
}
finally
{
// 记录添加成功时间
player.RoleData.PayData.PaySuccWaitAddRole[idx].AddItemSuccTime = (int)GameServerUtils.GetTimeSecond();
}
//记录玩家进入购买钻石数量
player.RoleData.PayData.TodayPayDiamond += desc.payDiamond + dailyPackDiamond;
//购买代币不触发任何支付后的事件
if (desc.goodsType != (int)PayGoodsType.None)
{
GameServerUtils.GetEventHandlerMgr().TriggerPlayerPaySuccess(player, desc.itemID, addData.DiamondExchange, addDiamond, addData.Amount, isPlayerFirstPay, payTime3rd, ref csRes);
}
else
{
//购买代币需要触发一下
// PlayerDataSvc.UnlockNewPlayerGift(player,desc.goodsType,desc.itemID);
}
if (isFirstPay && desc.firstPayAwardType > 0)
{
if (desc.firstPayAwardId ==ItemId.Diamond)
{
csRes.Diamond += (uint)desc.firstPayAwardNum;
}
else
{
if (desc.firstPayAwardType > 0)
{
csRes.Items.Add(new TypeIDValueString()
{ Type = desc.firstPayAwardType, Id = new FixedStructString64(desc.firstPayAwardId), Value = desc.firstPayAwardNum });
}
}
}
if (!isFirstPay)
{
if (desc.followPayAwardId == ItemId.Diamond)
{
csRes.Diamond += (uint)desc.followPayAwardNum;
}
else
{
if (desc.followPayAwardType > 0)
{
csRes.Items.Add(new TypeIDValueString()
{ Type = desc.followPayAwardType, Id = new FixedStructString64(desc.followPayAwardId), Value = desc.followPayAwardNum });
}
}
}
TraceLog.Error("add item success,itemID:" + desc.itemID + addData.DiamondExchange + " addDiamond:" + addDiamond + " payMoney:" + addData.Amount + "is irst:" + isPlayerFirstPay);
PlayerNotify.NotifyPlayerPayDataChange(player);
SendToPlayer(player, (int)CSGameMsgID.PayGoogleSuccessRes, ref csRes);
}
private List<TypeIDValueString> GetPayAddItemEx(ref SSPayDBAddDiamondStatusRes res)
{
List<TypeIDValueString> itemEx = null;
for (int i = 0; i < res.SelectItems.Count; i++)
{
if (itemEx == null)
{
itemEx = new List<TypeIDValueString>();
}
itemEx.Add(res.SelectItems[i]);
}
return itemEx;
}
private List<TypeIDValueString> GetPayAddItemEx(ref CSPayGetFreeItemReq req)
{
List<TypeIDValueString> itemEx = null;
for (int i = 0; i < req.SelectItems.Count; i++)
{
if (itemEx == null)
{
itemEx = new List<TypeIDValueString>();
}
itemEx.Add(req.SelectItems[i].Item);
}
return itemEx;
}
private int CheckAddPayItemToPlayer(PlayerOnGame player, string orderId, uint diamond, PayDiamondDesc desc,
int vipEx, ref CSPayGoogleSuccessRes csRes, List<TypeIDValueString> itemEx, PayChannel payChannel)
{
int ret = CheckAddPayItem(player, orderId, diamond, desc, vipEx, itemEx, payChannel);
if (ret != 0)
{
return ret;
}
// csRes.VipCardType = desc.vipCardType;
for (int i = 0; i < desc.giveItem.Length; i++)
{
if (desc.giveItem[i].type > 0 && desc.giveItem[i].count > 0)
{
var one = new TypeIDValueString { Type = desc.giveItem[i].type, Id = new FixedStructString64(desc.giveItem[i].id) , Value = desc.giveItem[i].count };
csRes.Items.Add(ref one);
}
}
var packGiveItem = PayCommSvc.GetBuyOneClickDailyPackGiveItem(player, desc.itemID);
for (var i = 0; i < packGiveItem.Length; i++)
{
csRes.Items.Add(ref packGiveItem[i]);
}
// 不在PayDiamond表中的额外物品
if (itemEx != null)
{
foreach (var it in itemEx)
{
csRes.Items.Add(it);
}
}
// //自选礼包的物品更新
// if (SelfSelectBagScv.IsSelfSelectBag(desc.goodsType))
// {
// var selfItems = SelfSelectBagScv.GetPaySelectBagItems(player, desc.itemID, true);
// foreach (var one in selfItems)
// {
// csRes.Items.Add(one);
// }
// }
return 0;
}
private int CheckAddPayItem(PlayerOnGame player, string orderId, uint diamond,
PayDiamondDesc desc, int vipEx, List<TypeIDValueString> itemEx, PayChannel payChannel)
{
player.Debug("PayHandler.CheckAddPayItem uid {0} itemId {1} orderId {2}"
, player.UserID, desc.itemID, orderId);
if (payChannel == PayChannel.GameToken) {
var ret = CheckCostPayItem(player, desc, orderId, true);
if (ret != 0)
{
return ret;
}
}
// 添加钻石和物品
UnifyOp bagOp = new UnifyOp(player, BillChangeItemReason.Pay, orderId);
if (diamond > 0)
{
bagOp.AddDiamond(diamond); // 现在这里的diamond只有diamoneExchange 首次充值额外赠送另外算
player.RoleData.PayData.TodayPayDiamond += diamond;
}
if (desc.diamond > 0)
{
bagOp.AddDiamond(desc.diamond);
player.RoleData.PayData.TodayPayDiamond += desc.diamond;
}
if (desc.payDiamond > 0)
{
bagOp.AddDiamond(desc.payDiamond);
}
var firstPay = PlayerPayUtil.IsFirstPayThisItem(player, desc);
if (firstPay && desc.firstPayAwardType > 0)
{
bagOp.AddGoods(desc.firstPayAwardType, desc.firstPayAwardId.ToString(), desc.firstPayAwardNum);
if (desc.firstPayAwardId == ItemId.Diamond)
{
player.RoleData.PayData.TodayPayDiamond += desc.firstPayAwardNum;
}
}
for (int i = 0; i < desc.giveItem.Length; i++)
{
if (desc.giveItem[i].type > 0 && desc.giveItem[i].count > 0)
{
bagOp.AddGoods(desc.giveItem[i].type, desc.giveItem[i].id, desc.giveItem[i].count);
if ( desc.giveItem[i].id == ItemId.Diamond)
{
player.RoleData.PayData.TodayPayDiamond += desc.giveItem[i].count;
}
}
}
var packGiveItem = PayCommSvc.GetBuyOneClickDailyPackGiveItem(player, desc.itemID);
for (var i = 0; i < packGiveItem.Length; i++)
{
bagOp.AddGoods(packGiveItem[i].Type, packGiveItem[i].Id.ToString(), packGiveItem[i].Value);
if (packGiveItem[i].Id.ToString() == ItemId.Diamond)
{
player.RoleData.PayData.TodayPayDiamond += packGiveItem[i].Value;
}
}
//非首充
if (!firstPay && desc.followPayAwardNum > 0)
{
bagOp.AddGoods(desc.followPayAwardType, desc.followPayAwardId, desc.followPayAwardNum);
if (desc.followPayAwardId == ItemId.Diamond)
{
player.RoleData.PayData.TodayPayDiamond += desc.followPayAwardNum;
}
}
// 不在PayDiamond表中的额外物品
if (itemEx != null)
{
foreach (var it in itemEx)
{
bagOp.AddGoods(it.Type, it.Id.ToString(), it.Value);
}
}
// //自选礼包的物品更新
// if (SelfSelectBagScv.IsSelfSelectBag(desc.goodsType))
// {
// var selfItems = SelfSelectBagScv.GetPaySelectBagItems(player, desc.itemID);
// foreach (var one in selfItems)
// {
// bagOp.AddGoods(one.Type, one.Id.ToString(), one.Value);
// }
// }
CSErrCode iRet = bagOp.DoOp(sendGetItemMsg: true);
if (iRet != 0)
{
player.Error("PayHandler.CheckAddPayItem uid {0} bagOp.DoOp failed ret {1}", player.UserID, iRet);
return (int)iRet;
}
// // 月卡/周卡
if (PayCommSvc.IsMonthlyCard(desc.vipCardType))
{
MonthlyCardSvc.OnActiveMonthlyCard(player, desc.vipCardType);
}
player.Debug("PayHandler.CheckAddPayItem uid {0} add diamond {1} new diamond {2} succ"
, player.UserID, diamond, player.RoleBase.Diamond);
return 0;
}
public int CheckCostPayItem(PlayerOnGame player, PayDiamondDesc desc, string orderId, bool cost = true)
{
var consumeItemId = ItemId.Token;
var consumeItemCount = desc.currencyRes;
if (!string.IsNullOrEmpty(desc.consumeItemId) && desc.consumeItemCount > 0)
{
consumeItemId = desc.consumeItemId;
consumeItemCount = (uint)desc.consumeItemCount;
}
var bagOpDelete = new UnifyOp(player, BillChangeItemReason.Pay, orderId);
if (!cost)
{
return bagOpDelete.GetItemCount(consumeItemId) >= consumeItemCount ? 0 : -1;
}
bagOpDelete.CostGoods((int)GoodsType.Items, consumeItemId, consumeItemCount);
CSErrCode iDeleteRet = bagOpDelete.CheckOp();
if (iDeleteRet != 0)
{
player.Error(
"PayHandler.CheckAddPayItem uid {0} bagOp.DoOp failed ret {1} when delete consumeItem {2}"
, player.UserID, iDeleteRet, consumeItemId);
return -1;
}
iDeleteRet = bagOpDelete.DoOp();
if (iDeleteRet != 0)
{
player.Error(
"PayHandler.CheckAddPayItem uid {0} bagOp.DoOp failed ret {1} when delete consumeItem {2}"
, player.UserID, iDeleteRet, consumeItemId);
return -1;
}
return 0;
}
public void ProcessPayGetFreeItemReq(PlayerSession playerSession, StructPacket packet)
{
PlayerOnGame player = playerSession.Player;
if (player == null)
{
TraceLog.Trace("PayHandler.ProcessPayGetFreeItemReq no player, session id {0}", playerSession.SessionID);
return;
}
// 这个系统解锁效率不高, 建议修改成按Bit来判断, 限制下外挂领取免费物品, 付费的就不限制了, 反正花钱了
ref CSPayGetFreeItemReq req = ref packet.GetMessage<CSPayGetFreeItemReq>();
PayType payType = PlayerPayUtil.GetPlayerPayType(player);
PayDiamondDesc desc = PayCommSvc.GetPayDiamondDesc(req.ItemID);
if (desc == null)
{
player.Error("PayHandler.ProcessPayGetFreeItemReq invalid itemId {0} uid {1}", req.ItemID, player.UserID);
return;
}
if (desc.currencyRes != 0)
{
player.Error("PayHandler.ProcessPayGetFreeItemReq itemId {0} not free", req.ItemID);
return;
}
var res = new CSPayGetFreeItemRes();
res.ItemID = req.ItemID;
res.Ret = PayCommSvc.CheckPayLimit(player, desc);
if (res.Ret != 0)
{
player.Error("PayHandler.ProcessPayGetFreeItemReq CheckPayLimit failed, itemId {0} uid {1} ret {2}"
, req.ItemID, player.UserID, res.Ret);
SendToPlayer(player, (int)CSGameMsgID.PayGetFreeItemRes, ref res);
return;
}
int recordIndex = PlayerPayUtil.AddPaySuccRecordIfNotExist(player, desc);
if (recordIndex == -1)
{
TraceLog.Error("PayHandler.ProcessPayGetFreeItemReq uid {0} itemId {1} add pay record failed"
, player.UserID, desc.itemID);
res.Ret = -1;
SendToPlayer(player, (int)CSGameMsgID.PayGetFreeItemRes, ref res);
return;
}
// 不在PayDiamond表中的额外物品
var itemEx = GetPayAddItemEx(ref req);
//res.Ret = CheckAddPayItem(player, PayCommSvc.FreeGiftPack, 0, desc, 0, itemEx,);
//if (res.Ret != 0)
//{
// SendToPlayer(player, (int)CSGameMsgID.PayGetFreeItemRes, ref res);
// return;
//}
ref DBRolePayItemRecord record = ref PlayerPayUtil.GetPayItemRecordByIndex(player, recordIndex);
record.PaySuccessCount++;
record.PayCountToday++;
record.PayCountWeek++;
record.PayCountMonth++;
PlayerNotify.NotifyPlayerPayDataChange(player);
GameBillLogUtils.LogPayFreeGiftPack(player, desc, ref record);
res.Diamond = desc.diamond;
//res.VipCardType = desc.vipCardType;
res.PayDiamond = desc.payDiamond;
for (int i = 0; i < desc.giveItem.Length; i++)
{
if (desc.giveItem[i].type > 0 && desc.giveItem[i].count > 0)
{
var one = new TypeIDValueString { Type = desc.giveItem[i].type,
Id = new FixedStructString64(desc.giveItem[i].id), Value = desc.giveItem[i].count };
res.Items.Add(ref one);
}
}
// 不在PayDiamond表中的额外物品
if (itemEx != null)
{
foreach (var it in itemEx)
{
res.Items.Add(it);
}
}
player.Trace("PayHandler.ProcessPayGetFreeItemReq uid {0} itemId {1} succ", player.UserID, req.ItemID);
SendToPlayer(player, (int)CSGameMsgID.PayGetFreeItemRes, ref res);
}
private void NotifyHttpPaySvrAddItemSucc(PlayerOnGame player, ref DBPaySuccWaitAddRole data)
{
var notify = new SSPayAddPlayerItemNotify();
var playerSession = GameServerUtils.GetPlayerTableOp().GetPlayerSessionByUid(player.UserID);
if (playerSession != null)
{
notify.CUid.SetString(playerSession.AccountInfo.AccountID.GetPtr());
notify.CName.SetString(playerSession.Nick);
notify.ChannelId = playerSession.channelId;
notify.ProductId.SetString(playerSession.clientInfo.pcode);
}
else
{
notify.CUid.SetString(player.AccountInfo.AccountID.GetPtr());
notify.CName.SetString(player.RoleBase.Nick.GetPtr());
notify.ChannelId = player.channelId;
notify.ProductId.SetString(player.clientInfo.pcode);
}
string orderId = data.OrderId.GetString();
var arr = orderId.Split('-');
if (arr.Length >= 8)
{
notify.GoodsId.SetString(arr[7]);
}
notify.OrderNo.SetString(data.OrderId3rd.GetPtr());
notify.CpOrderId.SetString(orderId);
notify.Amount = data.Amount;
notify.Unit.SetString(data.Currency.GetPtr());
notify.PayTime = data.PayTime3rd;
notify.RoleId = player.UserID;
notify.RoleName.SetString(player.RoleBase.Nick.GetPtr());
notify.RoleLevel = player.RoleBase.Level;
notify.VipLevel = player.RoleBase.VipLevel;
notify.TotalCharge = player.RoleData.PayData.TotalPayMoneyUSD;
notify.ServerId = player.RealmID;
var realm = GameServerUtils.GetRealmBriefInfo(player.RealmID);
if (realm != null)
{
notify.ServerName.SetString(realm.realmName);
}
notify.GetTime = GameServerUtils.GetTimeSecond();
notify.MoneyType = (int)CurrencyType.Diamond;
// 付款方式:1(sdk支付:常规付款操作)、2(虚拟支付:测试使用,无真实消费)、3(英雄线下付款)
notify.PaymentMethod = data.IsTestPay == 0 ? 1 : 2;
notify.IsTestPay = data.IsTestPay;
GameServerUtils.GetPacketSender().SendToWorldServer((int)SSGameMsgID.PayAddPlayerItemNotify, ref notify, player.UserID);
}
private void ProcessClientTriggerItemArriveReq(PlayerSession playerSession, StructPacket packet)
{
PlayerOnGame player = playerSession.Player;
if (player == null)
{
TraceLog.Trace("PayHandler.ProcessClientTriggerItemArriveReq no player, session id {0}", playerSession.SessionID);
return;
}
}
private void OnPayItemStockInfoReq(PlayerSession playerSession, StructPacket packet)
{
PlayerOnGame player = playerSession.Player;
if (player == null)
{
TraceLog.Trace("PayHandler.OnPayItemStockInfoReq no player, session id {0}", playerSession.SessionID);
return;
}
var realmStock = GameServerUtils.GetGameServerData().m_realmItemStock;
// gamesvr缓存中没有数据, 向worldsvr请求
if (!realmStock.TryGetValue(player.RealmID, out var realmInfo))
{
var ssReq = new SSPayItemStockInfoReq { RealmId = player.RealmID, ReqUid = player.UserID };
GameServerUtils.GetPacketSender().SendToWorldServer((int)SSGameMsgID.PayItemStockInfoReq, ref ssReq, player.UserID);
return;
}
var res = new CSPayItemStockInfoRes();
// realm的库存数据全部下发
foreach (ItemStockInfoOne stockInfo in realmInfo.stockDict.Values)
{
var item = new PayItemStockInfo();
item.ItemID = stockInfo.itemId;
item.Count = stockInfo.remainCount;
res.ItemInfo.Add(ref item);
}
SendToPlayer(player, (int)CSGameMsgID.PayItemStockInfoRes, ref res);
}
// 收到world的回包
public void OnPayItemStockInfoRes(uint serverID, StructPacket packet)
{
ref var res = ref packet.GetMessage<SSPayItemStockInfoRes>();
if (res.ItemInfo.Count == 0)
{
TraceLog.Trace("PayHandler.OnPayItemStockInfoRes realm {0} no stockInfo", res.RealmId);
return;
}
var realmInfo = new RealmItemStockInfo { realmId = res.RealmId };
for (int i = 0; i < res.ItemInfo.Count; i++)
{
var stockInfo = new ItemStockInfoOne
{
itemId = res.ItemInfo[i].ItemID,
remainCount = res.ItemInfo[i].Count
};
realmInfo.stockDict.Add(stockInfo.itemId, stockInfo);
TraceLog.Trace("PayHandler.OnPayItemStockInfoRes realm {0} item {1} count {2}"
, res.RealmId, stockInfo.itemId, stockInfo.remainCount);
}
// 刷新gamesvr的缓存
var realmStock = GameServerUtils.GetGameServerData().m_realmItemStock;
if (realmStock.ContainsKey(res.RealmId))
{
realmStock[res.RealmId] = realmInfo;
}
else
{
realmStock.Add(res.RealmId, realmInfo);
}
// 同步给玩家
if (res.ReqUid != 0)
{
PlayerOnGame player = GameServerUtils.GetPlayerTableOp().GetPlayerByUid(res.ReqUid);
if (player == null)
{
return;
}
var csRes = new CSPayItemStockInfoRes();
foreach (ItemStockInfoOne stockInfo in realmInfo.stockDict.Values)
{
var item = new PayItemStockInfo();
item.ItemID = stockInfo.itemId;
item.Count = stockInfo.remainCount;
csRes.ItemInfo.Add(ref item);
}
SendToPlayer(player, (int)CSGameMsgID.PayItemStockInfoRes, ref csRes);
}
}
public void OnNotifyItemStockInfo(uint serverID, StructPacket packet)
{
ref var notify = ref packet.GetMessage<SSNotifyItemStockInfo>();
var realmStock = GameServerUtils.GetGameServerData().m_realmItemStock;
if (realmStock.TryGetValue(notify.RealmId, out var realmInfo))
{
int itemId = notify.ItemInfo.ItemID;
if (realmInfo.stockDict.TryGetValue(itemId, out var stockInfo))
{
stockInfo.remainCount = notify.ItemInfo.Count;
}
}
}
public void ProcessFakePay(uint serverID, StructPacket packet)
{
ref var req = ref packet.GetMessage<SSOperationFakePay>();
bool success = false;
for (var i = 0; i < req.ItemId.Count; i++)
{
var ret = PayCommSvc.FakePay(req.Uid, req.ItemId[i]);
if (ret < 0)
{
success = false;
break;
}
success = true;
}
SSOperationFakePayRes res = new SSOperationFakePayRes();
res.Ret = success ? 0 : -1;
res.Id = req.Id;
res.Data = req.Data;
res.Uid = req.Uid;
GameServerUtils.GetPacketSender().SendToWorldServer((int)SSGameMsgID.OperationFakepayRes, ref res, req.Uid);
}
}
}