| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356 |
- package handler
- import (
- "bet24.com/log"
- "bet24.com/servers/common"
- //"bet24.com/servers/coreservice/limiteditems"
- item "bet24.com/servers/micros/item_inventory/proto"
- notification "bet24.com/servers/micros/notification/proto"
- "encoding/json"
- "strconv"
- "sync"
- "time"
- )
- const DELAY_REMOVE = 300 // 300秒后删除用户
- const DELAY_CHECK = 60 // 每分钟检查一次
- var inventorymgr *inventory
- func getInventoryManager() *inventory {
- if inventorymgr == nil {
- inventorymgr = newInventory()
- }
- return inventorymgr
- }
- type inventory struct {
- lock *sync.RWMutex
- userInventory map[int]*user_inventory
- lockRemove *sync.RWMutex
- userRemove map[int]int64
- }
- func newInventory() *inventory {
- ret := new(inventory)
- ret.lock = &sync.RWMutex{}
- ret.userInventory = make(map[int]*user_inventory)
- ret.lockRemove = &sync.RWMutex{}
- ret.userRemove = make(map[int]int64)
- go ret.checkRemoveUser()
- return ret
- }
- func (this *inventory) checkRemoveUser() {
- time.AfterFunc(DELAY_CHECK*time.Second, this.checkRemoveUser)
- var toRemove []int
- latestRemoveTime := time.Now().Unix() - DELAY_REMOVE
- this.lockRemove.RLock()
- for k, v := range this.userRemove {
- if v < latestRemoveTime {
- toRemove = append(toRemove, k)
- }
- }
- this.lockRemove.RUnlock()
- if len(toRemove) == 0 {
- return
- }
- this.lockRemove.Lock()
- for _, v := range toRemove {
- delete(this.userRemove, v)
- }
- this.lockRemove.Unlock()
- for _, v := range toRemove {
- this.destroyUser(v)
- }
- }
- func (this *inventory) onUserEnter(userId int, ipAddress string) *user_inventory {
- this.lockRemove.Lock()
- delete(this.userRemove, userId)
- this.lockRemove.Unlock()
- this.lock.RLock()
- ui, ok := this.userInventory[userId]
- this.lock.RUnlock()
- if ok {
- return ui
- }
- ui = newUserInventory(userId, ipAddress)
- this.lock.Lock()
- this.userInventory[userId] = ui
- this.lock.Unlock()
- return ui
- }
- func (this *inventory) onUserExit(userId int) {
- this.lockRemove.Lock()
- this.userRemove[userId] = time.Now().Unix()
- this.lockRemove.Unlock()
- }
- func (this *inventory) destroyUser(userId int) {
- this.lock.RLock()
- s, _ := this.userInventory[userId]
- this.lock.RUnlock()
- if s == nil {
- return
- }
- s.destructor()
- this.lock.Lock()
- delete(this.userInventory, userId)
- this.lock.Unlock()
- }
- func (this *inventory) consume(userId int, itemId int, bullet int, count int, isGift int) (bool, string) {
- this.lock.RLock()
- ui, ok := this.userInventory[userId]
- this.lock.RUnlock()
- if !ok {
- ui = this.onUserEnter(userId, "")
- if ui != nil {
- return ui.consume(itemId, bullet, count, bullet, isGift)
- }
- log.Debug("inventory.consume userId[%d] not exist", userId)
- return false, "user not exist"
- }
- return ui.consume(itemId, bullet, count, bullet, isGift)
- }
- func (this *inventory) sell(userId, itemId, count, logType int) (bool, string) {
- this.lock.RLock()
- ui, ok := this.userInventory[userId]
- this.lock.RUnlock()
- if !ok {
- ui = this.onUserEnter(userId, "")
- if ui != nil {
- return ui.sell(itemId, count, logType)
- }
- log.Debug("inventory.sell userId[%d] not exist", userId)
- return false, "user not exist"
- }
- return ui.sell(itemId, count, logType)
- }
- func (this *inventory) consumeBulk(userId int, items []item.ItemPack, logType int) bool {
- this.lock.RLock()
- ui, ok := this.userInventory[userId]
- this.lock.RUnlock()
- if !ok {
- ui = this.onUserEnter(userId, "")
- if ui != nil {
- return ui.consumeBulk(items, logType)
- }
- log.Debug("inventory.consume userId[%d] not exist", userId)
- return false
- }
- return ui.consumeBulk(items, logType)
- }
- func (this *inventory) consumeLottery(userId, count int) (bool, string) {
- this.lock.RLock()
- ui, ok := this.userInventory[userId]
- this.lock.RUnlock()
- if !ok {
- ui = this.onUserEnter(userId, "")
- if ui != nil {
- return ui.consumeLottery(count)
- }
- log.Debug("inventory.consumeLottery userId[%d] not exist", userId)
- return false, "user not exist"
- }
- return ui.consumeLottery(count)
- }
- func (this *inventory) getUser(userId int, forceCreate bool) *user_inventory {
- this.lock.RLock()
- ret, ok := this.userInventory[userId]
- this.lock.RUnlock()
- if !ok {
- if forceCreate {
- return this.onUserEnter(userId, "")
- }
- return nil
- }
- return ret
- }
- func (this *inventory) addItemsWithExpireTime(userId int, items []item.ItemPack,
- desc string, logType int, expireTime int) bool {
- user := this.getUser(userId, false)
- toRemove := false
- if user == nil {
- user = newUserInventory(userId, "127.0.0.1")
- toRemove = true
- }
- ret := user.addItemsWithExpireTime(items, logType, expireTime)
- if toRemove {
- // 用户没有进来,不需要保存
- user.destructor()
- }
- return ret
- }
- func (this *inventory) addItems(userId int, items []item.ItemPack, desc string, logType int) bool {
- // log.Debug("iventorymgr.addItems userId=%d items=%+v desc=%s", userId, items, desc)
- user := this.getUser(userId, false)
- toRemove := false
- if user == nil {
- user = newUserInventory(userId, "127.0.0.1")
- toRemove = true
- }
- var itemIds []int
- for _, v := range items {
- //v.Count = limiteditems.AddItem(userId, v.ItemId, v.Count)
- user.addItem(v, logType)
- itemIds = append(itemIds, v.ItemId)
- }
- //通知客户端
- d, _ := json.Marshal(notification.NotificationInventory{ItemIds: itemIds, Action: Inventory_Add})
- notification.AddNotification(userId, notification.Notification_Inventory, string(d))
- if toRemove {
- // 用户没有进来,不需要保存
- user.destructor()
- }
- return true
- }
- func (this *inventory) getUserItems(userId int) []*item.UserItem {
- user := this.getUser(userId, true)
- if user == nil {
- log.Debug("inventory.getUserItems userId[%d] not exist", userId)
- return nil
- }
- return user.getItemList()
- }
- func (this *inventory) getItemCount(userId int, itemId int) int {
- user := this.getUser(userId, true)
- if user == nil {
- log.Debug("inventory.getItemCount userId[%d] not exist", userId)
- return 0
- }
- return user.getItemCount(itemId)
- }
- // 获取抽奖券
- func (this *inventory) getUserLottery(userId int) *item.UserItem {
- user := this.getUser(userId, true)
- if user == nil {
- log.Debug("inventory.getUserLottery userId[%d] not exist", userId)
- return nil
- }
- return user.getLottery()
- }
- // 赠送
- func (this *inventory) gift(userId, toUserId, itemId, count int) (bool, string) {
- // 先扣减
- retCode, msg := this.consume(userId, itemId, common.LOGTYPE_TRANSFER_CONSUME, count, 1)
- if !retCode {
- return retCode, msg
- }
- var items []item.ItemPack
- items = append(items, item.ItemPack{
- ItemId: itemId,
- Count: count,
- })
- // 加道具
- retCode = this.addItems(toUserId, items, "赠送", common.LOGTYPE_TRANSFER_ADD)
- return retCode, "成功"
- }
- func (iv *inventory) dumpSys(param string) {
- log.Release("-------------------------------")
- log.Release("inventory.dumpSys %s", param)
- defer func() {
- log.Release("+++++++++++++++++++++++++++++++")
- log.Release("")
- }()
- if param == "" {
- d, _ := json.Marshal(getItemManager().getItems())
- log.Release(string(d))
- } else {
- var itemId int
- var err error
- if itemId, err = strconv.Atoi(param); err != nil {
- log.Release("atoi error %v", err)
- return
- }
- d, _ := json.Marshal(getItemManager().getItem(itemId))
- log.Release(string(d))
- }
- }
- func (iv *inventory) dumpUser(param string) {
- log.Release("-------------------------------")
- log.Release("inventory.dumpUser %s", param)
- defer func() {
- log.Release("+++++++++++++++++++++++++++++++")
- log.Release("")
- }()
- if param == "all" {
- for k, v := range iv.userInventory {
- log.Release("%d:%d", k, v.userId)
- }
- return
- }
- var userId int
- var err error
- if userId, err = strconv.Atoi(param); err != nil {
- log.Release("atoi error %v", err)
- return
- }
- si := iv.getUserItems(userId)
- if si == nil {
- log.Release("user %d has no items", userId)
- return
- }
- d, _ := json.Marshal(si)
- log.Release(string(d))
- }
- func (this *inventory) reduceItemByAdmin(opUserID int, opUserName string, userId, itemId, count int) (bool, string) {
- toRemove := false
- user := this.getUser(userId, false)
- if user == nil {
- user = newUserInventory(userId, "127.0.0.1")
- toRemove = true
- }
- ok, msg := user.reduceItemByAdmin(opUserID, opUserName, itemId, count)
- if toRemove {
- // 用户没有进来,不需要保存
- user.destructor()
- }
- return ok, msg
- }
- func (this *inventory) checkDecortaionType(itemId int, t int, userId int) bool {
- userItem := this.getUser(userId, true)
- if userItem == nil {
- log.Release("inventory.checkDecortaionType userItem not found %d", userId)
- return false
- }
- // 有没有?
- if userItem.getItemCount(itemId) == 0 {
- log.Release("inventory.checkDecortaionType user[%d] do not have [%d]", userId, itemId)
- return false
- }
- return getItemManager().checkDecortaionType(itemId, t)
- }
|