package video import ( "bet24.com/log" "bet24.com/servers/common" inventory "bet24.com/servers/micros/item_inventory/proto" item "bet24.com/servers/micros/item_inventory/proto" "sort" "sync" "time" ) type user_video struct { userId int lock *sync.RWMutex video_list map[int]*userVideo settle_list []*settleVideoInfo } func newUserVideo(userId int) *user_video { ret := new(user_video) ret.userId = userId ret.lock = &sync.RWMutex{} ret.video_list = make(map[int]*userVideo) //加载数据 go ret.loadUserVideo() go ret.loadSettleVideo() //log.Debug("newUserVideo %d", userId) return ret } func (this *user_video) loadUserVideo() { now := common.GetTimeStamp() list := getUserVideoList(this.userId) for _, v := range list { if common.IsSameDay(now, v.UpdateTime) { continue } v.PlayTimes = 0 v.UpdateTime = now this.updateToDB(v, 0, "userVideo.loadUserVideo") } this.lock.Lock() this.video_list = list this.lock.Unlock() } func (this *user_video) loadSettleVideo() { list := getGameSettleVideoList(this.userId) // 按时间顺序 sort.SliceStable(list, func(i, j int) bool { return list[i].Crdate < list[j].Crdate }) this.lock.Lock() this.settle_list = list this.lock.Unlock() } func (this *user_video) getVideo(videoId int) *userVideo { if videoId <= 0 { return nil } this.lock.RLock() for _, v := range this.video_list { if v.VideoId == videoId { this.lock.RUnlock() return v } } this.lock.RUnlock() uv := &userVideo{ VideoId: videoId, PlayTimes: 0, UpdateTime: common.GetTimeStamp(), } this.lock.Lock() this.video_list[videoId] = uv this.lock.Unlock() this.updateToDB(uv, 0, "userVideo.getVideo") return uv } func (this *user_video) updateToDB(uv *userVideo, isStat int, funcName string) { go updateUserVideo(this.userId, uv, isStat, funcName) } func (this *user_video) play(videoId int) (bool, int, []item.ItemPack) { success, v, s := this.getInfo(videoId) if !success { return false, 0, nil } if v == nil { return false, 0, nil } v.PlayTimes++ v.UpdateTime = common.GetTimeStamp() this.updateToDB(v, 1, "userVideo.play") return true, v.PlayTimes, s.Awards } func (this *user_video) getInfo(videoId int) (bool, *userVideo, *video) { s := mgr.getSysVideo(videoId) if s == nil { log.Debug("uservideo.getInfo getSysVideo userId=%d videoId=%d is not exist", this.userId, videoId) return false, nil, nil } v := this.getVideo(videoId) if v == nil { log.Debug("uservideo.getInfo getVideo userId=%d videoId=%d is not exist", this.userId, videoId) return false, nil, s } now := common.GetTimeStamp() if !common.IsSameDay(now, v.UpdateTime) { v.PlayTimes = 0 v.UpdateTime = now this.updateToDB(v, 0, "userVideo.getInfo") } if v.PlayTimes >= s.PlayTimes { return false, v, s } return true, v, s } func (this *user_video) getSettleInfo(gameId, settleAmount int, sysInfo *settleVideo) *settleInfo_resp { log.Debug("uservideo.getSettleInfo userId=%d gameId=%d settleAmount=%d sysInfo=%+v", this.userId, gameId, settleAmount, sysInfo) maxAmount := settleAmount * sysInfo.MaxRate / 100 if maxAmount <= 0 { return &settleInfo_resp{} } // 保留最近20条 max := 20 this.lock.Lock() if count := len(this.settle_list); count >= max { this.settle_list = append(this.settle_list[:count-max], this.settle_list[count-max+1:]...) } now := time.Now() ts := common.GetStamp(now) info := &settleVideoInfo{ SettleId: 0, GameID: gameId, LoseAmount: settleAmount, MaxTimes: sysInfo.MaxTimes, SettleTimes: 0, MaxAmount: maxAmount, SettleAmount: 0, Crdate: now.Format(common.Layout), TimeStamp: ts, } this.settle_list = append(this.settle_list, info) this.lock.Unlock() // 更新到数据库 go addGameSettleVideo(this.userId, info) return &settleInfo_resp{ Success: true, TimeStamp: ts, ReturnAmount: maxAmount, MaxTimes: sysInfo.MaxTimes, SettleAmount: maxAmount / sysInfo.MaxTimes, } } func (this *user_video) settle(ts int) (bool, int) { amount, info := 0, &settleVideoInfo{} this.lock.RLock() for _, v := range this.settle_list { if v.TimeStamp == ts { info = v break } } this.lock.RUnlock() // 没有找到数据 if info == nil { return false, amount } log.Debug("uservideo.settle userId=%d ts=%d info=%+v", this.userId, ts, info) // 判断是否已经领完 if info.SettleTimes >= info.MaxTimes || info.SettleAmount >= info.MaxAmount { return false, amount } // 最后一次全部给 if info.SettleTimes == info.MaxTimes-1 { amount = info.MaxAmount - info.SettleAmount } else { // 否则均分 amount = info.MaxAmount / info.MaxTimes } // 没有可领取的金币 if amount <= 0 { return false, amount } // 加次数、金币 info.SettleTimes++ info.SettleAmount += amount log.Debug("uservideo.settle userId=%d ts=%d info=%+v", this.userId, ts, info) // 更新数据库 go awardGameSettleVideo(this.userId, info) var items []item.ItemPack items = append(items, item.ItemPack{ ItemId: 1, Count: amount, }) // 发送道具 if success := inventory.AddItems(this.userId, items, "看视频游戏结算输返还", info.GameID*100+common.LOGTYPE_VIDEO_GAME_RETURN); !success { log.Error("video.settle AddItems fail userId=%d items=%+v", this.userId, items) } return true, amount } // 游戏返还视频列表 func (this *user_video) getGameSettleVideoList() []*settleVideoInfo { this.lock.RLock() defer this.lock.RUnlock() return this.settle_list } // 游戏返还视频奖励 func (this *user_video) awardGameSettleVideo(settleId int) *awardRetInfo { ret, info := &awardRetInfo{}, &settleVideoInfo{} this.lock.RLock() for _, v := range this.settle_list { if v.SettleId == settleId { info = v break } } this.lock.RUnlock() // 没有找到数据 if info == nil { ret.RetCode = 11 return ret } log.Debug("uservideo.awardGameSettleVideo userId=%d settleId=%d info=%+v", this.userId, settleId, info) // 判断是否已经领完 if info.SettleTimes >= info.MaxTimes || info.SettleAmount >= info.MaxAmount { ret.RetCode = 12 return ret } // 最后一次全部给 if info.SettleTimes == info.MaxTimes-1 { ret.Amount = info.MaxAmount - info.SettleAmount } else { // 否则均分 ret.Amount = info.MaxAmount / info.MaxTimes } // 没有可领取的金币 if ret.Amount <= 0 { ret.RetCode = 11 return ret } // 加次数、金币 info.SettleTimes++ info.SettleAmount += ret.Amount log.Debug("uservideo.awardGameSettleVideo userId=%d settleId=%d info=%+v", this.userId, settleId, info) // 更新数据库 go awardGameSettleVideo(this.userId, info) var items []item.ItemPack items = append(items, item.ItemPack{ ItemId: 1, Count: ret.Amount, }) // 发送道具 if success := inventory.AddItems(this.userId, items, "看视频游戏结算输返还", info.GameID*100+common.LOGTYPE_VIDEO_GAME_RETURN); !success { log.Error("video.awardGameSettleVideo AddItems fail userId=%d items=%+v", this.userId, items) } ret.RetCode = 1 return ret } // 检查小红点 func (this *user_video) checkTip() bool { this.lock.RLock() defer this.lock.RUnlock() for _, v := range this.settle_list { if v.SettleTimes < v.MaxTimes { return true } } return false }