| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421 |
- package gift
- import (
- "bet24.com/log"
- "bet24.com/servers/common"
- coreClient "bet24.com/servers/coreservice/client"
- badge "bet24.com/servers/micros/badge/proto"
- pb "bet24.com/servers/micros/giftservice/proto"
- item "bet24.com/servers/micros/item_inventory/proto"
- money "bet24.com/servers/micros/money/proto"
- notification "bet24.com/servers/micros/notification/proto"
- user "bet24.com/servers/micros/userservices/proto"
- "encoding/json"
- "sync"
- "time"
- )
- var mgr *giftmanager
- func getGiftManager() *giftmanager {
- if mgr == nil {
- mgr = new(giftmanager)
- }
- return mgr
- }
- type chargeInfo struct {
- userId int
- toUserId int
- productId string
- }
- type giftmanager struct {
- giftlist []pb.Gift
- lastConfigString string
- penddingChargeList []pendingcharge
- lock *sync.RWMutex
- }
- func (gm *giftmanager) run() {
- log.Debug("giftmanager.run()")
- gm.lock = &sync.RWMutex{}
- gm.loadConfig()
- gm.checkPendingCharge()
- }
- func (gm *giftmanager) checkPendingCharge() {
- time.AfterFunc(1*time.Minute, gm.checkPendingCharge)
- gm.lock.Lock()
- defer gm.lock.Unlock()
- for i := 0; i < len(gm.penddingChargeList); {
- v := gm.penddingChargeList[i]
- if v.isTimeout() {
- log.Release("giftmanager.checkPendingCharge removing [%d->%d][%s]", v.userId, v.toUserId, v.productId)
- gm.penddingChargeList = append(gm.penddingChargeList[:i], gm.penddingChargeList[i+1:]...)
- } else {
- i++
- }
- }
- }
- func (gm *giftmanager) dump(cmd, param1 string) {
- switch cmd {
- case "sys":
- gm.dumpSys()
- case "pending":
- gm.dumpPendingCharge()
- default:
- log.Release("giftmanager.dump unhandled cmd %s %s", cmd, param1)
- }
- }
- func (gm *giftmanager) dumpSys() {
- log.Release("-------------------------------")
- log.Release("giftmanager.dumpSys gift count[%d]", len(gm.giftlist))
- defer func() {
- log.Release("+++++++++++++++++++++++++++++++")
- log.Release("")
- }()
- for _, v := range gm.giftlist {
- log.Release(" Id[%d]Name[%s]Price[%.1f]Charm[%d->%d]Items%v", v.GiftId, v.Name, v.Price,
- v.SenderCharm, v.ReceiverCharm, v.Items)
- }
- }
- func (gm *giftmanager) dumpPendingCharge() {
- gm.lock.RLock()
- defer gm.lock.RUnlock()
- log.Release("-------------------------------")
- log.Release("giftmanager.dumpPendingCharge gift count[%d]", len(gm.penddingChargeList))
- defer func() {
- log.Release("+++++++++++++++++++++++++++++++")
- log.Release("")
- }()
- now := time.Now().Unix()
- for _, v := range gm.penddingChargeList {
- log.Release(" Id[%d]ToUserId[%d]ProductId[%s]Created[%d]", v.userId, v.toUserId, v.productId,
- now-v.createTime)
- }
- }
- func (gm *giftmanager) getGiftList(userId int) []pb.Gift {
- if len(gm.giftlist) == 0 {
- return nil
- }
- return gm.giftlist
- }
- func (gm *giftmanager) getGiftListString(userId int) string {
- list := gm.getGiftList(userId)
- if list == nil {
- return ""
- }
- d, _ := json.Marshal(list)
- return string(d)
- }
- func (gm *giftmanager) getGift(giftId int, userId int) *pb.Gift {
- if len(gm.giftlist) == 0 {
- return nil
- }
- for _, v := range gm.giftlist {
- if v.GiftId != giftId {
- continue
- }
- ret := v
- return &ret
- }
- return nil
- }
- func (gm *giftmanager) getGiftByProductId(productId string) *pb.Gift {
- if len(gm.giftlist) == 0 {
- return nil
- }
- for _, v := range gm.giftlist {
- if v.ProductId != productId {
- continue
- }
- ret := v
- return &ret
- }
- return nil
- }
- func (gm *giftmanager) sendGift(userId int, toUserId int, giftId int) (int, string) {
- if userId == 0 || toUserId == 0 || userId == toUserId {
- log.Release("giftmanager.sendGift UserId[%d->%d] GiftId[%d] invalid userId", userId, toUserId, giftId)
- return pb.SendGiftRet_Failed, "invalid userId "
- }
- g := gm.getGift(giftId, userId)
- if g == nil {
- log.Release("giftmanager.sendGift UserId[%d->%d] GiftId[%d] not found", userId, toUserId, giftId)
- return pb.SendGiftRet_Failed, "invalid giftId"
- }
- // 如果是赠送需要充值的物品,先记录,等充值完毕后再查询进行赠送
- if g.PayType == pb.PayType_RMB {
- gm.addChargeList(userId, toUserId, g.ProductId)
- return pb.SendGiftRet_Charge, g.ProductId
- }
- if g.PayType == pb.PayType_Diamond {
- // 扣钻石
- if money.ReduceChip(userId, int(g.Price), common.LOGTYPE_GIFT_SEND, "giftservice", "sendGift", "") != 1 {
- return pb.SendGiftRet_Failed, "not enough diamond"
- }
- } else {
- // 扣金币
- if !money.ReduceMoney(userId, int(g.Price), common.LOGTYPE_GIFT_SEND, "giftservice", "sendGift", "") {
- return pb.SendGiftRet_Failed, "not enough gold"
- }
- // 徽章进度
- go badge.DoAction(userId, badge.Action_PropConsumeGold, int(g.Price), badge.Scope{})
- }
- gm.doSendGift(userId, toUserId, g)
- return pb.SendGiftRet_OK, ""
- }
- // 赠送礼物,没有需要充值的物品
- func (gm *giftmanager) sendGiftBulk(userId int, toUserIds []int, giftId, num int) (int, string, *pb.Gift) {
- if userId == 0 || len(toUserIds) == 0 || num <= 0 {
- log.Release("giftmanager.sendGiftBulk UserId[%d->%+v] GiftId[%d] num[%d] invalid userId", userId, toUserIds, giftId, num)
- return pb.SendGiftRet_Failed, "invalid userId ", nil
- }
- g := gm.getGift(giftId, userId)
- if g == nil {
- log.Release("giftmanager.sendGiftBulk UserId[%d->%+v] GiftId[%d] num[%d] not found", userId, toUserIds, giftId, num)
- return pb.SendGiftRet_Failed, "invalid giftId", nil
- }
- items := make([]item.ItemPack, len(g.Items))
- copy(items, g.Items)
- oneGift := &pb.Gift{
- GiftId: g.GiftId,
- GiftType: g.GiftType,
- Name: g.Name,
- Desc: g.Name,
- Price: g.Price,
- PayType: g.PayType,
- ProductId: g.ProductId,
- SenderCharm: g.SenderCharm,
- ReceiverCharm: g.ReceiverCharm,
- Icon: g.Icon,
- Items: items,
- AnimationType: g.AnimationType,
- UserType: g.UserType,
- IsBottom: g.IsBottom,
- }
- // 计算总价(总价=单价*礼物数量*人数)
- totalPrice := int(oneGift.Price * float64(num*len(toUserIds)))
- // 多个礼物,计算总额
- if num > 1 {
- for i := 0; i < len(oneGift.Items); i++ {
- oneGift.Items[i].Count = oneGift.Items[i].Count * num
- }
- }
- if oneGift.PayType == pb.PayType_Diamond {
- // 扣钻石
- if money.ReduceChip(userId, totalPrice, common.LOGTYPE_GIFT_SEND, "giftservice", "sendGift", "") != 1 {
- return pb.SendGiftRet_Failed, "not enough diamond", nil
- }
- } else {
- // 扣金币
- if !money.ReduceMoney(userId, totalPrice, common.LOGTYPE_GIFT_SEND, "giftservice", "sendGift", "") {
- return pb.SendGiftRet_Failed, "not enough gold", nil
- }
- }
- for _, toUserId := range toUserIds {
- gm.doSendGift(userId, toUserId, oneGift)
- }
- return pb.SendGiftRet_OK, "", oneGift
- }
- func (gm *giftmanager) addChargeList(userId, toUserId int, productId string) {
- // 去重
- idx := gm.getChargeIndex(userId, toUserId, productId)
- if idx == -1 {
- gm.lock.Lock()
- gm.penddingChargeList = append(gm.penddingChargeList,
- pendingcharge{userId: userId, toUserId: toUserId, productId: productId})
- gm.lock.Unlock()
- }
- }
- func (gm *giftmanager) getChargeIndex(userId, toUserId int, productId string) int {
- gm.lock.RLock()
- defer gm.lock.RUnlock()
- for k, v := range gm.penddingChargeList {
- if v.isSame(userId, toUserId, productId) {
- return k
- }
- }
- return -1
- }
- func (gm *giftmanager) removeChargeInfo(userId, toUserId int, productId string) {
- gm.lock.Lock()
- defer gm.lock.Unlock()
- for i := 0; i < len(gm.penddingChargeList); {
- if gm.penddingChargeList[i].isSame(userId, toUserId, productId) {
- gm.penddingChargeList = append(gm.penddingChargeList[:i], gm.penddingChargeList[i+1:]...)
- } else {
- i++
- }
- }
- }
- func (gm *giftmanager) getAndRemovePendingCharge(userId int, productId string) *pendingcharge {
- var ret *pendingcharge
- gm.lock.Lock()
- defer gm.lock.Unlock()
- for i := 0; i < len(gm.penddingChargeList); {
- if gm.penddingChargeList[i].isSame(userId, 0, productId) {
- ret = &pendingcharge{
- userId: userId,
- productId: productId,
- toUserId: gm.penddingChargeList[i].toUserId,
- }
- gm.penddingChargeList = append(gm.penddingChargeList[:i], gm.penddingChargeList[i+1:]...)
- } else {
- i++
- }
- }
- return ret
- }
- // 充值成功后看下是否为赠送
- func (gm *giftmanager) checkGiftCharge(userId int, productId string) bool {
- pc := gm.getAndRemovePendingCharge(userId, productId)
- // 找不到
- if pc == nil {
- return false
- }
- // 给对方发物品
- g := gm.getGiftByProductId(productId)
- if g == nil {
- log.Release("giftmanager.checkGiftCharge [%d] [%s] not found", userId, productId)
- return false
- }
- return gm.doSendGift(userId, pc.toUserId, g)
- }
- func (gm *giftmanager) doSendGift(userId, toUserId int, g *pb.Gift) bool {
- // 成功了,给对方加道具
- d, _ := json.Marshal(g.Items)
- ug := pb.UserGift{
- Sender: userId,
- Receiver: toUserId,
- GiftId: g.GiftId,
- Items: string(d),
- SendTime: int(time.Now().Unix()),
- }
- ug.Rid = addUserGift(ug, g.GiftType)
- // 加魅力值
- go user.AddUserCharm(userId, g.SenderCharm)
- go user.AddUserCharm(toUserId, g.ReceiverCharm)
- // 发送私聊信息
- // 语音房不发私聊
- ugData, _ := json.Marshal(ug)
- if pb.GiftType_AudioRoom != g.GiftType {
- coreClient.SendGiftMessage(userId, toUserId, string(ugData))
- }
- // 发通知给对方
- notification.AddNotification(userId, notification.Notification_GiftSent, string(ugData))
- if g.AnimationType == pb.AnimationType_Global {
- notification.AddNotification(-1, notification.Notification_ReceiveGift, string(ugData))
- } else {
- notification.AddNotification(toUserId, notification.Notification_ReceiveGift, string(ugData))
- }
- // 潜在好友
- go coreClient.FriendAddPotential(userId, toUserId, "send gift")
- go coreClient.FriendAddPotential(toUserId, userId, "receive gift")
- return true
- }
- func (gm *giftmanager) getUnclaimedGifts(userId int) []pb.UserGift {
- return getUnclaimedGifts(userId)
- }
- func (gm *giftmanager) claimGift(userId, rid int) string {
- itemString := claimUserGift(userId, rid, int(time.Now().Unix()))
- log.Debug("giftmanager.claimGift [%d][%d] returns %s", userId, rid, itemString)
- type tmpItems struct {
- Items string
- }
- var retItems []tmpItems
- err := json.Unmarshal([]byte(itemString), &retItems)
- if err != nil {
- log.Release("giftmanager.claimGift Unmarshal1 failed %s", itemString)
- return ""
- }
- if len(retItems) == 0 {
- return ""
- }
- var itms []item.ItemPack
- err = json.Unmarshal([]byte(retItems[0].Items), &itms)
- if err == nil && len(itms) > 0 {
- item.AddItems(userId, itms, "claim gift", common.LOGTYPE_GIFT_RECEIVE)
- } else {
- log.Release("giftmanager.claimGift Unmarshal2 failed %s", itemString)
- }
- return retItems[0].Items
- }
- func (gm *giftmanager) getReceivedGiftRecord(userId int) string {
- //log.Debug("giftmanager.getReceivedGiftRecord userId[%d]", userId)
- ret := getReceivedGiftHistory(userId, pb.GiftType_Nomal, 6)
- type tmpItems struct {
- GiftID int
- Items string
- }
- var itms []tmpItems
- err := json.Unmarshal([]byte(ret), &itms)
- if err != nil {
- log.Release("giftmanager.getReceivedGiftRecord Unmarshal failed %s", ret)
- return ""
- }
- //log.Debug("giftmanager.getReceivedGiftRecord userId[%d] itms[%s] ", userId, ret)
- type giftAndItems struct {
- GiftId int
- Items []item.ItemPack
- }
- var retItems []giftAndItems
- for _, v := range itms {
- var oneItems []item.ItemPack
- err := json.Unmarshal([]byte(v.Items), &oneItems)
- if err == nil {
- retItems = append(retItems, giftAndItems{GiftId: v.GiftID, Items: oneItems})
- } else {
- log.Debug("giftmanager.getReceivedGiftRecord userId[%d] Unmarshal failed[%s]", userId, v.Items)
- }
- }
- d, _ := json.Marshal(retItems)
- log.Debug("giftmanager.getReceivedGiftRecord userId[%d] ret[%s] ", userId, string(d))
- return string(d)
- }
|