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.
 
 
 
 
 
 

1054 lines
40 KiB

using System.Net.Http.Headers;
using System;
using System.Collections.Generic;
using System.Linq;
using Sog;
using ProtoCSStruct;
using Sog.Log;
namespace Game
{
public static class PayCommSvc
{
// 注意: 所有的首次/第一次的限定条件, 不能和其他条件组合, 除非策划保证首次条件一定在最后满足, 否则可能会失败!!!!!!
// 例如: 首次10连抽获得2张紫卡, 同时vip等级超过5级, 可能满足首次条件时, vip等级不满足
// 等vip等级满足时, 首次条件已经不可能再达成, 从而导致无法触发
//enum PayLimitEvent
//{
// PlayerBorn = 1,
// VipLevel = 2,
// PlayerLevel = 3,
// SystemFuncId = 4,
// MainlineFail3BeforeChapter6 = 5, // 主线前6章连续失败3次
// EquipIntensify = 6, // 装备强化次数
// CommDraw = 7, // 高抽
// RaceDraw = 8, // 定向抽
// UpPoolDraw = 9, // 限定抽
// FirstPGRelease = 10, // 共鸣水晶首次卸下英雄
// First2PurpleDraw10 = 11, // 首次一次10连抽获得2张紫卡
// FirstDrawRealPurpleCard = 12, // 首次抽到紫卡, 即获得第4张紫卡, 前3张是固定送的不算
// FirstUseItemAddHero45 = 13, // 首次兑换RaceType为4或5的英雄
// MainlandFinish = 14,
// RealmOpen = 15, // 开服
// GetEquipRed = 16, // 获得红色装备
// HeroWeaponUnlock = 17, // 专武解锁
//}
public static readonly string FreeGiftPack = "FreeGiftPack";
public static readonly int MaxPayMoneyValidTime = 7 * 86400;
// 月卡叠加购买限制时间
public static readonly int MonthlyCardLimitDays = 30;
// 月卡有效时长
public static readonly int MonthlyCardValidTime = 30 * 86400;
public static readonly int WeeklyCardLimitDays = 7;
public static readonly int WeeklyCardValidTime = 7 * 86400;
public static readonly int WeekSec = 7 * 86400;
public static readonly string MonthlyCardDailyMailTitle = "#Mail36";
public static readonly string MonthlyCardDailyMailContent = "#Mail37";
// 周卡领取邮件的内容暂时和月卡一致
public static readonly string WeeklyCardDailyMailTitle = "#Mail36";
public static readonly string WeeklyCardDailyMailContent = "#Mail37";
public static readonly string VipWeeklyMailTitle = "#Mail40";
public static readonly string VipWeeklyMailContent = "#Mail41";
public static readonly string[] PrepayItemMailTitle = { "#Mail51", "#Mail54" };
public static readonly string[] PrepayItemMailContent = { "#Mail52", "#Mail_103" };
public static void OnPlayerOnline(PlayerOnGame player)
{
player.Trace("PayCommSvc.OnPlayerOnline player {0} ", player.UserID);
int nowSec = (int)GameServerUtils.GetTimeSecond();
// 先更新玩家身上的支付数据, 如果其他逻辑依赖最新的支付数据, 那么不要把代码写在该函数前面
UpdatePlayerPayRecord(player, nowSec, false);
AddNewItemOnPlayerOnline(player);
//CheckSendMonthlyCardDailyReward(player, nowSec);
//CheckSendVipWeeklyReward(player, nowSec);
// 每次上线清掉失败次数, 开始尝试加钱
for (int i = 0; i < player.RoleData.PayData.PaySuccWaitAddRole.Count; i++)
{
player.RoleData.PayData.PaySuccWaitAddRole[i].DbResFailCount = 0;
// 平滑一下时间
player.RoleData.PayData.PaySuccWaitAddRole[i].LastSendDBTime = nowSec + i;
}
// 华为等着客户端发起补单流程, 因为DB没有保存inAppPurchaseData
if (player.AccountInfo.AccountType != (int)AccountType.AccountType_Huawei)
{
var query = new SSQueryPayGoogleSuccOrder { Uid = player.UserID };
GameServerUtils.GetPacketSender().SendToWorldServer((int)SSGameMsgID.QueryPayGoogleSuccOrder, ref query, player.UserID);
}
}
public static void OnNewDayStart(PlayerOnGame player, bool notifyClient)
{
player.Trace("PayCommSvc.OnNewDayStart player {0} ", player.UserID);
int nowSec = (int)GameServerUtils.GetTimeSecond();
// 先更新玩家身上的支付数据, 如果其他逻辑依赖最新的支付数据, 那么不要把代码写在该函数前面
UpdatePlayerPayRecord(player, nowSec, notifyClient);
AddNewItemOnPlayerOnline(player);
}
public static void OnPlayerLevelUp(PlayerOnGame player)
{
}
public static void OnVipLevelUp(PlayerOnGame player)
{
UpdateVipWeeklyRewardStartTime(player);
}
// 统计数据变化
public static void OnTotalStatisticsChanged(PlayerOnGame player, int statId, long newVal, long chgVal)
{
//if (statId == (int) CSRoleStatisticsID.EquipIntensifyNum)
//{
// CheckNewItemOnEvent(player, PayLimitEvent.EquipIntensify, (int) newVal, 0);
//}
}
public static void OnAddHero(PlayerOnGame player, int descId, int star, string reason)
{
}
private static void UpdateVipWeeklyRewardStartTime(PlayerOnGame player)
{
if (player.RoleData.PayData.StartVipWeeklyRewardTime > 0)
{
return;
}
// 升级到满足vip周奖励的时间
int rewardLv = 0;//CommParamDescMgr.Instance.GetConfig((int)CommParamKey.VipWeeklyRewardLevel).int_val;
if (player.RoleBase.VipLevel < rewardLv)
{
return;
}
var configRealm = GameServerUtils.GetGameServerData().m_configRealm;
var realmBrief = configRealm.FirstOrDefault(r => r.realmId == player.RealmID);
if (realmBrief == null || realmBrief.openTime == 0)
{
return;
}
long startTime = AppTime.GetTodayStartTime(realmBrief.openTime);
long week = (GameServerUtils.GetTimeSecond() - startTime) / WeekSec;
player.RoleData.PayData.StartVipWeeklyRewardTime = (int)(startTime + week * WeekSec);
player.Debug("PayCommSvc.UpdateVipWeeklyRewardStartTime player {0} week {1} start time {2}"
, player.UserID, week, player.RoleData.PayData.StartVipWeeklyRewardTime);
}
// public static void DeleteItemData(PlayerOnGame player, PayLimitEvent limitEvent,int value)
// {
// //删除指定
// for (int i = player.RoleData.PayData.PayItemRecord.Count - 1; i >= 0 ; i--)
// {
// ref var record = ref player.RoleData.PayData.PayItemRecord[i];
// PayDiamondDesc desc = PayCommSvc.GetPayDiamondDesc(record.ItemId);
// if (desc != null && desc.timeLimitType == (int)limitEvent)
// {
// if (desc.vipCardType <= 0 || PlayerPayUtil.GetMonthlyCardRemainDays(player, (VipCardType)desc.vipCardType) <= 0)
// {
// player.RoleData.PayData.PayItemRecord.RemoveAt(i);
// }
// }
// }
// }
private static void CheckNewItemOnEvent(PlayerOnGame player,
PayLimitEvent limitEvent, int value, int value2,int timeLimitParam2 = 0)
{
foreach (PayDiamondDesc desc in PayDiamondDescMgr.Instance.ItemTable.Values)
{
// 特殊条件, 限时商品, 通行证, 在满足条件时需要记录额外的数据, 并通知客户端
// 如果不是这几类商品, 客户端会判断是否显示在商城中
if (! CheckEventCond(player, desc, limitEvent, value, value2))
{
continue;
}
NewItemArrival(player, desc, (int)limitEvent);
}
}
// PayLimitEvent发生时检查是否满足配置要求
private static bool CheckEventCond(PlayerOnGame player, PayDiamondDesc desc,
PayLimitEvent limitEvent, int value, int value2)
{
switch (limitEvent)
{
default:
TraceLog.Error("PayCommSvc.CheckEventCond uid {0} {1} not hanle", player.UserID, limitEvent);
break;
}
return false;
}
// 月卡/周卡属于时长类卡, 保存在RoleData.PayData.MonthlyCard
public static bool IsTimeCard(int type)
{
return IsMonthlyCard(type);
}
public static bool IsMonthlyCard(int cardId)
{
var desc = MonthlyCardDescMgr.Instance.GetConfig(cardId);
return desc != null;
}
public static bool IsOneClickDailyPack(int itemId)
{
var desc = PayDiamondDescMgr.Instance.GetConfig(itemId);
return desc is { goodsType: PayGoodsType.DailyPack, itemID: PayDiamondId.DailyPack4 };
}
public static int[] SubDailyPackIds()
{
return new[] { PayDiamondId.DailyPack1, PayDiamondId.DailyPack2, PayDiamondId.DailyPack3 };
}
public static long GetBuyOneClickDailyPackDiamond(PlayerOnGame player, int itemId)
{
if (!IsOneClickDailyPack(itemId))
{
return 0;
}
var ret = 0L;
var list = SubDailyPackIds();
for (int i = 0; i < list.Length; i++)
{
var add = false;
var tempDesc = PayDiamondDescMgr.Instance.GetConfig(list[i]);
for (int j = 0; j < player.RoleData.PayData.PayItemRecord.Count; j++)
{
var record = player.RoleData.PayData.PayItemRecord[j];
if (list[i] == record.ItemId)
{
if (record.PayCountToday > 0)
{
add = true;
continue;
}
//今天购买了总礼包就不能购买子礼包了
ret += tempDesc.diamond;
add = true;
}
}
if (!add)
{
ret += tempDesc.diamond;
}
}
return ret;
}
public static TypeIDValueString[] GetBuyOneClickDailyPackGiveItem(PlayerOnGame player, int itemId)
{
if (!IsOneClickDailyPack(itemId))
{
return Array.Empty<TypeIDValueString>();
}
var list = new List<TypeIDValueString>();
var listIds = SubDailyPackIds();
for (int i = 0; i < listIds.Length; i++)
{
var add = false;
var tempDesc = PayDiamondDescMgr.Instance.GetConfig(listIds[i]); //今天购买了总礼包就不能购买子礼包了
for (int j = 0; j < player.RoleData.PayData.PayItemRecord.Count; j++)
{
var record = player.RoleData.PayData.PayItemRecord[j];
if (listIds[i] == record.ItemId)
{
if (record.PayCountToday > 0)
{
add = true;//今天购买了总礼包就不能购买子礼包了
continue;
}
var giveItem = tempDesc.giveItem;
foreach (var give in giveItem)
{
GenericUtils.Merge(list, give.type,give.id, give.count);
}
add = true;
break;
}
}
if (!add)
{
var giveItem = tempDesc.giveItem;
foreach (var give in giveItem)
{
GenericUtils.Merge(list, give.type,give.id, give.count);
}
}
}
return list.ToArray();
}
// 新品上架, 是否上架的逻辑应该在调用此接口之前完成
private static void NewItemArrival(PlayerOnGame player, PayDiamondDesc desc, int triggerEvent)
{
player.Trace("PayCommSvc.NewItemArrival uid {0} itemId {1}", player.UserID, desc.itemID);
// 特殊条件, 或者限时Item, 增加一条PaySuccRecord记录
if ( PlayerPayUtil.GetPaySuccessRecordIndex(player, desc.itemID) == -1)
{
PlayerPayUtil.AddPaySuccRecordIfNotExist(player, desc);
PlayerNotify.NotifyPlayerPayDataChange(player);
var notify = new CSPayNewItemNotify();
notify.ItemID = desc.itemID;
notify.TriggerEvent = triggerEvent;
player.SendToClient((int) CSGameMsgID.PayNewItemNotify, ref notify);
}
}
public static PayDiamondDesc GetPayDiamondDesc(int itemid)
{
// 目前商城策划只配置了一种支付类型的商品
return PayDiamondDescMgr.Instance.GetConfig(itemid);
}
public static int CheckPayLimit(PlayerOnGame player, PayDiamondDesc desc,PayLimitEvent excludeType = 0)
{
if (desc == null)
{
player.Error("PayCommSvc.CheckPayLimit uid {0} desc is null", player.UserID);
return -1;
}
if (desc.vipCardType > 0)
{
// 月卡/周卡
if (IsTimeCard(desc.vipCardType))
{
int remainDays = PlayerPayUtil.GetMonthlyCardRemainDays(player, desc.vipCardType);
int limitDays = GetMonthlyCardLimitDay((VipCardType) desc.vipCardType);
if (remainDays > limitDays)
{
player.Trace("PayCommSvc.CheckPayLimit uid {0} MonthlyCard {1} remainDays {2} should <= {3}"
, player.UserID, desc.vipCardType, remainDays, limitDays);
return -1;
}
// 数据不够存储了
int idx = PlayerPayUtil.GetMonthlyCardDataIndex(player, desc.vipCardType);
if (idx == -1 && player.RoleData.PayData.MonthlyCard.Count >= player.RoleData.PayData.MonthlyCard.GetMaxCount())
{
player.Error("PayCommSvc.CheckPayLimit uid {0} MonthlyCard {1} not enough Length"
, player.UserID, desc.vipCardType);
return -1;
}
}
}
{
int recordIndex = PlayerPayUtil.GetPaySuccessRecordIndex(player, desc.itemID);
if (recordIndex != -1)
{
ref DBRolePayItemRecord record = ref PlayerPayUtil.GetPayItemRecordByIndex(player, recordIndex);
// 有效支付时间
if (record.EndTime > 0 && (int)GameServerUtils.GetTimeSecond() >= record.EndTime)
{
player.Error("PayCommSvc.CheckPayLimit uid {0} payItem {1} endTime {2} not valid pay time"
, player.UserID, desc.itemID, record.EndTime);
return (int)CSErrCode.PayItemNotValid;
}
}
// 校验特殊限制条件
if (desc.timeLimitType > 0 && desc.timeLimitType != (int)excludeType && !CheckPayTimeLimit(player, desc))
{
player.Error("PayCommSvc.CheckPayLimit itemId {0} timeLimitType {1} check failed"
, desc.itemID, desc.timeLimitType);
return (int)CSErrCode.PayItemNotValid;
}
//总购买次数限制
if (CheckPayTimesLimit(player, desc))
{
player.Error("PayCommSvc.CheckPayLimit itemId {0} timeLimitType {1} buy count limit check failed"
, desc.itemID, desc.timeLimitType);
return (int)CSErrCode.PayItemNotValid;
}
//今日购买次数限制
if (CheckPayTimesDailyLimit(player, desc))
{
player.Error(
"PayCommSvc.CheckPayLimit itemId {0} timeLimitType {1} day buy count limit check failed"
, desc.itemID, desc.timeLimitType);
return (int)CSErrCode.PayItemNotValid;
}
}
// 指定时间之后充值1笔后可免费领取的礼包
if (CheckValidFixedPayTime(desc) != 0)
{
return (int)CSErrCode.PayInvalidTime;
}
//章节礼包
if (desc.goodsType == PayGoodsType.ChapterPack && desc.chapterCondition.Length == 2)
{
var chapterId = desc.chapterCondition[0];
var battleId = desc.chapterCondition[1];
if (chapterId > player.RoleData.ChapterData.ChapterId)
{
return (int)CSErrCode.PayItemNotValid;
}
if (battleId > player.RoleData.ChapterData.BattleId)
{
return (int)CSErrCode.PayItemNotValid;
}
}
if (desc.goodsType == PayGoodsType.DailyPack)
{
var subDailyPackIds = SubDailyPackIds();
if (subDailyPackIds.Contains(desc.itemID))//购买的是子礼包
{
for (int i = 0; i < player.RoleData.PayData.PayItemRecord.Count; i++)
{
var record = player.RoleData.PayData.PayItemRecord[i];
var tempDesc = PayDiamondDescMgr.Instance.GetConfig(record.ItemId);//今天购买了总礼包就不能购买子礼包了
if (IsOneClickDailyPack(tempDesc.itemID) && record.PayCountToday > 0)
{
return (int)CSErrCode.PayItemNotValid;
}
}
}
else //子礼包都购买玩了,就不能购买总礼包了
{
var ret = true;
foreach (var dailyPackId in subDailyPackIds)
{
var index = -1;
for (int i = 0; i < player.RoleData.PayData.PayItemRecord.Count; i++)
{
var record = player.RoleData.PayData.PayItemRecord[i];
if (record.ItemId == dailyPackId&& record.PayCountToday>0)
{
index = i;
break;
}
}
ret = ret && index != -1;
}
if (ret)
{
return (int)CSErrCode.PayItemNotValid;
}
}
}
return 0;
}
// 根据PayDiamondDesc中的timeLimitType字段, 检查玩家是否满足条件
private static bool CheckPayTimeLimit(PlayerOnGame player, PayDiamondDesc desc)
{
switch ((PayLimitEvent)desc.timeLimitType)
{
case PayLimitEvent.None:
return true;
case PayLimitEvent.PopGift:
return PopPackageSvc.IsPopPackageEffective(player, desc.popUpPackageType);
case PayLimitEvent.ActivityGift:
{
var state = ActivitySvc.GetActivityState(player, desc.activityId);
return state == ActivityState.InProgress;
}
}
return false;
}
private static bool CheckPayTimesLimit(PlayerOnGame player, PayDiamondDesc desc)
{
if (desc.buyCountLimit <= 0)
{
return false;
}
ref var record = ref player.RoleData.PayData.PayItemRecord;
for (int i = 0; i < record.Count; i++)
{
if (record[i].ItemId == desc.itemID)
{
return record[i].PaySuccessCount >= desc.buyCountLimit;
}
}
return false;
}
private static bool CheckPayTimesDailyLimit(PlayerOnGame player, PayDiamondDesc desc)
{
// 总购买次数限制判断
if (desc.dailyLimit > 0)
{
ref var record = ref player.RoleData.PayData.PayItemRecord;
for (int i = 0; i < record.Count; i++)
{
if (record[i].ItemId == desc.itemID)
{
return record[i].PayCountToday >= desc.dailyLimit;
}
}
}
return false;
}
public static int CheckValidFixedPayTime(PayDiamondDesc desc)
{
//配置的静态时间段限制
long startTime = desc.startTimeInt;
long endTime = desc.endTimeInt;
long nowSec = GameServerUtils.GetTimeSecond();
if ((startTime > 0 && nowSec < startTime) || (endTime > 0 && nowSec > endTime))
{
TraceLog.Trace("PayCommSvc.CheckValidFixedPayTime item {0} can not pay, need startTime {1} endTime {2}"
, desc.itemID, startTime, endTime);
return (int)CSErrCode.PayInvalidTime;
}
return 0;
}
// 角色创建后多少天, 商品可以购买, 如果需要限制购买时间, 填写validTime
private static bool CheckPlayerBornEvent(PlayerOnGame player, PayDiamondDesc desc)
{
long startTime = AppTime.GetTodayStartTime(player.RoleBase.CreateTime) + (desc.timeLimitParam - 1) * 86400;
long endTime = 0;
player.Trace("PayCommSvc.CheckPlayerBornEvent uid {0} payItem {1} start {2} end {3}"
, player.UserID, desc.itemID, startTime, endTime);
long nowSec = GameServerUtils.GetTimeSecond();
return startTime <= nowSec && (endTime == 0 || nowSec < endTime);
}
// 开服多少天后, 商品可以购买, 如果需要限制购买时间, 填写validTime
private static bool CheckRealmOpenEvent(PlayerOnGame player, PayDiamondDesc desc)
{
var realm = GameServerUtils.GetGameServerData().m_configRealm.FirstOrDefault(r => r.realmId == player.RealmID);
if (realm == null || realm.openTime <= 0)
{
return false;
}
long startTime = AppTime.GetTodayStartTime(realm.openTime) + (desc.timeLimitParam - 1) * 86400;
long endTime = 0;
player.Trace("PayCommSvc.CheckRealmOpenEvent uid {0} item {1} start {2} end {3}"
, player.UserID, desc.itemID, startTime, endTime);
long nowSec = GameServerUtils.GetTimeSecond();
return startTime <= nowSec && (endTime == 0 || nowSec < endTime);
}
public static void OnTick(PlayerOnGame player, long nowSecond)
{
// 对于没有收到DB回应的订单, 再次发起修改成状态2的请求
for (int i = 0; i < player.RoleData.PayData.PaySuccWaitAddRole.Count; i++)
{
ref var addData = ref player.RoleData.PayData.PaySuccWaitAddRole[i];
// 订单发货成功, 无需处理, 等待超时后删除
if (addData.AddItemSuccTime > 0)
{
continue;
}
// 每次上线每笔订单尝试3次, 如果失败就等下次上线再尝试
if (addData.DbResFailCount >= 3)
{
continue;
}
// 每隔5秒尝试一次修改DB订单状态
if ((int)nowSecond >= addData.LastSendDBTime + 5)
{
addData.LastSendDBTime = (int)nowSecond;
var addReq = new SSPayDBAddDiamondStatusReq
{
Uid = player.UserID,
AmountExchange = addData.AmountExchange,
DiamondExchange = addData.DiamondExchange,
Money = addData.Money,
};
addReq.OrderId.SetString(addData.OrderId.GetPtr());
if (addData.IsReplaceItem)
{
addReq.ReplaceItemId = addData.ItemID;
}
GameServerUtils.GetPacketSender().SendToWorldServer(
(int)SSGameMsgID.PayDbAddDiamondStatusReq, ref addReq, player.UserID);
}
}
}
public static void UpdatePlayerPayRecord(PlayerOnGame player, int nowSec, bool notifyClient)
{
bool changed = false;
List<int> deleteList = null;
for (int i = 0; i < player.RoleData.PayData.PayItemRecord.Count; i++)
{
ref var record = ref player.RoleData.PayData.PayItemRecord[i];
// 版本号变化, 代表物品配置变了
var desc = GetPayDiamondDesc(record.ItemId);
if (desc == null)
{
if (deleteList == null)
{
deleteList = new List<int>();
}
deleteList.Add(record.ItemId);
changed = true;
continue;
}
// 每天刷新一次购买次数限制
if (AppTime.IsSameDay(nowSec, record.LastUpdateRecordTime))
{
continue;
}
if (record.PayCountToday != 0)
{
player.Trace("PayCommSvc.UpdatePlayerPayRecord uid {0} itemId {1} PayCountToday {2} reset to 0"
, player.UserID, record.ItemId, record.PayCountToday);
record.PayCountToday = 0;
}
if (!AppTime.IsSameWeek127(nowSec, record.LastUpdateRecordTime))
{
player.Trace("PayCommSvc.UpdatePlayerPayRecord uid {0} itemId {1} PayCountWeek {2} reset to 0"
, player.UserID, record.ItemId, record.PayCountWeek);
record.PayCountWeek = 0;
}
if (record.PayCountMonth != 0 && !AppTime.IsSameMonth(nowSec, record.LastUpdateRecordTime))
{
player.Trace("PayCommSvc.UpdatePlayerPayRecord uid {0} itemId {1} PayCountMonth {2} reset to 0"
, player.UserID, record.ItemId, record.PayCountMonth);
record.PayCountMonth = 0;
}
//清理玩家每日购买钻石数
player.RoleData.PayData.TodayPayDiamond = 0;
record.LastUpdateRecordTime = nowSec;
changed = true;
}
// 商城物品被删除了
if (deleteList != null)
{
for (int i = 0; i < deleteList.Count; i++)
{
for (int j = 0; j < player.RoleData.PayData.PayItemRecord.Count; j++)
{
if (deleteList[i] == player.RoleData.PayData.PayItemRecord[j].ItemId)
{
player.Debug("PayCommSvc.UpdatePlayerPayRecord uid {0} delete itemId {1}", player.UserID, deleteList[i]);
player.RoleData.PayData.PayItemRecord.RemoveAt(j);
break;
}
}
}
}
// 更新最近7天内单笔最大购买金额列表
int dayGap = AppTime.GetDayElapse(nowSec, player.RoleData.PayData.LastUpdateMaxPayMoneyTime);
if (dayGap >= 7)
{
// 距离上次更新超过7天
player.RoleData.PayData.MaxPayMoneyLast7Days.Clear();
for (int i = 0; i < 7; i++)
{
player.RoleData.PayData.MaxPayMoneyLast7Days.Add(0);
}
player.RoleData.PayData.LastUpdateMaxPayMoneyTime = nowSec;
changed = true;
}
else if (dayGap > 0) // 1 <= dayGap <= 6
{
// 有效值后移
int tail = 7 - dayGap - 1;
for (int i = tail; i >= 0; i--)
{
player.RoleData.PayData.MaxPayMoneyLast7Days[i + dayGap] =
player.RoleData.PayData.MaxPayMoneyLast7Days[i];
}
// 前面补0
for (int i = 0; i < dayGap; i++)
{
player.RoleData.PayData.MaxPayMoneyLast7Days[i] = 0;
}
player.RoleData.PayData.LastUpdateMaxPayMoneyTime = nowSec;
changed = true;
}
bool isMonthlyCardChange = false;
// 更新月卡数据
for (int i = player.RoleData.PayData.MonthlyCard.Count - 1; i >= 0; i--)
{
ref var cardData = ref player.RoleData.PayData.MonthlyCard[i];
if (nowSec >= cardData.ExpireTime && cardData.ExpireTime>0)//第二个条件是为了永远不删除永久卡
{
player.Debug("PayCommSvc.UpdatePlayerPayRecord uid {0} delete monthly card {1}"
, player.UserID, cardData.CardId);
player.RoleData.PayData.MonthlyCard[i].IsTimeOutCard = true;
changed = true;
isMonthlyCardChange = true;
//GameServerUtils.GetEventHandlerMgr().TriggerMonthCartTimeOut(player, 0);
}
else
{
player.RoleData.PayData.MonthlyCard[i].IsTimeOutCard = false;
}
}
PlayerPayUtil.DeletePaySuccWaitAddRole(player);
if (changed)
{
player.MakeDirty();
if (notifyClient)
{
PlayerNotify.NotifyPlayerPayDataChange(player);
}
}
//检查一遍有激活下一个礼包的
if (isMonthlyCardChange)
{
MonthlyCardSvc.SyncInfo(player);
}
}
public static int GetMonthlyCardLimitDay(VipCardType cardType)
{
var desc = MonthlyCardDescMgr.Instance.GetConfig((int)cardType);
return desc?.duration ?? 0;
}
// 上线时检查是否有新的可购买商品需要通知客户端
public static void AddNewItemOnPlayerOnline(PlayerOnGame player)
{
foreach (PayDiamondDesc desc in PayDiamondDescMgr.Instance.ItemTable.Values)
{
// 特殊条件, 限时商品, 通行证, 在满足条件时需要记录额外的数据, 并通知客户端
// 如果不是这几类商品, 客户端会判断是否显示在商城中
if (desc.timeLimitType > 0 )
{
PlayerPayUtil.AddPaySuccRecordIfNotExist(player, desc);
}
}
PlayerNotify.NotifyPlayerPayDataChange(player);
}
// 英雄支付, 子类型3~10是台湾mycard支付, 支付金额由用户控制, 不一定等于商品金额, 需要特殊逻辑处理
public static bool IsMycardPay(int heroPaySubType)
{
return 3 <= heroPaySubType && heroPaySubType <= 10;
}
public static string GetPaymentId(int itemId)
{
var desc = PayDiamondDescMgr.Instance.GetConfig(itemId);
if (desc != null)
{
return GetPaymentId(desc);
}
return null;
}
public static string GetPaymentId(PayDiamondDesc desc)
{
if (!string.IsNullOrEmpty(desc.productID))
{
return desc.productID;
}
return null;
}
//代币支付
public static int TokenPay(PlayerOnGame player, CSPayGoogleReq payReq, SSPayGoogleReq ssReq)
{
var desc = PayDiamondDescMgr.Instance.GetConfig(payReq.ItemID);
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 (token < needTokenNum)
{
return (int)CSErrCode.Fail;
}
GameServerUtils.GetGameServerData().m_packetHandlerTable.TryGetValue((int)SSGameMsgID.PayGoogleSuccessRes, out var handler);
PayHandler payHandler = handler as PayHandler;
if (payHandler == null)
{
return (int)CSErrCode.Fail;
}
StructPacket packet = new StructPacket();
packet.Header.Type = (int)SSGameMsgID.PayGoogleSuccessRes;
StructMessageParser<SSPayGoogleSuccessRes> parser = new StructMessageParser<SSPayGoogleSuccessRes>();
packet.Parser = parser;
long payTime = GameServerUtils.GetTimeSecond();
var paymentId = GetPaymentId(desc);
string orderId = PayUtils.GenOrderIdForUser(player.UserID, GameServerUtils.GetApp().ServerID,
desc.itemID, payReq.Param1, payReq.Param2, paymentId, payTime);
PayType payType = PlayerPayUtil.GetPlayerPayType(player);
ref SSPayGoogleSuccessRes req = ref parser.GetMessage();
req.Uid = player.UserID;
req.OrderId.SetString(orderId);
req.Currency.SetString(""+desc.currencyId);
req.PayType = (uint)payType;
req.PayParam1 = payReq.Param1;
req.PayParam2 = payReq.Param2;
req.ItemID = desc.itemID;
req.Amount = needTokenNum;
req.OrderId3rd.SetString("tokenpay_" + orderId);
req.PayChannel = payReq.PayChannel;
req.Ret = 0;
req.Status = 1;
var ret = payHandler.CheckCostPayItem(player, desc, orderId, false);
if (ret != 0)
{
return ret;
}
ret = payHandler.ProcessPayGoogleSuccessRes(GameServerUtils.GetAppID(), packet);
if (ret < 0)
{
return ret;
}
var ssDBAddRes = new SSPayDBAddDiamondStatusRes
{
Uid = player.UserID,
Diamond = desc.diamond,
Status = 2,
PayChannel = payReq.PayChannel,
};
ssDBAddRes.Ret = 0;
for (int i = 0; i < ssReq.SelectItems.Count; i++)
{
var t = ssReq.SelectItems[i];
ssDBAddRes.SelectItems.Add(t.Item);
}
ssDBAddRes.OrderId.SetString(orderId);
payHandler.OnDBAddDiamondStatusRes(player.UserID, ref ssDBAddRes, false);
var res = new CSPayGoogleRes();
res.OrderId.SetString(orderId);
res.Uid = player.UserID;
res.PayChannel = payReq.PayChannel;
res.ItemID = payReq.ItemID;
res.OrderId.SetString(orderId);
res.JsApiPay = payReq.JsApiPay;
res.PaymentId.SetString(paymentId);
res.SelectItems.CopyFrom(ref payReq.SelectItems);
player.SendToClient((int)CSGameMsgID.PayGoogleRes, ref res);
return (int)CSErrCode.None;
}
//伪造支付
public static int FakePay(long uid, int itemId, int payParam1 = 0, int payParam2 = 0)
{
// 打错误日志避免被冲掉
TraceLog.Error("GmCmdSvc.FakePay uid {0}", uid);
PlayerOnGame player = GameServerUtils.GetPlayerTableOp().GetPlayerByUid(uid);
if (player == null)
{
TraceLog.Error("GmCmdSvc.FakePay uid {0} no player", uid);
return -1;
}
if (itemId == 0)
{
TraceLog.Error("GmCmdSvc.FakePay no itemId");
return -1;
}
PayType payType = PlayerPayUtil.GetPlayerPayType(player);
PayDiamondDesc desc = PayCommSvc.GetPayDiamondDesc(itemId);
if (desc == null)
{
player.Error("GmCmdSvc.FakePay uid {0} invalid itemId {1}", uid, itemId);
return -1;
}
var paymentId = PayCommSvc.GetPaymentId(desc);
if (paymentId == null)
{
player.Error("GmCmdSvc.FakePay item {0} currency {1} money {2} no paymentId"
, desc.itemID, desc.currencyId, desc.currencyRes);
return -1;
}
var iRet = PayCommSvc.CheckPayLimit(player, desc);
if (iRet != 0)
{
return iRet;
}
// 记录物品购买信息
int recordIndex = PlayerPayUtil.AddPaySuccRecordIfNotExist(player, desc);
if (recordIndex == -1)
{
TraceLog.Error("GmCmdSvc.FakePay uid {0} itemId {1} add pay record failed"
, player.UserID, desc.itemID);
return -1;
}
// 生成订单号
long payTime = GameServerUtils.GetTimeSecond();
string orderId = PayUtils.GenOrderIdForUser(player.UserID, GameServerUtils.GetApp().ServerID,
desc.itemID, payParam1, payParam2, paymentId, payTime);
GameServerUtils.GetGameServerData().m_packetHandlerTable.TryGetValue((int)SSGameMsgID.PayGoogleSuccessRes, out var handler);
PayHandler payHandler = handler as PayHandler;
if (payHandler == null)
{
TraceLog.Error("GmCmdSvc.FakePay get PayHandler failed");
return -1;
}
// 伪造支付成功请求, 插入待添加列表
var ssPaySuccRes = new SSPayGoogleSuccessRes
{
Uid = uid,
PayType = (uint)payType,
Status = 1,
PayParam1 = payParam1,
PayParam2 = payParam2,
PayTime3rd = payTime,
Amount = desc.currencyRes,
};
ssPaySuccRes.ItemID = itemId;
ssPaySuccRes.OrderId.SetString(orderId);
ssPaySuccRes.OrderId3rd.SetString("fakepay_" + orderId);
ssPaySuccRes.Currency.SetString("USD");
ref DBRolePayItemRecord record = ref PlayerPayUtil.GetPayItemRecordByIndex(player, recordIndex);
int idx = payHandler.InsertPaySuccWaitAddRole(player, desc, ref ssPaySuccRes,
ref record, 0, 0, false);
if (idx == -1)
{
return -1;
}
ref DBPaySuccWaitAddRole addData = ref player.RoleData.PayData.PaySuccWaitAddRole[idx];
// 已经添加成功, 无需再处理
if (addData.AddItemSuccTime > 0)
{
TraceLog.Error("GmCmdSvc.FakePay uid {0} orderId {1} already add succ {2}", uid, orderId, addData.AddItemSuccTime);
return -1;
}
// 伪造修改DB状态成功请求
var ssDBAddRes = new SSPayDBAddDiamondStatusRes { Uid = uid, Diamond = desc.diamond, Status = 2 };
ssDBAddRes.OrderId.SetString(orderId);
payHandler.OnDBAddDiamondStatusRes(uid, ref ssDBAddRes, false);
GameBillLogUtils.LogFakePay(ref addData, 0, addData.IsPlayerFirstPay, player);
return 0;
}
}
}