game_sync/worldsrv/action_third.go

663 lines
25 KiB
Go
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

package main
import (
"mongo.games.com/game/common"
"mongo.games.com/game/protocol/gamehall"
"mongo.games.com/game/webapi"
"mongo.games.com/goserver/core/basic"
"mongo.games.com/goserver/core/logger"
"mongo.games.com/goserver/core/netlib"
"mongo.games.com/goserver/core/task"
"mongo.games.com/goserver/core/utils"
"strconv"
"sync/atomic"
"time"
)
func init() {
common.RegisterHandler(int(gamehall.GameHallPacketID_PACKET_CS_ENTERTHRIDGAME), &CSEnterThridGameHandler{})
netlib.RegisterFactory(int(gamehall.GameHallPacketID_PACKET_CS_ENTERTHRIDGAME), &CSEnterThridGamePacketFactory{})
common.RegisterHandler(int(gamehall.GameHallPacketID_PACKET_CS_LEAVETHRIDGAME), &CSLeaveThridGameHandler{})
netlib.RegisterFactory(int(gamehall.GameHallPacketID_PACKET_CS_LEAVETHRIDGAME), &CSLeaveThridGamePacketFactory{})
common.RegisterHandler(int(gamehall.GameHallPacketID_PACKET_CS_THRIDGAMEBALANCEUPDATE), &CSThridBalanceRefreshHandler{})
netlib.RegisterFactory(int(gamehall.GameHallPacketID_PACKET_CS_THRIDGAMEBALANCEUPDATE), &CSThridBalanceRefreshPacketFactory{})
}
// 第三方-->系统
func _StartTransferThird2SystemTask(p *Player) {
if p.scene == nil {
logger.Logger.Tracef("player snid=%v TransferThird2SystemTask p.scene == nil return", p.SnId)
return
}
if p.scene.sceneMode != int(common.SceneMode_Thr) {
logger.Logger.Infof("player snid=%v TransferThird2SystemTask p.scene == thrID return", p.SnId)
return
}
if p.thridBalanceRefreshReqing {
logger.Logger.Tracef("player snid=%v TransferThird2SystemTask p.thridBalanceRefreshReqing == true return", p.SnId)
return
}
gainway := common.GainWay_Transfer_Thrid2System
plt := webapi.ThridPlatformMgrSington.FindPlatformByPlatformBaseGameId(p.scene.gameId)
if plt == nil {
logger.Logger.Tracef("player snid=%v TransferThird2SystemTask plt == nil return", p.SnId)
return
}
oper := plt.GetPlatformBase().Name + "2System"
thirdBalance := int64(0)
timeStamp := time.Now().UnixNano()
p.thridBalanceRefreshReqing = true
timeout := false
task.New(nil, task.CallableWrapper(func(o *basic.Object) interface{} {
for i := int32(0); i < model.GameParamData.ThirdPltTransferMaxTry; {
var err error
var coinLog *model.PayCoinLog
var coinlogex *model.CoinLog
var apiHasTransfer = false
remark := plt.GetPlatformBase().Name + "转出到系统"
allow := plt.ReqIsAllowTransfer(p.SnId, p.Platform, p.Channel)
if !allow {
goto Rollback
}
err, thirdBalance = plt.ReqUserBalance(p.SnId, p.Platform, p.Channel, p.Ip)
if err != nil {
goto Rollback
}
if thirdBalance <= 0 {
return nil
}
if plt.GetPlatformBase().TransferInteger {
thirdBalance = (thirdBalance / 100) * 100
if thirdBalance <= 0 {
return nil
}
}
timeStamp = time.Now().UnixNano()
//如果請求超時的話資金就不能從三方出來,玩家的錢只會少
err, timeout = plt.ReqTransfer(p.SnId, -thirdBalance, strconv.FormatInt(timeStamp, 10), p.Platform, p.Channel, p.Ip)
if err != nil || timeout {
goto Rollback
}
apiHasTransfer = true
coinLog = model.NewPayCoinLog(timeStamp, int32(p.SnId), thirdBalance, int32(gainway), oper, model.PayCoinLogType_Coin, 0)
timeStamp = coinLog.TimeStamp
err = model.InsertPayCoinLogs(p.Platform, coinLog)
if err != nil {
goto Rollback
}
coinlogex = model.NewCoinLogEx(p.SnId, thirdBalance, p.Coin+thirdBalance, p.SafeBoxCoin, 0, int32(gainway),
0, oper, remark, p.Platform, p.Channel, p.BeUnderAgentCode, 0, p.PackageID, int32(plt.GetPlatformBase().VultGameID))
err = model.InsertCoinLog(coinlogex)
if err != nil {
goto Rollback
}
return nil
Rollback:
if coinLog != nil {
model.RemovePayCoinLog(p.Platform, coinLog.LogId)
}
if coinlogex != nil {
model.RemoveCoinLogOne(coinlogex.Platform, coinlogex.LogId)
}
//如果發現有任何一個超時,則就不在往下執行,因為不知道數據是否正確
if timeout {
logger.Logger.Errorf("player snid=%v third->system transfer %v timeout at try %v times,then stop try!", p.SnId, -thirdBalance, i+1)
break
}
if apiHasTransfer {
err, timeout = plt.ReqTransfer(p.SnId, thirdBalance, strconv.FormatInt(time.Now().UnixNano(), 10), p.Platform, p.Channel, p.Ip)
if err != nil {
logger.Logger.Errorf("player snid=%v third->system transfer rollback fail at try %v times", p.SnId, i+1)
}
}
//如果发现有任何一個超时,則就不在往下执行,因为不知道数据是否在三方已经处理
if timeout {
logger.Logger.Errorf("player snid=%v third->system rollback transfer %v timeout at try %v times,then stop try!", p.SnId, thirdBalance, i+1)
break
}
logger.Logger.Tracef("player snid=%v third->system transfer rollback at try %v times", p.SnId, i+1)
i++
if i < model.GameParamData.ThirdPltTransferMaxTry {
time.Sleep(time.Duration(model.GameParamData.ThirdPltTransferInterval) * time.Duration(time.Second))
}
}
return errors.New("third->system transfer error >max try times!")
}), task.CompleteNotifyWrapper(func(data interface{}, tt task.Task) {
statePack := &gamehall.SCThridGameBalanceUpdateState{}
if data != nil {
p.thirdBalanceRefreshMark[plt.GetPlatformBase().Name] = false
p.thridBalanceReqIsSucces = false
statePack.OpRetCode = gamehall.OpResultCode_Game_OPRC_Error_Game
logger.Logger.Trace("SCThridAccountTransferHandler third->system transfer error:", data)
} else {
p.thridBalanceReqIsSucces = true
statePack.OpRetCode = gamehall.OpResultCode_Game_OPRC_Sucess_Game
p.Coin += thirdBalance
p.SetPayTs(timeStamp)
p.thirdBalanceRefreshMark[plt.GetPlatformBase().Name] = true
ThirdPlatformMgrSington.AddThirdPlatformCoin(p.Platform, plt.GetPlatformBase().Tag, thirdBalance)
}
p.SendToClient(int(gamehall.GameHallPacketID_PACKET_SC_THRIDGAMEBALANCEUPDATESTATE), statePack)
p.dirty = true
//这个地方虽然说拉取失败,但是为了不影响玩家玩其他的游戏,还是可以进入其它场景
//后面玩家自己通过手动刷新余额
if p.scene != nil {
p.scene = nil
}
p.thridBalanceRefreshReqing = false
p.diffData.Coin = -1 //强制更新金币
p.SendDiffData()
return
}), "ThridAccountTransfer").Start()
}
type CSEnterThridGamePacketFactory struct {
}
type CSEnterThridGameHandler struct {
}
func (this *CSEnterThridGamePacketFactory) CreatePacket() interface{} {
pack := &gamehall.CSEnterThridGame{}
return pack
}
func (this *CSEnterThridGameHandler) Process(s *netlib.Session, packetid int, data interface{}, sid int64) error {
logger.Logger.Trace("CSEnterThridGameHandler Process recv ", data)
p := PlayerMgrSington.GetPlayer(sid)
if p == nil {
logger.Logger.Warn("CSEnterThridGameHandler p == nil")
return nil
}
if msg, ok := data.(*gamehall.CSEnterThridGame); ok {
returnErrorCodeFunc := func(code gamehall.OpResultCode_Game) {
pack := &gamehall.SCEnterThridGame{}
pack.OpRetCode = code
pack.ThridGameId = msg.ThridGameId
p.SendToClient(int(gamehall.GameHallPacketID_PACKET_SC_ENTERTHRIDGAME), pack)
logger.Trace(pack)
}
//正在请求刷新余额中不能进入三方
if p.thridBalanceRefreshReqing {
logger.Logger.Warn("CSEnterThridGameHandler client req thridBalanceRefreshReqing", p.SnId)
returnErrorCodeFunc(gamehall.OpResultCode_Game_OPRC_ThirdPltProcessing_Game)
return nil
}
//msg.ThridGameId=proto.Int32(430010001)
if p.scene != nil {
logger.Logger.Infof("Player %v in game.", p.SnId)
returnErrorCodeFunc(gamehall.OpResultCode_Game_OPRC_ThirdPltProcessing_Game)
return nil
}
if p.isDelete {
returnErrorCodeFunc(gamehall.OpResultCode_Game_OPRC_RoomHadClosed_Game)
return nil
}
//pt := PlatformMgrSington.GetPackageTag(p.PackageID)
//if pt != nil && pt.IsForceBind == 1 {
// if p.BeUnderAgentCode == "" || p.BeUnderAgentCode == "0" {
// returnErrorCodeFunc(gamehall.OpResultCode_Game_OPRC_MustBindPromoter_Game)
// return nil
// }
//}
ok, thridPltGameItem := ThirdPltGameMappingConfig.FindByGameID(msg.GetThridGameId())
if !ok {
logger.Logger.Infof("Player %v thridgame id err.", p.SnId, msg.GetThridGameId())
returnErrorCodeFunc(gamehall.OpResultCode_Game_OPRC_Error_Game)
return nil
}
thridGameId := thridPltGameItem.GetThirdGameID()
//检测房间状态是否开启
gps := PlatformMgrSington.GetGameConfig(p.Platform, msg.GetThridGameId())
if gps == nil {
logger.Logger.Infof("Player %v no cfg room close", p.SnId)
returnErrorCodeFunc(gamehall.OpResultCode_Game_OPRC_RoomHadClosed_Game)
return nil
}
dbGameFree := gps.DbGameFree
if dbGameFree == nil {
logger.Logger.Infof("Player %v no gamefree", p.SnId)
returnErrorCodeFunc(gamehall.OpResultCode_Game_OPRC_RoomHadClosed_Game)
return nil
}
//找到对应的平台
v, ok := webapi.ThridPlatformMgrSington.ThridPlatformMap.Load(thridPltGameItem.GetThirdPlatformName())
if !ok {
logger.Logger.Infof("Player %v no platform", p.SnId)
returnErrorCodeFunc(gamehall.OpResultCode_Game_OPRC_RoomHadClosed_Game)
return nil
}
plt := v.(webapi.IThirdPlatform)
pfConfig := PlatformMgrSington.GetPlatform(p.Platform)
if pfConfig == nil || pfConfig.ThirdGameMerchant == nil || pfConfig.ThirdGameMerchant[int32(plt.GetPlatformBase().BaseGameID)] == 0 {
logger.Logger.Infof("Player %v no pfcfg", p.SnId)
returnErrorCodeFunc(gamehall.OpResultCode_Game_OPRC_RoomHadClosed_Game)
return nil
}
//检查限额,金额不足
if dbGameFree.GetLimitCoin() != 0 && p.GetCoin() < int64(dbGameFree.GetLimitCoin()) {
returnErrorCodeFunc(gamehall.OpResultCode_Game_OPRC_CoinNotEnough_Game)
return nil
}
//三方不检查游戏次数限制
//todayData, _ := p.GetDaliyGameData(int(msg.GetThridGameId()))
//if dbGameFree.GetPlayNumLimit() != 0 &&
// todayData != nil &&
// todayData.GameTimes >= int64(dbGameFree.GetPlayNumLimit()) {
// logger.Logger.Infof("CSEnterThridGameHandler player snid:%v todayData.GameTimes:%v>PlayNumLimit:%v then kick", p.SnId, todayData.GameTimes, dbGameFree.GetPlayNumLimit())
// returnErrorCodeFunc(gamehall.OpResultCode_OPRC_RoomGameTimes)
// return nil
//}
//检查平台配额是否足够
if plt.GetPlatformBase().IsNeedCheckQuota {
dgQuota := ThirdPlatformMgrSington.GetThirdPlatformCoin(p.Platform, plt.GetPlatformBase().Tag)
if dgQuota <= 0 || dgQuota <= p.GetCoin() {
logger.Logger.Infof("Player snid %v %v platfrom Quota of game not enough.", p.SnId, plt.GetPlatformBase().Name)
returnErrorCodeFunc(gamehall.OpResultCode_Game_OPRC_Dg_QuotaNotEnough_Game)
return nil
}
}
//检查场景是否开放或者存在,预设数据
scene := SceneMgrSington.GetThirdScene(plt)
if scene != nil {
p.scene = scene
} else {
logger.Logger.Infof("Player %v no scene", p.SnId)
returnErrorCodeFunc(gamehall.OpResultCode_Game_OPRC_RoomHadClosed_Game)
return nil
}
pack := &gamehall.SCEnterThridGame{}
pack.ThridGameId = msg.ThridGameId
amount := p.GetCoin()
if plt.GetPlatformBase().TransferInteger {
amount = (amount / 100) * 100
}
p.Coin = p.GetCoin() - amount
gainway := common.GainWay_Transfer_System2Thrid
oper := "System2" + plt.GetPlatformBase().Name
timeStamp := time.Now().UnixNano()
p.thridBalanceRefreshReqing = true
transferTimeOut := false
task.New(nil, task.CallableWrapper(func(o *basic.Object) interface{} {
var err error
var ok bool
url := ""
remark := "转入" + plt.GetPlatformBase().Name + thridPltGameItem.GetDesc()
//thridPlatformCoin := int64(0)
var coinLog *model.PayCoinLog
var coinlogex *model.CoinLog
err = ensureThridPltUserName(plt, p, s.RemoteAddr())
if err != nil && err != webapi.ErrNoCreated {
goto Rollback
}
coinLog = model.NewPayCoinLog(timeStamp, int32(p.SnId), -amount, int32(gainway), oper, model.PayCoinLogType_Coin, 0)
timeStamp = coinLog.TimeStamp
err = model.InsertPayCoinLogs(p.Platform, coinLog)
if err != nil {
goto Rollback
}
coinlogex = model.NewCoinLogEx(p.SnId, -amount, p.Coin, p.SafeBoxCoin, 0, int32(gainway),
0, oper, remark, p.Platform, p.Channel, p.BeUnderAgentCode, 0, p.PackageID, int32(plt.GetPlatformBase().VultGameID))
err = model.InsertCoinLog(coinlogex)
if err != nil {
goto Rollback
}
ok = utils.RunPanicless(func() {
err, url = plt.ReqEnterGame(p.SnId, thridGameId, s.RemoteAddr(), p.Platform, p.Channel, p.Ip)
})
if err != nil || !ok {
logger.Logger.Errorf("plt.ReqEnterGame() snid:%v error: %v", p.SnId, err)
if thrErr, ok := err.(webapi.ThirdError); ok {
if thrErr.IsClose() {
pack.OpRetCode = gamehall.OpResultCode_Game_OPRC_Thr_GameClose_Game
} else {
pack.OpRetCode = gamehall.OpResultCode_Game_OPRC_Error_Game
}
} else {
pack.OpRetCode = gamehall.OpResultCode_Game_OPRC_Error_Game
}
goto Rollback
}
err, transferTimeOut = plt.ReqTransfer(p.SnId, amount, strconv.FormatInt(timeStamp, 10), p.Platform, p.Channel, p.Ip)
if err != nil || transferTimeOut {
logger.Logger.Errorf("plt.ReqTransfer() snid:%v error:%v", p.SnId, err)
pack.OpRetCode = gamehall.OpResultCode_Game_OPRC_Error_Game
goto Rollback
}
pack.OpRetCode = gamehall.OpResultCode_Game_OPRC_Sucess_Game
pack.ScreenOrientationType = proto.Int32(thridPltGameItem.GetScreenOrientationType())
pack.EnterUrl = proto.String(url)
return nil
Rollback:
pack.OpRetCode = gamehall.OpResultCode_Game_OPRC_Error_Game
if coinLog != nil {
model.RemovePayCoinLog(p.Platform, coinLog.LogId)
}
if coinlogex != nil {
if transferTimeOut {
err2 := model.UpdateCoinLogRemark(coinlogex.Platform, coinlogex.LogId, plt.GetPlatformBase().Name+"需人工处理")
if err2 != nil {
logger.Logger.Errorf("thr UpdateCoinLogRemark(%v) error: %v", coinlogex.LogId, err2)
}
} else {
model.RemoveCoinLogOne(coinlogex.Platform, coinlogex.LogId)
}
}
return errors.New("system->third transfer rollback!")
}), task.CompleteNotifyWrapper(func(data interface{}, tt task.Task) {
if pack.GetOpRetCode() == gamehall.OpResultCode_Game_OPRC_Sucess_Game {
ThirdPlatformMgrSington.AddThirdPlatformCoin(p.Platform, plt.GetPlatformBase().Tag, -amount)
p.SetPayTs(timeStamp)
} else {
//如帐变出现问题,就在日志里面查下面的输出信息!!!
//如果转账超时,三方的转账是否成功就是未知的,这时不能将金币再加到玩家身上。
//如果出现超时问题,就需要人工对账。
//注意这个地方说的超时已经包含CG工程Check订单后的超时
if transferTimeOut {
logger.Logger.Errorf("CSEnterThridGameHandler player snid:%v transfer %v to %v timeout:", p.SnId, amount, plt.GetPlatformBase().Name)
} else {
p.Coin += amount
}
p.scene = nil
pack.OpRetCode = gamehall.OpResultCode_Game_OPRC_Error_Game
logger.Logger.Trace("SCThridAccountTransferHandler system->third transfer error:", data)
}
p.dirty = true
p.thirdBalanceRefreshMark[plt.GetPlatformBase().Name] = false
p.SendDiffData()
p.SendToClient(int(gamehall.GameHallPacketID_PACKET_SC_ENTERTHRIDGAME), pack)
p.thridBalanceRefreshReqing = false
logger.Logger.Trace("CSEnterThridGameHandler send client:", pack)
return
}), "CSEnterThridGameHandler").Start()
}
return nil
}
func ensureThridPltUserName(pltform webapi.IThirdPlatform, p *Player, ip string) error {
var err error
err = pltform.ReqCreateAccount(p.SnId, p.Platform, p.Channel, p.GetIP())
if err != nil {
if err != webapi.ErrNoCreated {
logger.Logger.Errorf("Snid=%v Plt=%v CreateAccountReq error:%v", p.SnId, pltform.GetPlatformBase().Name, err)
}
return err
}
return nil
//switch pltform.GetPlatformBase().Name {
//case "WWG平台":
// if len(p.WwgPlatformName) == 0 {
// err = pltform.ReqCreateAccount(p.SnId, p.Platform, p.Channel)
// if err != nil {
// logger.Logger.Error("WwgCreateAccountReq error:", err)
// return err
// }
// p.WwgPlatformName = pltform.MappingGameName(p.SnId)
// }
//case "FG平台":
// if len(p.FgPlatformName) == 0 {
// err = pltform.ReqCreateAccount(p.SnId, p.Platform, p.Channel)
// if err != nil {
// logger.Logger.Error("FgCreateAccountReq error:", err)
// return err
// }
// p.FgPlatformName = pltform.MappingGameName(p.SnId)
// }
//case "AMEBA平台":
// if len(p.AmebaPlatformName) == 0 {
// err = pltform.ReqCreateAccount(p.SnId, p.Platform, p.Channel)
// if err != nil {
// logger.Logger.Error("AmebaCreateAccountReq error:", err)
// return err
// }
// p.AmebaPlatformName = pltform.MappingGameName(p.SnId)
// }
//case "VR彩票":
// if len(p.VrPlatformName) == 0 {
// err = pltform.ReqCreateAccount(p.SnId, p.Platform, p.Channel)
// if err != nil {
// logger.Logger.Error("VrCreateAccountReq error:", err)
// return err
// }
// p.VrPlatformName = pltform.MappingGameName(p.SnId)
// }
//}
//return nil
}
type CSLeaveThridGamePacketFactory struct {
}
type CSLeaveThridGameHandler struct {
}
func (this *CSLeaveThridGamePacketFactory) CreatePacket() interface{} {
pack := &gamehall.CSLeaveThridGame{}
return pack
}
func (this *CSLeaveThridGameHandler) Process(s *netlib.Session, packetid int, data interface{}, sid int64) error {
logger.Logger.Trace("CSLeaveThridGameHandler Process recv ", data)
if _, ok := data.(*gamehall.CSLeaveThridGame); ok {
p := PlayerMgrSington.GetPlayer(sid)
if p == nil {
logger.Logger.Warn("CSLeaveThridGameHandler p == nil")
return nil
}
_StartTransferThird2SystemTask(p)
pack := &gamehall.SCLeaveThridGame{}
pack.OpRetCode = gamehall.OpResultCode_Game_OPRC_Sucess_Game
p.SendToClient(int(gamehall.GameHallPacketID_PACKET_SC_LEAVETHRIDGAME), pack)
}
return nil
}
type CSThridBalanceRefreshPacketFactory struct {
}
type CSThridBalanceRefreshHandler struct {
}
func (this *CSThridBalanceRefreshPacketFactory) CreatePacket() interface{} {
pack := &gamehall.CSThridGameBalanceUpdate{}
return pack
}
func (this *CSThridBalanceRefreshHandler) Process(s *netlib.Session, packetid int, data interface{}, sid int64) error {
logger.Logger.Trace("CSThridBalanceRefreshHandler Process recv ", data)
if _, ok := data.(*gamehall.CSThridGameBalanceUpdate); ok {
p := PlayerMgrSington.GetPlayer(sid)
if p == nil {
logger.Logger.Warn("CSThridBalanceRefreshHandler p == nil")
return nil
}
if p.scene != nil {
logger.Logger.Tracef("player snid=%v CSThridBalanceRefreshHandler p.scene != nil return", p.SnId)
return nil
}
//请求太快不做处理给API减轻一些压力
if p.thridBalanceRefreshReqing {
logger.Logger.Warn("CSThridBalanceRefreshHandler client req too fast")
return nil
}
p.thridBalanceRefreshReqing = true
gainway := common.GainWay_Transfer_Thrid2System
waitgroup := webapi.ThridPlatformMgrSington.AllPlatformCount()
isSucces := true
timeout := false
webapi.ThridPlatformMgrSington.ThridPlatformMap.Range(func(key, value interface{}) bool {
plt := value.(webapi.IThirdPlatform)
if stateOk, exist := p.thirdBalanceRefreshMark[plt.GetPlatformBase().Name]; exist && stateOk {
waitgroup--
if 0 == waitgroup {
statePack := &gamehall.SCThridGameBalanceUpdateState{}
pack := &gamehall.SCThridGameBalanceUpdate{}
pack.OpRetCode = gamehall.OpResultCode_Game_OPRC_Sucess_Game
p.thridBalanceReqIsSucces = true
statePack.OpRetCode = gamehall.OpResultCode_Game_OPRC_Sucess_Game
p.SendToClient(int(gamehall.GameHallPacketID_PACKET_SC_THRIDGAMEBALANCEUPDATESTATE), statePack)
pack.Coin = proto.Int64(p.Coin)
p.SendToClient(int(gamehall.GameHallPacketID_PACKET_SC_THRIDGAMEBALANCEUPDATE), pack)
p.thridBalanceRefreshReqing = false
}
return true
}
var tsk task.Task
tsk = task.New(nil,
task.CallableWrapper(func(o *basic.Object) interface{} {
plt := tsk.GetEnv("plt").(webapi.IThirdPlatform)
tsk.PutEnv("timeStamp", time.Now().UnixNano())
var err error
var coinLog *model.PayCoinLog
var coinlogex *model.CoinLog
var apiHasTransfer = false
remark := "刷新" + plt.GetPlatformBase().Name + "转出到系统"
thirdBalance := int64(0)
allow := false
if plt == nil {
logger.Logger.Tracef("player snid=%v CSThridBalanceRefreshHandler plt == nil return", p.SnId)
return int64(-1)
}
pfConfig := PlatformMgrSington.GetPlatform(p.Platform)
if pfConfig == nil {
return int64(0)
}
if pfConfig.ThirdGameMerchant == nil || pfConfig.ThirdGameMerchant[int32(plt.GetPlatformBase().BaseGameID)] == 0 {
return int64(0)
}
oper := plt.GetPlatformBase().Name + "2System"
err = ensureThridPltUserName(plt, p, s.RemoteAddr())
if err != nil {
if err == webapi.ErrNoCreated {
return int64(0)
}
logger.Logger.Tracef("player snid=%v at %v ensureThridPltUserName() err: %v", p.SnId, plt.GetPlatformBase().Name, err)
goto Rollback
}
allow = plt.ReqIsAllowTransfer(p.SnId, p.Platform, p.Channel)
if !allow {
logger.Logger.Tracef("player snid=%v at %v is not allow Transfer", p.SnId, plt.GetPlatformBase().Name)
goto Rollback
}
err, thirdBalance = plt.ReqUserBalance(p.SnId, p.Platform, p.Channel, p.Ip)
if err != nil {
logger.Logger.Tracef("player snid=%v at %v plt.ReqUserBalance() err: %v", p.SnId, plt.GetPlatformBase().Name, err)
goto Rollback
}
if thirdBalance <= 0 {
return int64(0)
}
if plt.GetPlatformBase().TransferInteger {
thirdBalance = (thirdBalance / 100) * 100
if thirdBalance <= 0 {
return int64(0)
}
}
err, timeout = plt.ReqTransfer(p.SnId, -thirdBalance, strconv.FormatInt(time.Now().UnixNano(), 10), p.Platform, p.Channel, p.Ip)
if err != nil || timeout {
logger.Logger.Tracef("player snid=%v at %v plt.ReqTransfer() err: %v", p.SnId, plt.GetPlatformBase().Name, err)
goto Rollback
}
apiHasTransfer = true
coinLog = model.NewPayCoinLog(time.Now().UnixNano(), int32(p.SnId), thirdBalance, int32(gainway), oper, model.PayCoinLogType_Coin, 0)
tsk.PutEnv("timeStamp", coinLog.TimeStamp)
err = model.InsertPayCoinLogs(p.Platform, coinLog)
if err != nil {
logger.Logger.Tracef("player snid=%v at %v model.InsertPayCoinLogs() err: %v", p.SnId, plt.GetPlatformBase().Name, err)
goto Rollback
}
coinlogex = model.NewCoinLogEx(p.SnId, thirdBalance, p.Coin+thirdBalance, p.SafeBoxCoin, 0, int32(gainway),
0, oper, remark, p.Platform, p.Channel, p.BeUnderAgentCode, 0, p.PackageID, int32(plt.GetPlatformBase().VultGameID))
err = model.InsertCoinLog(coinlogex)
if err != nil {
logger.Logger.Tracef("player snid=%v at %v model.InsertCoinLogs() err: %v", p.SnId, plt.GetPlatformBase().Name, err)
goto Rollback
}
tsk.PutEnv("plt", plt)
return thirdBalance
Rollback:
if coinLog != nil {
model.RemovePayCoinLog(p.Platform, coinLog.LogId)
}
if coinlogex != nil {
model.RemoveCoinLogOne(coinlogex.Platform, coinlogex.LogId)
}
if timeout {
logger.Logger.Errorf("player snid=%v CSThridBalanceRefreshHandler transfer %v to %v timeout!", p.SnId, -thirdBalance, plt.GetPlatformBase().Name)
return int64(-1)
}
if apiHasTransfer {
err, timeout = plt.ReqTransfer(p.SnId, thirdBalance, strconv.FormatInt(time.Now().UnixNano(), 10), p.Platform, p.Channel, p.Ip)
if timeout {
logger.Logger.Errorf("player snid=%v CSThridBalanceRefreshHandler transfer rollback %v to %v timeout!", p.SnId, thirdBalance, plt.GetPlatformBase().Name)
}
}
return int64(-1)
}),
task.CompleteNotifyWrapper(func(data interface{}, tt task.Task) {
thirdBalance := data.(int64)
plt := tsk.GetEnv("plt").(webapi.IThirdPlatform)
timeStamp := tsk.GetEnv("timeStamp").(int64)
if thirdBalance < 0 {
isSucces = false
logger.Logger.Tracef("player snid=%v at platform=%v CSThridBalanceRefreshHandler third->system transfer fail", p.SnId, plt.GetPlatformBase().Name)
} else if thirdBalance > 0 {
p.thirdBalanceRefreshMark[plt.GetPlatformBase().Name] = true
p.Coin += thirdBalance
p.SetPayTs(timeStamp)
ThirdPlatformMgrSington.AddThirdPlatformCoin(p.Platform, plt.GetPlatformBase().Tag, thirdBalance)
p.dirty = true
logger.Logger.Tracef("player snid=%v at platform=%v CSThridBalanceRefreshHandler third->system transfer succes", p.SnId, plt.GetPlatformBase().Name)
} else {
p.thirdBalanceRefreshMark[plt.GetPlatformBase().Name] = true
}
if atomic.AddInt32(&waitgroup, -1) == 0 {
p.diffData.Coin = -1
p.SendDiffData()
statePack := &gamehall.SCThridGameBalanceUpdateState{}
pack := &gamehall.SCThridGameBalanceUpdate{}
if isSucces {
pack.OpRetCode = gamehall.OpResultCode_Game_OPRC_Sucess_Game
p.thridBalanceReqIsSucces = true
statePack.OpRetCode = gamehall.OpResultCode_Game_OPRC_Sucess_Game
} else {
pack.OpRetCode = gamehall.OpResultCode_Game_OPRC_Error_Game
p.thridBalanceReqIsSucces = false
statePack.OpRetCode = gamehall.OpResultCode_Game_OPRC_Error_Game
}
p.SendToClient(int(gamehall.GameHallPacketID_PACKET_SC_THRIDGAMEBALANCEUPDATESTATE), statePack)
pack.Coin = proto.Int64(p.Coin)
p.SendToClient(int(gamehall.GameHallPacketID_PACKET_SC_THRIDGAMEBALANCEUPDATE), pack)
p.thridBalanceRefreshReqing = false
logger.Logger.Tracef("SendToClient() player snid=%v at CSThridBalanceRefreshHandler() pack:%v", p.SnId, pack.String())
}
}), "ThridAccount")
tsk.PutEnv("plt", value)
tsk.Start()
return true
})
}
return nil
}