| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615 |
- package frame
- import (
- "encoding/json"
- "fmt"
- "time"
- "bet24.com/log"
- coreservice "bet24.com/servers/coreservice/client"
- "bet24.com/servers/insecureframe/gate"
- "bet24.com/servers/insecureframe/message"
- activityservice "bet24.com/servers/micros/activityservice/proto"
- audioroom "bet24.com/servers/micros/audioroom/proto"
- _ "bet24.com/servers/micros/ladderservice/proto"
- notification "bet24.com/servers/micros/notification/proto"
- privateroom "bet24.com/servers/micros/privateroom/proto"
- task "bet24.com/servers/micros/task/proto"
- userservices "bet24.com/servers/micros/userservices/proto"
- "bet24.com/servers/transaction"
- "bet24.com/servers/user"
- )
- func (t *ThreadsafeTable) GetTableID() int {
- return t.tableId
- }
- func (t *ThreadsafeTable) IsPrivate() bool {
- return t.isPrivate()
- }
- func (t *ThreadsafeTable) GetRoomNo() int {
- return t.roomNo
- }
- func (t *ThreadsafeTable) GetOwner() int {
- return t.owner
- }
- // 游戏准备好后,即可调用框架StartGame进行场景广播
- func (t *ThreadsafeTable) StartGame() {
- if t.tableStatus != TableStatus_Free {
- log.Release("ThreadsafeTable.StartGame not free status")
- return
- }
- t.startTime = time.Now().Unix()
- var userIds []int
- // 将所有用户状态改变
- for i := 0; i < t.chairCount; i++ {
- if t.users[i] == -1 {
- continue
- }
- usr := gate.GetUserInfo(t.users[i])
- if usr == nil || !usr.IsPlayer() {
- continue
- }
- gameFrame.setUserStatus(t.users[i], user.UserStatus_Play)
- userIds = append(userIds, usr.GetUserId())
- }
- t.tableStatus = TableStatus_Playing
- // 广播场景
- t.broadcastScene()
- if t.isPrivate() {
- go privateroom.SetRoomStatus(t.roomNo, privateroom.PrivateRoomStatus_Playing)
- }
- // 潜在好友
- go func(users []int) {
- reason := fmt.Sprintf("play %s", gameFrame.GetGameName())
- for i := 0; i < len(users)-1; i++ {
- for j := i + 1; j < len(users); j++ {
- coreservice.FriendAddPotential(users[i], users[j], reason)
- coreservice.FriendAddPotential(users[j], users[i], reason)
- }
- }
- }(userIds)
- }
- // 游戏结算后,调用
- func (t *ThreadsafeTable) EndGame() {
- if t.tableStatus != TableStatus_Playing {
- log.Debug("ThreadsafeTable.EndGame not playing status")
- return
- }
- // 将所有用户状态改变
- for i := 0; i < t.chairCount; i++ {
- if t.users[i] == -1 {
- continue
- }
- usr := gate.GetUserInfo(t.users[i])
- if usr == nil {
- // t.users[i] = -1
- continue
- }
- // 如果玩家得状态是准备,就不处理了
- if usr.GetUserStatus() == user.UserStatus_Ready {
- // 模拟发个准备
- go t.onUserReady(t.users[i], i, true)
- continue
- }
- gameFrame.setUserStatus(t.users[i], user.UserStatus_Sit)
- }
- t.tableStatus = TableStatus_Free
- gameFrame.removeOfflineByTableId(t.tableId)
- t.broadcastData(message.Table_GameEnd, "")
- if t.isPrivate() {
- go privateroom.SetRoomStatus(t.roomNo, privateroom.PrivateRoomStatus_Ended)
- }
- }
- func (t *ThreadsafeTable) MultiSetStart() {
- t.multiSetStatus = MultiSetStatus_Playing
- }
- func (t *ThreadsafeTable) MultiSetEnd() {
- t.multiSetStatus = MultiSetStatus_Free
- }
- func (t *ThreadsafeTable) GetUserByChair(chairId int) *user.UserInfo {
- if chairId < 0 || chairId >= len(t.users) {
- log.Debug("ThreadsafeTable.GetUserByChair %d not in %d", chairId, len(t.users))
- return nil
- }
- if t.users[chairId] == -1 {
- //log.Debug("ThreadsafeTable.GetUserByChair chair %d have no user", chairId)
- return nil
- }
- usr := t.getPlayer(t.users[chairId])
- if usr == nil {
- log.Debug("ThreadsafeTable.GetUserByChair chair %d user not exist", chairId)
- t.users[chairId] = -1
- return nil
- }
- return usr
- }
- // 踢人,fource表示就算玩家状态为Playing也踢走
- func (t *ThreadsafeTable) KickUser(userIndex int32, force bool) bool {
- for i := 0; i < t.chairCount; i++ {
- if t.users[i] == userIndex {
- return t.KickUserByChair(i, force)
- }
- }
- return false
- }
- func (t *ThreadsafeTable) KickUserByChair(chairId int, force bool) bool {
- usr := t.GetUserByChair(chairId)
- if usr == nil {
- return false
- }
- if !force && usr.GetUserStatus() == user.UserStatus_Play {
- log.Debug("ThreadsafeTable.KickUserByChair user is playing")
- return false
- }
- userIndex := usr.GetUserIndex()
- t.RemoveUser_safe(userIndex, !usr.IsRobot(), false)
- if force {
- gate.KickUser(userIndex)
- }
- return true
- }
- func (t *ThreadsafeTable) SendGameData(userIndex int32, msg, data string) {
- if userIndex == -1 {
- t.broadcastData(msg, data)
- return
- }
- // 检查userIndex是否有效
- for i := 0; i < t.chairCount; i++ {
- if t.users[i] == userIndex {
- gate.SendMessage(userIndex, msg, data)
- return
- }
- }
- for _, v := range t.watchUsers {
- if v.UserIndex == userIndex {
- gate.SendMessage(userIndex, msg, data)
- return
- }
- }
- log.Debug("ThreadsafeTable.SendGameData userIndex[%d][%s] not in table", userIndex, msg)
- }
- func (t *ThreadsafeTable) SendGameDataToChair(chairId int, msg, data string) {
- if chairId == -1 {
- t.broadcastData(msg, data)
- return
- }
- usr := t.GetUserByChair(chairId)
- if usr == nil {
- return
- }
- t.sendData(usr.GetUserIndex(), msg, data)
- }
- func (t *ThreadsafeTable) BroadcastToWatcher(msg, data string) {
- for _, v := range t.watchUsers {
- t.sendData(v.UserIndex, msg, data)
- }
- }
- func (t *ThreadsafeTable) GetPlayer(userIndex int32) *user.UserInfo {
- for i := 0; i < t.chairCount; i++ {
- if t.users[i] == userIndex {
- ret := gate.GetUserInfo(userIndex)
- if ret == nil {
- ret = gameFrame.getOfflineUser(userIndex)
- }
- return ret
- }
- }
- return nil
- }
- func (t *ThreadsafeTable) getPlayer(userIndex int32) *user.UserInfo {
- return t.GetPlayer(userIndex)
- }
- func (t *ThreadsafeTable) GetUserByUserId(userId int) *user.UserInfo {
- return gate.GetUserByUserId(userId)
- }
- func (t *ThreadsafeTable) GetPlayerByUserId(userId int) *user.UserInfo {
- for i := 0; i < t.chairCount; i++ {
- if t.users[i] == -1 {
- continue
- }
- usr := t.getPlayer(t.users[i])
- if usr == nil {
- continue
- }
- if usr.GetUserId() == userId {
- return usr
- }
- }
- return nil
- }
- func (t *ThreadsafeTable) GetUser(userIndex int32) (*user.UserInfo, bool) {
- usr := t.GetPlayer(userIndex)
- if usr != nil {
- return usr, true
- }
- // 旁观列表
- for _, v := range t.watchUsers {
- if v.UserIndex == userIndex {
- return gate.GetUserInfo(userIndex), false
- }
- }
- return nil, false
- }
- func (t *ThreadsafeTable) NotifySceneChanged(chairId int) {
- if chairId == -1 {
- t.broadcastScene()
- return
- }
- if !t.sendGameScene(chairId) {
- log.Debug("ThreadsafeTable NotifySceneChanged chairId[%d] is empty", chairId)
- }
- }
- func (t *ThreadsafeTable) onUserReady(userIndex int32, chairId int, isReady bool) {
- if isReady {
- t.tableSink.OnUserReady(userIndex, chairId)
- } else {
- t.tableSink.OnUserCancelReady(userIndex, chairId)
- }
- }
- func (t *ThreadsafeTable) WriteUserMoney(userId int, amount, tax int, status, scoreType int, sourceName string) (bool, int) {
- if scoreType < 100 {
- scoreType += gameFrame.gameSink.GetGameID() * 100
- }
- ret, amount := gate.WriteUserMoney(userId, amount, tax, status, scoreType, sourceName, gameFrame.gameSink.IsChipRoom())
- return ret, amount
- }
- func (t *ThreadsafeTable) WriteUserMoneyWithModifyAmount(userId int, amount, tax int, status, scoreType int, sourceName string) int {
- if scoreType < 100 {
- scoreType += gameFrame.gameSink.GetGameID() * 100
- }
- return gate.WriteUserMoneyWithModifyAmount(userId, amount, tax, status, scoreType, sourceName, gameFrame.gameSink.IsChipRoom())
- }
- func (t *ThreadsafeTable) WriteBetRecordWithPlayTime(userId int, betAmount int, winAmount int, winRate float64, betDesc string, resultDesc string, roomName string, secsBefore int) {
- //log.Debug("ThreadsafeTable.WriteBetRecordWithPlayTime[%d]", userId)
- // 机器人不写分
- usr := t.GetUserByUserId(userId)
- if usr != nil && usr.IsRobot() {
- log.Debug("ThreadsafeTable.WriteBetRecordWithPlayTime[%d] robot return", userId)
- return
- }
- t.writeBetRecordWithPlayTime(userId, betAmount, winAmount, winRate, betDesc, resultDesc, roomName, secsBefore)
- }
- func (t *ThreadsafeTable) delayReportUserBet() {
- t.reportUserBetsTimer = nil
- if len(t.tmpUserBets) == 0 {
- return
- }
- log.Debug("ThreadsafeTable.delayReportUserBet owner[%d] roomNo[%d] %v", t.owner, t.roomNo, t.tmpUserBets)
- audioroom.ReportUserBet(t.owner, t.roomNo, gameFrame.gameSink.GetGameID(), gameFrame.gameSink.GetRoomName(), t.tmpUserBets, gameFrame.IsChipRoom())
- t.tmpUserBets = []audioroom.UserBet{}
- }
- func (t *ThreadsafeTable) writeBetRecordWithPlayTime(userId int, betAmount int, winAmount int, winRate float64, betDesc string, resultDesc string, roomName string, secsBefore int) {
- gameId := gameFrame.gameSink.GetGameID()
- if gameFrame.gameSink.IsChipRoom() {
- transaction.WriteChipBetRecordAction(userId, gameId, "", betAmount, winAmount, 0, winRate, betDesc, resultDesc, secsBefore, "", roomName)
- } else {
- transaction.WriteBetRecordAction(userId, gameId, "", betAmount, winAmount, 0, winRate, betDesc, resultDesc, secsBefore, "", roomName)
- }
- go func() {
- if t.isMatch() {
- // 在比赛模块中完成任务
- //coreservice.DoTaskAction(userId, task.TaskAction_playmatch, 1, task.TaskScope{GameName: gameFrame.gameSink.GetGameName()})
- } else {
- task.DoTaskAction(userId, task.TaskAction_playgame, 1, task.TaskScope{GameName: gameFrame.gameSink.GetGameName()})
- task.DoTaskAction(userId, task.TaskAction_fire, betAmount, task.TaskScope{GameName: gameFrame.gameSink.GetGameName()})
- if winAmount-betAmount > 0 {
- task.DoTaskAction(userId, task.TaskAction_earn, winAmount-betAmount, task.TaskScope{GameName: gameFrame.gameSink.GetGameName()})
- task.DoTaskAction(userId, task.TaskAction_wingame, 1, task.TaskScope{GameName: gameFrame.gameSink.GetGameName()})
- }
- if winAmount > 0 {
- task.DoTaskAction(userId, task.TaskAction_betWin, winAmount, task.TaskScope{GameName: gameFrame.gameSink.GetGameName()})
- }
- }
- if !gameFrame.gameSink.IsChipRoom() {
- notification.AddNotification(userId, notification.Notification_Gold, "")
- //coreservice.AddGameExp(userId, gameId, winAmount-betAmount)
- coreservice.AddUserWinScore(userId, winAmount-betAmount)
- score := winAmount - betAmount
- if score < 0 {
- score = -score
- }
- if score > 0 {
- activityservice.TriggerSavingPot(userId, gameFrame.gameSink.GetGameID(), score)
- }
- }
- // 如果是语聊房游戏,存储并上报投注日志
- if t.GetOwner() > 0 && gameFrame.gameSink.GetChairCount() < 2 {
- t.tmpUserBets = append(t.tmpUserBets, audioroom.UserBet{
- UserId: userId,
- TotalBet: betAmount,
- TotalWin: winAmount,
- })
- if t.reportUserBetsTimer == nil {
- t.reportUserBetsTimer = time.AfterFunc(2*time.Second, t.delayReportUserBet)
- }
- }
- if gameFrame.IsLadderRoom() {
- //ladderservice.AddUserLadderScore(userId, gameId, roomName, winAmount-betAmount)
- }
- }()
- }
- func (t *ThreadsafeTable) WriteBetRecord(userId int, betAmount int, winAmount int, winRate float64, betDesc string, resultDesc string, roomName string) {
- // 机器人不写分
- usr := t.GetUserByUserId(userId)
- if usr != nil && usr.IsRobot() {
- return
- }
- secsBefore := int(time.Now().Unix() - t.startTime)
- t.writeBetRecordWithPlayTime(userId, betAmount, winAmount, winRate, betDesc, resultDesc, roomName, secsBefore)
- }
- func (t *ThreadsafeTable) WriteBetRecordWithSetcount(userId int, betAmount int, winAmount int, winRate float64, betDesc string, resultDesc string, roomName string, setCount int) {
- usr := t.GetUserByUserId(userId)
- if usr != nil && usr.IsRobot() {
- return
- }
- secsBefore := int(time.Now().Unix() - t.startTime)
- t.writeBetRecordWithPlayTime(userId, betAmount, winAmount, winRate, betDesc, resultDesc, roomName, secsBefore)
- go transaction.WriteBetRecordSetCount(userId, gameFrame.gameSink.GetGameID(), secsBefore, setCount)
- }
- func (t *ThreadsafeTable) FinishGame(userId int, baseScore, gameType, playerCount int) {
- if gameFrame.gameSink.IsChipRoom() {
- return
- }
- usr := t.GetPlayerByUserId(userId)
- if usr == nil || usr.IsRobot() {
- return
- }
- go coreservice.TriggerCouponTask(userId, gameFrame.gameSink.GetGameID(), baseScore, gameType, playerCount)
- }
- func (t *ThreadsafeTable) GetTableStatus() int {
- return t.tableStatus
- }
- func (t *ThreadsafeTable) IsPlaying() bool {
- return t.tableStatus == TableStatus_Playing
- }
- func (t *ThreadsafeTable) IsMultiSetPlaying() bool {
- return t.multiSetStatus == MultiSetStatus_Playing
- }
- func (t *ThreadsafeTable) RequestADAward(userIndex int32, losingAmount int) {
- if gameFrame.gameSink.IsChipRoom() {
- return
- }
- if losingAmount >= 0 {
- log.Debug("ThreadsafeTable.RequestADAward %d not losing %d", userIndex, losingAmount)
- return
- }
- usr := t.GetPlayer(userIndex)
- if usr == nil {
- log.Debug("ThreadsafeTable.RequestADAward user %d not exist", userIndex)
- return
- }
- if usr.IsRobot() {
- return
- }
- ret := coreservice.VideoSettleInfo(usr.GetUserId(), losingAmount, gameFrame.gameSink.GetGameID())
- if !ret.Success {
- log.Debug("coreservice.VideoSettleInfo failed %d %d", usr.GetUserId(), losingAmount)
- return
- }
- var rewardInfo message.AdRewardInfo
- rewardInfo.SerialNo = ret.TimeStamp
- rewardInfo.ReturnGold = ret.ReturnAmount
- rewardInfo.UserId = usr.GetUserId()
- rewardInfo.LosingGold = losingAmount
- rewardInfo.MaxTimes = ret.MaxTimes
- rewardInfo.SettleAmount = ret.SettleAmount
- log.Debug("coreservice.VideoSettleInfo Success %d %d", usr.GetUserId(), rewardInfo.ReturnGold)
- d, _ := json.Marshal(rewardInfo)
- // 发给客户端
- t.sendData(userIndex, message.Frame_ADRewardInfo, string(d))
- }
- func (t *ThreadsafeTable) LogWithTableId(format string, a ...interface{}) {
- f := fmt.Sprintf("[%d] %v", t.tableId, format)
- log.Debug(fmt.Sprintf(f, a...))
- }
- func (t *ThreadsafeTable) SetUserEndGame(chairId int) {
- t.LogWithTableId("SetUserEndGame %d", chairId)
- usr := t.GetUserByChair(chairId)
- if usr == nil {
- log.Debug("ThreadsafeTable.SetUserEndGame chair %d not exist", chairId)
- return
- }
- gameFrame.setUserStatus(usr.GetUserIndex(), user.UserStatus_Sit)
- //gameFrame.remove(t.tableId)
- // 如果掉线
- go gameFrame.removeOfflineUser(usr.GetUserId(), usr)
- }
- func (t *ThreadsafeTable) SetTimer(timerId int, delayMs int) {
- //log.Debug("[%d]ThreadsafeTable.SetTimer %d %d time[%d]", t.tableId, timerId, delayMs, time.Now().UnixNano()/1000000)
- t.KillTimer(timerId)
- timer := time.AfterFunc(time.Duration(delayMs)*time.Millisecond, func() {
- //log.Debug("[%d]ThreadsafeTable.OnTimer %d time[%d]", t.tableId, timerId, time.Now().UnixNano()/1000000)
- t.timerChan <- timerId
- t.timerLock.Lock()
- delete(t.timers, timerId)
- t.timerLock.Unlock()
- })
- t.timerLock.Lock()
- t.timers[timerId] = timer
- t.timerLock.Unlock()
- }
- func (t *ThreadsafeTable) KillTimer(timerId int) {
- t.timerLock.RLock()
- timer, ok := t.timers[timerId]
- t.timerLock.RUnlock()
- if !ok {
- return
- }
- t.timerLock.Lock()
- delete(t.timers, timerId)
- t.timerLock.Unlock()
- timer.Stop()
- }
- func (t *ThreadsafeTable) KillAllTimer() {
- t.killAllTimer()
- }
- func (t *ThreadsafeTable) killAllTimer() {
- t.timerLock.RLock()
- for _, v := range t.timers {
- v.Stop()
- }
- t.timerLock.RUnlock()
- }
- func (t *ThreadsafeTable) SendBroadcast(userId int, userName string, score int) {
- gameId := gameFrame.gameSink.GetGameID()
- gameName := gameFrame.gameSink.GetGameName()
- go coreservice.SendGameWinBroadcast(userId, userName, score, gameId, gameName)
- }
- func (t *ThreadsafeTable) Dismiss() {
- t.dismiss_safe()
- }
- func (t *ThreadsafeTable) GetUserChipOrGold(userIndex int32) int {
- return t.GetUserChipOrGoldByUser(t.GetPlayer(userIndex))
- }
- func (t *ThreadsafeTable) GetUserChipOrGoldByUserId(userId int) int {
- //return t.GetUserChipOrGoldByUser(t.GetPlayerByUserId(userId))
- u := gate.GetUserByUserId(userId)
- if u == nil {
- return 0
- }
- return t.GetUserChipOrGoldByUser(u)
- }
- func (t *ThreadsafeTable) GetUserChipOrGoldByUser(usr *user.UserInfo) int {
- if usr == nil {
- return 0
- }
- if gameFrame.gameSink.IsChipRoom() {
- return usr.GetChip()
- }
- return usr.GetUserGold()
- }
- func (t *ThreadsafeTable) GetPlayerCount() int {
- return t.getPlayerCount()
- }
- func (t *ThreadsafeTable) UpdateGameScore(userId, scoreDelta int) {
- if !t.isPrivate() {
- //log.Release("ThreadsafeTable.UpdateGameScore not private room")
- return
- }
- go privateroom.UpdateUserGameScore(t.roomNo, userId, scoreDelta)
- }
- func (t *ThreadsafeTable) DismissPrivateRoom() {
- if !t.isPrivate() {
- log.Release("ThreadsafeTable.DismissPrivateRoom not private room")
- return
- }
- go privateroom.DismissPrivateRoom(t.roomNo)
- }
- func (t *ThreadsafeTable) PrivateRoomSetWinners(winners []int) {
- if !t.isPrivate() {
- log.Release("ThreadsafeTable.PrivateRoomSetWinners not private room")
- return
- }
- privateroom.SetWinners(t.roomNo, winners)
- // 如果是百人场,就释放房间
- if gameFrame.gameSink.GetChairCount() < 2 {
- go gameFrame.removeTable(t.tableId)
- }
- }
- func (t *ThreadsafeTable) AddExperience(userId, exp int) int {
- if exp <= 0 {
- log.Release("ThreadsafeTable.AddExperience [%d:%d] invalid exp", userId, exp)
- return 0
- }
- return userservices.AddExperience(userId, exp)
- }
- func (t *ThreadsafeTable) GetUserList() []*user.UserInfo {
- var ret []*user.UserInfo
- for _, v := range t.watchUsers {
- usr, _ := t.GetUser(v.UserIndex)
- if usr != nil {
- ret = append(ret, usr)
- }
- }
- return ret
- }
- func (t *ThreadsafeTable) PrivateRoomGetRoomType() string {
- if !t.isPrivate() {
- log.Release("ThreadsafeTable.PrivateRoomGetRoomType not private room")
- return ""
- }
- return privateroom.GetRoomType(t.roomNo)
- }
- func (t *ThreadsafeTable) PrivateRoomGetFeeAndPrize(userId int) (int, int) {
- if !t.isPrivate() {
- log.Release("ThreadsafeTable.PrivateRoomGetFeeAndPrize not private room")
- return 0, 0
- }
- return privateroom.GetFeeAndPrize(t.roomNo, userId)
- }
- func (t *ThreadsafeTable) CloseTable() {
- go gameFrame.removeTable(t.tableId)
- }
|