package bacframe import ( "encoding/json" "fmt" "math/rand" "strconv" "sync" "time" "bet24.com/log" "bet24.com/redis" coreservice "bet24.com/servers/coreservice/client" "bet24.com/servers/insecureframe/gate" "bet24.com/servers/insecureframe/message" notification "bet24.com/servers/micros/notification/proto" task "bet24.com/servers/micros/task/proto" "bet24.com/servers/transaction" "bet24.com/servers/user" ) func NewGameFrame(gameSink GameSink) *GameFrame { f := new(GameFrame) f.gameSink = gameSink f.lock_user = &sync.RWMutex{} f.userlist = make(map[int32]*user.UserInfo) log.Debug("bac gameframe running...") return f } type GameFrame struct { gameSink GameSink lock_user *sync.RWMutex userlist map[int32]*user.UserInfo } // implement GateSink func (f *GameFrame) GetServerPort() int { return f.gameSink.GetServerPort() } func (f *GameFrame) OnUserEnter(userIndex int32) { } func (f *GameFrame) OnUserLogined(userIndex int32) { usr := gate.GetUserInfo(userIndex) if usr == nil { log.Debug("GameFrame.OnUserLogined invalid userIndex %d", userIndex) return } f.lock_user.Lock() f.userlist[userIndex] = usr f.lock_user.Unlock() // 先发自己 f.sendUserEnter(usr, userIndex) // 发其他人 f.lock_user.RLock() for k, v := range f.userlist { if k == userIndex { continue } f.sendUserEnter(usr, k) f.sendUserEnter(v, userIndex) } f.lock_user.RUnlock() f.gameSink.OnUserEnter(userIndex) } func (f *GameFrame) OnUserExit(userIndex int32) { usr := gate.GetUserInfo(userIndex) if usr == nil { log.Debug("GameFrame.OnUserExit user[%d] not exist", userIndex) return } userId := usr.GetUserId() f.lock_user.Lock() delete(f.userlist, userIndex) f.lock_user.Unlock() f.lock_user.RLock() for _, v := range f.userlist { f.sendUserExit(userId, v.GetUserIndex()) } f.lock_user.RUnlock() f.gameSink.OnUserExit(userIndex) } func (f *GameFrame) OnGameMessage(userIndex int32, userID int, msg, data string) bool { switch msg { case message.Frame_ADReward: f.recvAdReward(userIndex, data) return true case message.Frame_Ping: f.recvFramePing(userIndex, data) return true default: return f.gameSink.OnGameMessage(userIndex, userID, msg, data) } } func (f *GameFrame) GetGameID() int { return f.gameSink.GetGameID() } func (f *GameFrame) GetGameName() string { return f.gameSink.GetGameName() } func (f *GameFrame) GetRoomName() string { return f.gameSink.GetRoomName() } func (f *GameFrame) GetCertFile() string { return f.gameSink.GetCertFile() } func (f *GameFrame) GetKeyFile() string { return f.gameSink.GetKeyFile() } // 机器人配置 func (f *GameFrame) GetRobotCount() int { return f.gameSink.GetRobotCount() } func (f *GameFrame) GetRobotGoldLimit() (min, max int) { min, max = f.gameSink.GetRobotGoldLimit() return } func (f *GameFrame) GetRobotOnlineSec() int { return f.gameSink.GetRobotOnlineSec() } func (f *GameFrame) IsChipRoom() bool { return f.gameSink.IsChipRoom() } func (f *GameFrame) GetVersionID() int { return f.gameSink.GetVersionID() } func (f *GameFrame) IsPrivateRoom() bool { return false } func (f *GameFrame) GetChipRoom() int { if f.gameSink.IsChipRoom() { return 1 } else { return 0 } } func (f *GameFrame) OnPlatformConfig(key string) { f.gameSink.OnPlatformConfig(key) } // BacFrame func (f *GameFrame) NotifySceneChanged(userIndex int32) { f.SendGameData(userIndex, message.Table_GameScene, f.gameSink.OnGetGameScene()) } func (f *GameFrame) KickUser(userIndex int32) bool { return gate.KickUser(userIndex) } // 如果userindex == -1 表示发给所有人 func (f *GameFrame) SendGameData(userIndex int32, msg, data string) { if userIndex == -1 { gate.BroadcastData(msg, data) return } //log.Debug("GameFrame.SendGameData %d[%s]", userIndex, msg) gate.SendMessage(userIndex, msg, data) } func (f *GameFrame) GetUser(userIndex int32) *user.UserInfo { return gate.GetUserInfo(userIndex) } func (f *GameFrame) GetUserByUserId(userId int) *user.UserInfo { return gate.GetUserByUserId(userId) } func (f *GameFrame) WriteUserMoney(userId int, amount, tax int, status, scoreType int, sourceName string) (bool, int) { if scoreType < 100 { scoreType += f.gameSink.GetGameID() * 100 } return gate.WriteUserMoney(userId, amount, tax, status, scoreType, sourceName, f.gameSink.IsChipRoom()) } func (f *GameFrame) WriteUserMoneyWithModifyAmount(userId int, amount, tax int, status, scoreType int, sourceName string) int { if scoreType < 100 { scoreType += f.gameSink.GetGameID() * 100 } return gate.WriteUserMoneyWithModifyAmount(userId, amount, tax, status, scoreType, sourceName, f.gameSink.IsChipRoom()) } func (f *GameFrame) WriteBetRecord(userId int, betAmount int, winAmount int, tax int, winRate float64, betDesc string, resultDesc string, roomName string) { // 机器人不写日志 usr := f.GetUserByUserId(userId) if usr == nil || !usr.IsRobot() { gameId := f.gameSink.GetGameID() gameName := f.gameSink.GetGameName() if f.gameSink.IsChipRoom() { transaction.WriteChipBetRecordAction(userId, gameId, "", betAmount, winAmount, tax, winRate, betDesc, resultDesc, 0, "", roomName) } else { transaction.WriteBetRecordAction(userId, gameId, "", betAmount, winAmount, tax, winRate, betDesc, resultDesc, 0, "", roomName) } go func() { task.DoTaskAction(userId, task.TaskAction_playgame, 1, task.TaskScope{GameName: gameName}) task.DoTaskAction(userId, task.TaskAction_fire, betAmount, task.TaskScope{GameName: gameName}) if winAmount-betAmount > 0 { task.DoTaskAction(userId, task.TaskAction_earn, winAmount-betAmount, task.TaskScope{GameName: gameName}) task.DoTaskAction(userId, task.TaskAction_wingame, 1, task.TaskScope{GameName: gameName}) } if winAmount > 0 { task.DoTaskAction(userId, task.TaskAction_betWin, winAmount, task.TaskScope{GameName: gameName}) } if !f.gameSink.IsChipRoom() { notification.AddNotification(userId, notification.Notification_Chip, "") //coreservice.AddGameExp(userId, gameId, winAmount-betAmount) coreservice.AddUserWinScore(userId, winAmount-betAmount) } }() } if winAmount >= 3000000 { userName := strconv.Itoa(userId) if usr != nil { userName = usr.GetUserNickName() } f.SendBroadcast(userId, userName, winAmount) } } func (f *GameFrame) GetUserList() []*user.UserInfo { return gate.GetUserList() } func (f *GameFrame) sendUserEnter(usr *user.UserInfo, toUser int32) { if usr == nil { log.Debug("GameFrame.sendUserEnter usr == nil") return } info := usr.GetUserInfo_Table(toUser == usr.GetUserIndex()) d, _ := json.Marshal(info) gate.SendMessage(toUser, message.Table_UserEnter, string(d)) } func (f *GameFrame) sendUserExit(userId int, toUser int32) { info := message.TableUserExit{UserId: userId, ChairId: 0, ToWatch: false} d, _ := json.Marshal(info) gate.SendMessage(toUser, message.Table_UserExit, string(d)) } func (f *GameFrame) GetVirtualUserCount(userCount int, roomType int) int { if roomType < 0 { roomType = 0 } else { roomType = roomType % 1 } userCounts := [][]int{} userCounts = append(userCounts, []int{95, 120, 168, 196, 234}) hour := time.Now().Hour() hourIndex := 0 if hour >= 18 { hourIndex = 4 } else if hour >= 14 { hourIndex = 3 } else if hour >= 11 { hourIndex = 2 } else if hour >= 6 { hourIndex = 1 } param := 86 return userCount*param + userCounts[roomType][hourIndex] - 10 + rand.Intn(20) } func (f *GameFrame) recvAdReward(userIndex int32, data string) bool { usr := gate.GetUserInfo(userIndex) if usr == nil { log.Debug("GameFrame.recvAdReward user not exist") return false } serialNo, err := strconv.Atoi(data) if err != nil { log.Debug("GameFrame.recvAdReward invalid argument [%s]", data) return false } // 调用coreservice的视频奖励 // 根据返回信息刷新金币,并通知用户 var rewarded message.AdRewarded rewarded.UserId = usr.GetUserId() rewarded.SerialNo = serialNo rewarded.Gold = coreservice.VideoSettle(rewarded.UserId, serialNo) d, _ := json.Marshal(rewarded) log.Debug("GameFrame.recvAdReward sending data %s", string(d)) gate.SendMessage(userIndex, message.Frame_ADReward, string(d)) if rewarded.Gold > 0 { gate.RefreshGold(userIndex) } return true } func (f *GameFrame) recvFramePing(userIndex int32, data string) bool { gate.SendMessage(userIndex, message.Frame_Ping, data) return true } func (f *GameFrame) SendBroadcast(userId int, userName string, score int) { gameId := f.gameSink.GetGameID() gameName := f.gameSink.GetGameName() go coreservice.SendGameWinBroadcast(userId, userName, score, gameId, gameName) } func (f *GameFrame) GetUserChipOrGold(userIndex int32) int { return f.GetUserChipOrGoldByUser(f.GetUser(userIndex)) } func (f *GameFrame) GetUserChipOrGoldByUserId(userId int) int { return f.GetUserChipOrGoldByUser(f.GetUserByUserId(userId)) } func (f *GameFrame) GetUserChipOrGoldByUser(usr *user.UserInfo) int { if usr == nil { return 0 } if gameFrame.gameSink.IsChipRoom() { return usr.GetChip() } return usr.GetUserGold() } func (f *GameFrame) UpdateRoomList(roomName, addr string) { addrKey := "Addr" onlineKey := "Online" if f.gameSink.IsChipRoom() { addrKey = "ChipAddr" onlineKey = "ChipOnline" } gameName := f.gameSink.GetGameName() if gameName == "Battle" { gameName = "dragontiger" } redis.String_SetEx(fmt.Sprintf("%s:%s:%v", gameName, addrKey, roomName), addr, 70) online := fmt.Sprintf("%d", f.GetVirtualUserCount(gate.GetPlayerCount(), 0)) redis.String_SetEx(fmt.Sprintf("%s:%s:%v", gameName, onlineKey, roomName), online, 70) } func (f *GameFrame) dump(param string) { switch param { default: log.Release(" user count :%d", gate.GetPlayerCount()) } } func (f *GameFrame) IsLadderRoom() bool { gameSink_LadderRoom, ok := f.gameSink.(GameSink_LadderRoom) return ok && gameSink_LadderRoom.IsLadderRoom() }