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.
441 lines
18 KiB
441 lines
18 KiB
1 month ago
|
using System;
|
||
|
using System.Text;
|
||
|
using Sog;
|
||
|
using Sog.Service;
|
||
|
using ProtoCSStruct;
|
||
|
using System.Text.Json;
|
||
|
using System.Web;
|
||
|
using System.Text.Json.Nodes;
|
||
|
using LitJson;
|
||
|
using System.Collections.Generic;
|
||
|
using System.Net.Http;
|
||
|
using Org.BouncyCastle.Crypto.Parameters;
|
||
|
using Org.BouncyCastle.Security;
|
||
|
using System.Security.Cryptography;
|
||
|
using Org.BouncyCastle.Crypto;
|
||
|
using System.IO;
|
||
|
using Org.BouncyCastle.OpenSsl;
|
||
|
using Org.BouncyCastle.Utilities.Encoders;
|
||
|
using System.Runtime.InteropServices;
|
||
|
using System.Security;
|
||
|
using static System.Net.Mime.MediaTypeNames;
|
||
|
using System.Security.Cryptography.X509Certificates;
|
||
|
using System.Linq;
|
||
|
using Org.BouncyCastle.Asn1.Ocsp;
|
||
|
using World;
|
||
|
|
||
|
namespace HttpProxyPay
|
||
|
{
|
||
|
public class HttpProxyPayMsgHandler : BaseReloadableService
|
||
|
{
|
||
|
private ServerApp m_app;
|
||
|
|
||
|
|
||
|
|
||
|
public override int GetServiceType()
|
||
|
{
|
||
|
return HttpProxyPayServiceType.HttpProxyMsgHandler;
|
||
|
}
|
||
|
|
||
|
//销毁的时候置空
|
||
|
public override void Dispose()
|
||
|
{
|
||
|
m_app = null;
|
||
|
}
|
||
|
|
||
|
public HttpProxyPayMsgHandler(ServerApp app)
|
||
|
{
|
||
|
m_app = app;
|
||
|
}
|
||
|
|
||
|
public ServerApp GetApp()
|
||
|
{
|
||
|
return m_app;
|
||
|
}
|
||
|
|
||
|
public void HandlerMessage(uint remoteAppID, MessageData message)
|
||
|
{
|
||
|
StructPacket packet;
|
||
|
bool bSuccess = HttpProxyPayServerUtils.GetProtoPacker().UnpackMessage(message, out packet);
|
||
|
if(bSuccess == false)
|
||
|
{
|
||
|
TraceLog.Error("HttpProxyPayMsgHandler.HandlerMessage ,unpack msg failed {0}, remoteAppID {1}"
|
||
|
, message.Header.Type, remoteAppID);
|
||
|
return;
|
||
|
}
|
||
|
|
||
|
//消息多线程处理,这里需要clone一个才行
|
||
|
packet = packet.Clone();
|
||
|
|
||
|
//预先判断,提高效率
|
||
|
if (TraceLog.GetLogLevel() <= Sog.Log.LogLevel.TraceDetail
|
||
|
&& TraceLog.IsSkipLogMsgID(packet.MsgID) == false)
|
||
|
{
|
||
|
TraceLog.TraceDetail("HttpProxyPayMsgHandler.HandlerMessage recv message from server {0}, message type {1} length {2} : {3}->{4}"
|
||
|
, ServerIDUtils.IDToString(remoteAppID)
|
||
|
, message.Header.Type
|
||
|
, message.Header.Length
|
||
|
, packet.MessageName()
|
||
|
, packet.ToString());
|
||
|
}
|
||
|
|
||
|
|
||
|
switch (packet.MsgID)
|
||
|
{
|
||
|
//转给db处理
|
||
|
case (int)SSGameMsgID.PayGoogleReq:
|
||
|
OnPayGoogleReq(remoteAppID, packet);
|
||
|
break;
|
||
|
|
||
|
// 请求订单存DB成功, 转给gamesvr继续处理
|
||
|
case (int)SSGameMsgID.PayGoogleRes:
|
||
|
OnPayGoogleRes(remoteAppID, packet);
|
||
|
break;
|
||
|
|
||
|
// 处理客户端发起的支付成功通知, 比如google支付, 华为支付
|
||
|
case (int)SSGameMsgID.PayGoogleSuccessReq:
|
||
|
OnPayGoogleSuccReq(remoteAppID, packet);
|
||
|
break;
|
||
|
|
||
|
// DB支付状态修改为支付成功, 转给gamesvr预备加钱
|
||
|
case (int)SSGameMsgID.PayGoogleSuccessRes:
|
||
|
OnPayGoogleSuccRes(remoteAppID, packet);
|
||
|
break;
|
||
|
|
||
|
// DB支付状态修改为加钻石成功
|
||
|
case (int)SSGameMsgID.PayDbAddDiamondStatusReq:
|
||
|
OnDBAddDiamondStatusReq(remoteAppID, packet);
|
||
|
break;
|
||
|
|
||
|
// DB支付状态修改为已加钱, 转给gamesvr真正加钱
|
||
|
case (int)SSGameMsgID.PayDbAddDiamondStatusRes:
|
||
|
OnDBAddDiamondStatusRes(remoteAppID, packet);
|
||
|
break;
|
||
|
|
||
|
// 玩家上线时会查询所有支付成功但没有加钻石的订单, 并且触发后续加钱操作
|
||
|
case (int)SSGameMsgID.QueryPayGoogleSuccOrder:
|
||
|
OnQueryPayGoogleSuccOrder(remoteAppID, packet);
|
||
|
break;
|
||
|
|
||
|
// gm测试支付
|
||
|
case (int)SSGameMsgID.GmTestHeroPaySucc:
|
||
|
OnGMTestHeroPaySucc(remoteAppID, packet);
|
||
|
break;
|
||
|
|
||
|
// 退款
|
||
|
case (int)SSGameMsgID.PaySendDbRefundRes:
|
||
|
OnPaySendDBRefundRes(remoteAppID, packet);
|
||
|
break;
|
||
|
|
||
|
case (int)SSGameMsgID.PayAddPlayerItemNotify:
|
||
|
OnPayAddPlayerItemNotify(remoteAppID, packet);
|
||
|
break;
|
||
|
|
||
|
case (int)SSGameMsgID.PayHeroSaveHttpContentRes:
|
||
|
OnSaveHttpContentRes(remoteAppID, packet);
|
||
|
break;
|
||
|
|
||
|
case (int)SSGameMsgID.PayHeroSelectHttpContentRes:
|
||
|
OnSelectHttpContentRes(remoteAppID, packet);
|
||
|
break;
|
||
|
|
||
|
case (int)SSGameMsgID.HomeAdSendHttpSyn:
|
||
|
OnHomeAdSendHttpSyn(remoteAppID, packet);
|
||
|
break;
|
||
|
case (int)CSGameMsgID.PayWsjsapiReq:
|
||
|
PayWsjsapiReq(remoteAppID, packet);
|
||
|
break;
|
||
|
|
||
|
default:
|
||
|
TraceLog.Error("HttpProxyPayMsgHandler.HandlerMessage unknow MsgID {0}", packet.MsgID);
|
||
|
break;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
private void OnPayGoogleReq(uint remoteAppID, StructPacket packet)
|
||
|
{
|
||
|
var player = HttpProxyPayServerUtils.GetPlayerTableOp().GetPlayer(packet.ObjectID);
|
||
|
if (player == null)
|
||
|
{
|
||
|
player = new PlayerOnPay {uid = packet.ObjectID, worldSvrId = remoteAppID};
|
||
|
HttpProxyPayServerUtils.GetPlayerTableOp().AddPlayer(player);
|
||
|
}
|
||
|
|
||
|
player.lastPayReqTime = (int) HttpProxyPayServerUtils.GetTimeSecond();
|
||
|
|
||
|
ref var req = ref packet.GetMessage<SSPayGoogleReq>();
|
||
|
string orderId = req.OrderId.GetString();
|
||
|
string[] split = orderId.Split('-');
|
||
|
|
||
|
// uid-time-orderIdSeq-serverId-payitemId-payParam1-payParam2-paymentId
|
||
|
if (split.Length != 8)
|
||
|
{
|
||
|
TraceLog.Error("HttpProxyPayMsgHandler.OnPayGoogleReq invalid orderId {0}, must 8 params", orderId);
|
||
|
|
||
|
var res = new SSPayGoogleRes();
|
||
|
res.Ret = -1;
|
||
|
res.Uid = req.Uid;
|
||
|
res.ItemID = req.ItemID;
|
||
|
res.OrderId = req.OrderId;
|
||
|
res.Diamond = req.Diamond;
|
||
|
res.Money = req.Money;
|
||
|
res.GmTestPay = req.GmTestPay;
|
||
|
res.PayType = req.PayType;
|
||
|
res.PaymentId = req.PaymentId;
|
||
|
HttpProxyPayServerUtils.GetPacketSender().SendToServerByID(remoteAppID
|
||
|
, (int)SSGameMsgID.PayGoogleRes, ref res, packet.ObjectID);
|
||
|
return;
|
||
|
}
|
||
|
|
||
|
var svrData = HttpProxyPayServerUtils.GetHttpProxyServerData();
|
||
|
req.OrderId.SetString($"{orderId}-{svrData.selfPayId}");
|
||
|
|
||
|
uint dbServerID = DBServerSelect.GetDBServerID(packet.ObjectID);
|
||
|
HttpProxyPayServerUtils.GetPacketSender().SendToServerByID(dbServerID
|
||
|
, (int)SSGameMsgID.PayGoogleReq, ref req, packet.ObjectID);
|
||
|
}
|
||
|
|
||
|
|
||
|
private void OnPayGoogleRes(uint remoteAppID, StructPacket packet)
|
||
|
{
|
||
|
ref var res = ref packet.GetMessage<SSPayGoogleRes>();
|
||
|
TraceLog.Trace("HttpProxyPayMsgHandler.OnPayGoogleRes orderId {0} httpCtx {1} uid {2} ret {3}"
|
||
|
, res.OrderId, res.HttpCtxId, res.Uid, res.Ret);
|
||
|
|
||
|
// gamesvr发起的PayGoogleReq的HttpCtxId是0
|
||
|
// HttpCtxId != 0表示Hero网页商城发起的下单请求, 需要回复订单号, http应答交给线程去处理
|
||
|
if (res.PayType == (int)PayType.Hero && res.HttpCtxId != 0)
|
||
|
{
|
||
|
int iTaskIndex = (int)(res.Uid % HttpProxyPayServerUtils.HttpWorkThreadCount);
|
||
|
TraceLog.Debug("HttpProxyPayMsgHandler.OnPayGoogleRes uid {0} distribute to task {1}", res.Uid, iTaskIndex);
|
||
|
|
||
|
MessageTaskDistributor.Instance.Distribute(remoteAppID, packet, iTaskIndex);
|
||
|
return;
|
||
|
}
|
||
|
//minipay
|
||
|
if (res.PayType == (int)PayType.MiniPay)
|
||
|
{
|
||
|
res.OfferId.SetString(HttpProxyPayServerUtils.GetServerConfig().offerId);
|
||
|
res.Appkey.SetString(HttpProxyPayServerUtils.GetServerConfig().appkey);
|
||
|
}
|
||
|
|
||
|
var player = HttpProxyPayServerUtils.GetPlayerTableOp().GetPlayer(packet.ObjectID);
|
||
|
if (player != null)
|
||
|
{
|
||
|
HttpProxyPayServerUtils.GetPacketSender().SendToServerByID<SSPayGoogleRes>(player.worldSvrId, packet);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
// 成功支付触发的PayGoogleSuccRes
|
||
|
private void OnPayGoogleSuccRes(uint remoteAppID, StructPacket packet)
|
||
|
{
|
||
|
ref var res = ref packet.GetMessage<SSPayGoogleSuccessRes>();
|
||
|
TraceLog.Trace("HttpProxyPayMsgHandler.OnPayGoogleSuccRes orderId {0} httpCtx {1} uid {2} ret {3}"
|
||
|
, res.OrderId, res.HttpCtxId, res.Uid, res.Ret);
|
||
|
|
||
|
var player = HttpProxyPayServerUtils.GetPlayerTableOp().GetPlayer(res.Uid);
|
||
|
if (player != null)
|
||
|
{
|
||
|
HttpProxyPayServerUtils.GetPacketSender().SendToServerByID<SSPayGoogleSuccessRes>(player.worldSvrId, packet);
|
||
|
}
|
||
|
else if (res.Ret == 0 && (res.PayType == (int)PayType.Hero || res.PayType == (int)PayType.MiniPay))
|
||
|
{
|
||
|
// 英雄网页商城支付成功时, PaySvr可能没有player缓存, 直接转发到worldsvr去确认player是否在线
|
||
|
int itemId = res.ItemID;
|
||
|
var desc = PayDiamondDescMgr.Instance.GetConfig(itemId);
|
||
|
if (desc == null)
|
||
|
{
|
||
|
TraceLog.Error("HttpProxyPayMsgHandler.OnPayGoogleSuccRes {0} no desc", itemId);
|
||
|
return;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
// login发起的查询操作触发的PayGoogleSuccRes的HttpCtxId是0
|
||
|
// HttpCtxId != 0表示Hero支付服务器发起的Http回调, 需要回复succ, http应答交给线程去处理
|
||
|
if (res.Ret == 0 && (res.PayType == (int)PayType.Hero || res.PayType == (int)PayType.MiniPay) && res.HttpCtxId != 0)
|
||
|
{
|
||
|
int iTaskIndex = (int)(res.Uid % HttpProxyPayServerUtils.HttpWorkThreadCount);
|
||
|
TraceLog.Debug("HttpProxyPayMsgHandler.OnPayGoogleSuccRes uid {0} distribute to task {1}", res.Uid, iTaskIndex);
|
||
|
|
||
|
MessageTaskDistributor.Instance.Distribute(remoteAppID, packet, iTaskIndex);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
private void OnDBAddDiamondStatusReq(uint remoteAppID, StructPacket packet)
|
||
|
{
|
||
|
var player = HttpProxyPayServerUtils.GetPlayerTableOp().GetPlayer(packet.ObjectID);
|
||
|
if (player == null)
|
||
|
{
|
||
|
player = new PlayerOnPay { uid = packet.ObjectID, worldSvrId = remoteAppID };
|
||
|
HttpProxyPayServerUtils.GetPlayerTableOp().AddPlayer(player);
|
||
|
}
|
||
|
|
||
|
player.lastPayReqTime = (int)HttpProxyPayServerUtils.GetTimeSecond();
|
||
|
|
||
|
uint dbServerID = DBServerSelect.GetDBServerID(packet.ObjectID);
|
||
|
HttpProxyPayServerUtils.GetPacketSender().SendToServerByID<SSPayDBAddDiamondStatusReq>(dbServerID, packet);
|
||
|
}
|
||
|
|
||
|
private void OnDBAddDiamondStatusRes(uint remoteAppID, StructPacket packet)
|
||
|
{
|
||
|
var player = HttpProxyPayServerUtils.GetPlayerTableOp().GetPlayer(packet.ObjectID);
|
||
|
if (player != null)
|
||
|
{
|
||
|
HttpProxyPayServerUtils.GetPacketSender().SendToServerByID<SSPayDBAddDiamondStatusRes>(player.worldSvrId, packet);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
private void OnQueryPayGoogleSuccOrder(uint remoteAppID, StructPacket packet)
|
||
|
{
|
||
|
ref var req = ref packet.GetMessage<SSQueryPayGoogleSuccOrder>();
|
||
|
|
||
|
var player = HttpProxyPayServerUtils.GetPlayerTableOp().GetPlayer(req.Uid);
|
||
|
if (player == null)
|
||
|
{
|
||
|
player = new PlayerOnPay { uid = req.Uid, worldSvrId = remoteAppID };
|
||
|
HttpProxyPayServerUtils.GetPlayerTableOp().AddPlayer(player);
|
||
|
}
|
||
|
|
||
|
player.lastPayReqTime = (int)HttpProxyPayServerUtils.GetTimeSecond();
|
||
|
|
||
|
uint dbServerID = DBServerSelect.GetDBServerID(req.Uid);
|
||
|
HttpProxyPayServerUtils.GetPacketSender().SendToServerByID<SSQueryPayGoogleSuccOrder>(dbServerID, packet);
|
||
|
}
|
||
|
|
||
|
private void OnGMTestHeroPaySucc(uint remoteAppID, StructPacket packet)
|
||
|
{
|
||
|
ref var testReq = ref packet.GetMessage<SSGMTestHeroPaySucc>();
|
||
|
|
||
|
var player = HttpProxyPayServerUtils.GetPlayerTableOp().GetPlayer(testReq.Uid);
|
||
|
if (player == null)
|
||
|
{
|
||
|
player = new PlayerOnPay { uid = testReq.Uid, worldSvrId = remoteAppID };
|
||
|
HttpProxyPayServerUtils.GetPlayerTableOp().AddPlayer(player);
|
||
|
}
|
||
|
|
||
|
player.lastPayReqTime = (int)HttpProxyPayServerUtils.GetTimeSecond();
|
||
|
|
||
|
var req = new SSPayGoogleSuccessReq { Uid = testReq.Uid, PayType = (uint)testReq.PayType, CheckSuccess3rd = 1 };
|
||
|
req.ItemID = testReq.ItemID;
|
||
|
req.PurchaseData.SetString("gm_test_no_data");
|
||
|
req.Signature.SetString("gm_test_no_signature");
|
||
|
req.OrderId.SetString(testReq.OrderId.GetPtr());
|
||
|
req.OrderId3rd.SetString(testReq.OrderId3rd.GetPtr());
|
||
|
req.Amount = (uint)testReq.MoneyUSD;
|
||
|
if(testReq.PayType == (int)PayType.Hero)
|
||
|
{
|
||
|
req.Currency.SetString("USD");
|
||
|
}
|
||
|
else if(testReq.PayType == (int)PayType.MiniPay)
|
||
|
{
|
||
|
req.Currency.SetString("CNY");
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
req.Currency.SetString("USD");
|
||
|
}
|
||
|
req.PayParam1 = testReq.PayParam1;
|
||
|
req.PayParam2 = testReq.PayParam2;
|
||
|
req.GmTestPay = true;
|
||
|
req.PayTime3rd = testReq.PayTime;
|
||
|
|
||
|
uint dbServerID = DBServerSelect.GetDBServerID(testReq.Uid);
|
||
|
HttpProxyPayServerUtils.GetPacketSender().SendToServerByID(dbServerID, (int)SSGameMsgID.PayGoogleSuccessReq, ref req, req.Uid);
|
||
|
}
|
||
|
|
||
|
private void OnPaySendDBRefundRes(uint remoteAppID, StructPacket packet)
|
||
|
{
|
||
|
ref var res = ref packet.GetMessage<SSPaySendDBRefundRes>();
|
||
|
|
||
|
int iTaskIndex = (int)(res.Uid % HttpProxyPayServerUtils.HttpWorkThreadCount);
|
||
|
TraceLog.Debug("HttpProxyPayMsgHandler.OnPaySendDBRefundRes uid {0} distribute to task {1}", res.Uid, iTaskIndex);
|
||
|
|
||
|
MessageTaskDistributor.Instance.Distribute(remoteAppID, packet, iTaskIndex);
|
||
|
}
|
||
|
|
||
|
private void OnPayAddPlayerItemNotify(uint remoteAppID, StructPacket packet)
|
||
|
{
|
||
|
ref var notify = ref packet.GetMessage<SSPayAddPlayerItemNotify>();
|
||
|
HeroUSDKSvc.OnPayAddItemNotify(ref notify);
|
||
|
}
|
||
|
|
||
|
private void OnSaveHttpContentRes(uint remoteAppID, StructPacket packet)
|
||
|
{
|
||
|
ref var res = ref packet.GetMessage<SSPayHeroSaveHttpContentRes>();
|
||
|
|
||
|
int iTaskIndex = (int)(res.Http.Uid % HttpProxyPayServerUtils.HttpWorkThreadCount);
|
||
|
TraceLog.Debug("HttpProxyPayMsgHandler.OnSaveHttpContentRes uid {0} distribute to task {1}", res.Http.Uid, iTaskIndex);
|
||
|
|
||
|
MessageTaskDistributor.Instance.Distribute(remoteAppID, packet, iTaskIndex);
|
||
|
}
|
||
|
|
||
|
private void OnSelectHttpContentRes(uint remoteAppID, StructPacket packet)
|
||
|
{
|
||
|
ref var res = ref packet.GetMessage<SSPayHeroSelectHttpContentRes>();
|
||
|
if (res.Http.Count > 0)
|
||
|
{
|
||
|
TraceLog.Debug("HttpProxyPayMsgHandler.OnSelectHttpContentRes distribute to task 0");
|
||
|
|
||
|
// 交给线程1处理, 此条消息频率比较低, 正常情况下不会有太多条记录未提交, http发货通知可以慢慢处理, 只要不卡主线程就好
|
||
|
MessageTaskDistributor.Instance.Distribute(remoteAppID, packet, 0);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
private void OnPayGoogleSuccReq(uint remoteAppID, StructPacket packet)
|
||
|
{
|
||
|
ref var req = ref packet.GetMessage<SSPayGoogleSuccessReq>();
|
||
|
TraceLog.Trace("HttpProxyPayMsgHandler.OnPayGoogleSuccReq uid {0} payType {1}", req.Uid, (PayType)req.PayType);
|
||
|
|
||
|
var player = HttpProxyPayServerUtils.GetPlayerTableOp().GetPlayer(packet.ObjectID);
|
||
|
if (player == null)
|
||
|
{
|
||
|
player = new PlayerOnPay { uid = packet.ObjectID, worldSvrId = remoteAppID };
|
||
|
HttpProxyPayServerUtils.GetPlayerTableOp().AddPlayer(player);
|
||
|
}
|
||
|
|
||
|
player.lastPayReqTime = (int)HttpProxyPayServerUtils.GetTimeSecond();
|
||
|
|
||
|
if (req.PayType == (int)PayType.Google)
|
||
|
{
|
||
|
GooglePaySvc.OnCltPayGoogleSuccReq(remoteAppID, ref req);
|
||
|
}
|
||
|
else if (req.PayType == (int)PayType.Huawei)
|
||
|
{
|
||
|
HuaweiPaySvc.OnCltPayGoogleSuccReq(remoteAppID, packet);
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
TraceLog.Error("HttpProxyPayMsgHandler.OnPayGoogleSuccReq uid {0} invalid payType {1}"
|
||
|
, req.Uid, (PayType)req.PayType);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
private void OnHomeAdSendHttpSyn(uint remoteAppID, StructPacket packet)
|
||
|
{
|
||
|
//添加用户信息
|
||
|
var player = HttpProxyPayServerUtils.GetPlayerTableOp().GetPlayer(packet.ObjectID);
|
||
|
if (player == null)
|
||
|
{
|
||
|
player = new PlayerOnPay { uid = packet.ObjectID, worldSvrId = remoteAppID , lastAdTime = HttpProxyPayServerUtils.GetTimeSecond()};
|
||
|
HttpProxyPayServerUtils.GetPlayerTableOp().AddPlayer(player);
|
||
|
}
|
||
|
}
|
||
|
public static void PayWsjsapiReq(uint remoteAppID, StructPacket packet)
|
||
|
{
|
||
|
|
||
|
ref var req = ref packet.GetMessage<CSWXJSPayReq>();
|
||
|
|
||
|
int iTaskIndex = (int)(req.Uid % HttpProxyPayServerUtils.HttpWorkThreadCount); ;
|
||
|
|
||
|
MessageTaskDistributor.Instance.Distribute(remoteAppID, packet, iTaskIndex);
|
||
|
|
||
|
TraceLog.Debug("HttpProxyMsgHandler.PayWsjsapiReq type {0} distribute to task {1}"
|
||
|
, req.Uid
|
||
|
, iTaskIndex);
|
||
|
|
||
|
}
|
||
|
|
||
|
|
||
|
}
|
||
|
}
|