go_dreamfactory/modules/items/modelitems.go
2023-06-02 11:49:44 +08:00

582 lines
15 KiB
Go

package items
import (
"fmt"
"go_dreamfactory/comm"
"go_dreamfactory/lego/core"
"go_dreamfactory/modules"
"go_dreamfactory/pb"
"go_dreamfactory/sys/configure"
cfg "go_dreamfactory/sys/configure/structs"
"go_dreamfactory/sys/db"
"math"
"time"
"go.mongodb.org/mongo-driver/bson/primitive"
"go.mongodb.org/mongo-driver/mongo"
"go.mongodb.org/mongo-driver/x/bsonx"
)
///背包缓存数据管理组件
type ModelItemsComp struct {
modules.MCompModel
module *Items
}
//组件初始化接口
func (this *ModelItemsComp) Init(service core.IService, module core.IModule, comp core.IModuleComp, opt core.IModuleOptions) (err error) {
this.TableName = comm.TableItems
this.MCompModel.Init(service, module, comp, opt)
this.module = module.(*Items)
//创建uid索引
this.DB.CreateIndex(core.SqlTable(this.TableName), mongo.IndexModel{
Keys: bsonx.Doc{{Key: "uid", Value: bsonx.Int32(1)}},
})
return
}
///查询用户背包数据
func (this *ModelItemsComp) QueryUserPack(uId string) (itmes []*pb.DB_UserItemData, err error) {
var (
model *db.DBModel
)
itmes = make([]*pb.DB_UserItemData, 0)
if this.module.IsCross() {
if model, err = this.module.GetDBModelByUid(uId, this.TableName); err != nil {
this.module.Errorln(err)
} else {
if err = model.GetList(uId, &itmes); err != nil {
this.module.Errorf("err:%v", err)
}
}
} else {
if err = this.GetList(uId, &itmes); err != nil {
this.module.Errorf("err:%v", err)
}
}
return
}
///查询用户指定格子的物品数据
func (this *ModelItemsComp) QueryUserPackByGridId(uId string, grid string) (itme *pb.DB_UserItemData, err error) {
var (
model *db.DBModel
)
itme = &pb.DB_UserItemData{}
if this.module.IsCross() {
if model, err = this.module.GetDBModelByUid(uId, this.TableName); err != nil {
this.module.Errorln(err)
} else {
if err = model.GetListObj(uId, grid, itme); err != nil {
this.module.Errorf("err:%v", err)
}
}
} else {
if err = this.GetListObj(uId, grid, itme); err != nil {
this.module.Errorf("err:%v", err)
}
}
return
}
///查询用户指定格子的物品数据
func (this *ModelItemsComp) QueryUserPackByGridIds(uId string, grids []string) (itme []*pb.DB_UserItemData, err error) {
var (
model *db.DBModel
)
itme = make([]*pb.DB_UserItemData, len(grids))
if this.module.IsCross() {
if model, err = this.module.GetDBModelByUid(uId, this.TableName); err != nil {
this.module.Errorln(err)
} else {
if err = model.GetListObjs(uId, grids, &itme); err != nil {
this.module.Errorf("err:%v", err)
}
}
} else {
if err = this.GetListObjs(uId, grids, &itme); err != nil {
this.module.Errorf("err:%v", err)
}
}
return
}
//更新用户的背包信息
func (this *ModelItemsComp) AddUserPack(uId string, itmes ...*pb.DB_UserItemData) (err error) {
data := make(map[string]*pb.DB_UserItemData)
for _, v := range itmes {
data[v.GridId] = v
}
var (
model *db.DBModel
)
if this.module.IsCross() {
if model, err = this.module.GetDBModelByUid(uId, this.TableName); err != nil {
this.module.Errorln(err)
} else {
if err = model.AddLists(uId, data); err != nil {
this.module.Errorf("err:%v", err)
}
}
} else {
if err = this.AddLists(uId, data); err != nil {
this.module.Errorln(err)
}
}
return
}
//更新用户的背包信息
func (this *ModelItemsComp) UpdateUserPack(uid string, itmes ...*pb.DB_UserItemData) (err error) {
var (
model *db.DBModel
)
if this.module.IsCross() {
if model, err = this.module.GetDBModelByUid(uid, this.TableName); err != nil {
this.module.Errorln(err)
} else {
for _, v := range itmes {
model.ChangeList(uid, v.GridId, map[string]interface{}{
"amount": v.Amount,
"isNewItem": v.IsNewItem,
"lastopt": configure.Now().Unix(),
})
}
}
} else {
for _, v := range itmes {
this.ChangeList(uid, v.GridId, map[string]interface{}{
"amount": v.Amount,
"isNewItem": v.IsNewItem,
"lastopt": configure.Now().Unix(),
})
}
}
return
}
//更新用户的背包信息
func (this *ModelItemsComp) DeleteUserPack(uid string, itmes ...*pb.DB_UserItemData) (err error) {
var (
model *db.DBModel
)
gridIds := make([]string, len(itmes))
for i, v := range itmes {
gridIds[i] = v.GridId
}
if this.module.IsCross() {
if model, err = this.module.GetDBModelByUid(uid, this.TableName); err != nil {
this.module.Errorln(err)
} else {
if err = model.DelListlds(uid, gridIds); err != nil {
this.module.Errorf("err:%v", err)
return
}
}
} else {
if len(gridIds) > 0 {
if err = this.DelListlds(uid, gridIds); err != nil {
this.module.Errorf("err:%v", err)
return
}
}
}
return
}
//查询用户背包物品数量
func (this *ModelItemsComp) QueryUserPackItemsAmount(uId string, itemid ...string) (result map[string]uint32) {
var (
itmes []*pb.DB_UserItemData
err error
)
if itmes, err = this.QueryUserPack(uId); err != nil {
this.module.Errorf("err:%v", err)
return
}
result = map[string]uint32{}
for _, v := range itmes {
for _, v1 := range itemid {
if v.ItemId == v1 {
result[v1] += v.Amount
}
}
}
return
}
///添加或则减少物品到用户背包
func (this *ModelItemsComp) AddItemToUserPack(uId string, itemId string, addnum int32) (change []*pb.DB_UserItemData, err error) {
var (
itmes []*pb.DB_UserItemData
add []*pb.DB_UserItemData
del []*pb.DB_UserItemData
update []*pb.DB_UserItemData
leftnum int64
)
if addnum == 0 {
return
}
if itmes, err = this.QueryUserPack(uId); err != nil {
this.module.Errorf("err:%v", err)
return
}
change = make([]*pb.DB_UserItemData, 0)
if add, update, del, leftnum, err = this.addItemToUserPack(uId, itmes, itemId, addnum); err != nil {
return
}
if leftnum < 0 {
err = ItemNotEnoughError
return
} else if leftnum > 0 {
err = PackGridNumUpper
return
}
if len(add) > 0 {
if err = this.AddUserPack(uId, add...); err != nil {
this.module.Errorf("err:%v", err)
return
}
change = append(change, add...)
}
if len(del) > 0 {
if err = this.DeleteUserPack(uId, del...); err != nil {
this.module.Errorf("err:%v", err)
return
}
change = append(change, del...)
}
if len(update) > 0 {
if err = this.UpdateUserPack(uId, update...); err != nil {
this.module.Errorf("err:%v", err)
return
}
change = append(change, update...)
}
return
}
///添加或则减少多个物品到用户背包
func (this *ModelItemsComp) AddItemsToUserPack(uId string, items map[string]int32) (change []*pb.DB_UserItemData, err error) {
var (
itmes []*pb.DB_UserItemData
add []*pb.DB_UserItemData
del []*pb.DB_UserItemData
update []*pb.DB_UserItemData
leftnum int64
)
if itmes, err = this.QueryUserPack(uId); err != nil {
this.module.Errorf("err:%v", err)
return
}
change = make([]*pb.DB_UserItemData, 0)
for k, v := range items {
if add, update, del, leftnum, err = this.addItemToUserPack(uId, itmes, k, v); err != nil {
return
}
if leftnum < 0 {
err = ItemNotEnoughError
return
} else if leftnum > 0 {
err = PackGridNumUpper
return
}
if len(add) > 0 {
if err = this.AddUserPack(uId, add...); err != nil {
this.module.Errorf("err:%v", err)
return
}
change = append(change, add...)
//
}
if len(del) > 0 {
if err = this.DeleteUserPack(uId, del...); err != nil {
this.module.Errorf("err:%v", err)
return
}
change = append(change, del...)
}
if len(update) > 0 {
if err = this.UpdateUserPack(uId, update...); err != nil {
this.module.Errorf("err:%v", err)
return
}
change = append(change, update...)
}
}
return
}
///修改指定格子的物品数量
func (this *ModelItemsComp) AddItemToUserPackByGrid(uId string, gridid string, addnum int32) (change []*pb.DB_UserItemData, err error) {
var (
conf *cfg.GameItemData
itme *pb.DB_UserItemData
num int64
amount int64
)
if addnum == 0 {
return
}
if itme, err = this.QueryUserPackByGridId(uId, gridid); err != nil {
this.module.Errorf("err:%v", err)
return
}
if conf, err = this.module.configure.GetItemConfigure(itme.ItemId); err != nil {
this.module.Errorf("err:%v", err)
return
}
amount = int64(itme.Amount)
num = amount + int64(addnum)
change = make([]*pb.DB_UserItemData, 0)
if num < 0 {
err = ItemNotEnoughError
} else {
if conf.UpperLimit > 0 && num > int64(conf.UpperLimit) {
err = GirdAmountUpper
return
} else {
itme.Amount = uint32(num)
if itme.Amount > 0 {
this.UpdateUserPack(uId, itme)
} else {
this.DeleteUserPack(uId, itme)
}
change = append(change, itme)
}
}
return
}
///添加移除物品到用户背包
func (this *ModelItemsComp) addItemToUserPack(uid string, items []*pb.DB_UserItemData, itemId string, addnum int32) (add, update, del []*pb.DB_UserItemData, leftnum int64, err error) {
var (
conf *cfg.GameItemData
num int64
isNew bool
)
if addnum == 0 {
return
}
if conf, err = this.module.configure.GetItemConfigure(itemId); err != nil {
this.module.Errorln(err)
err = NoFoundItemConfig
return
}
if conf.UpperLimit == 0 {
err = fmt.Errorf("item UpperLimit is 0")
return
}
isNew = true
leftnum = int64(addnum)
add = make([]*pb.DB_UserItemData, 0)
del = make([]*pb.DB_UserItemData, 0)
update = make([]*pb.DB_UserItemData, 0)
for _, v := range items {
if v.ItemId == itemId {
isNew = false
num = int64(v.Amount) + int64(leftnum)
if num < 0 {
leftnum += int64(v.Amount)
v.Amount = 0
del = append(del, v)
} else if num > 0 && num < int64(v.Amount) {
leftnum = 0
v.Amount = uint32(num)
update = append(update, v)
break
} else if num > 0 && num > int64(v.Amount) {
if conf.UpperLimit > 0 {
if num <= int64(conf.UpperLimit) {
leftnum = 0
v.Amount = uint32(num)
update = append(update, v)
break
} else {
if v.Amount < uint32(conf.UpperLimit) {
leftnum = int64(num - int64(conf.UpperLimit))
v.Amount = uint32(conf.UpperLimit)
update = append(update, v)
}
}
} else {
leftnum = 0
v.Amount = uint32(num)
update = append(update, v)
}
} else if num == 0 {
leftnum = 0
v.Amount = 0
del = append(del, v)
}
}
}
if leftnum < 0 { //背包物品不够
return
}
if leftnum > 0 { //还没有放完 寻找空的格子填充
index := int32(len(items))
for leftnum > 0 { //需要补充格子
if conf.UpperLimit < 0 || (conf.UpperLimit > 0 && leftnum <= int64(conf.UpperLimit)) {
grid := &pb.DB_UserItemData{
GridId: primitive.NewObjectID().Hex(),
UId: uid,
ItemId: itemId,
Amount: uint32(leftnum),
CTime: configure.Now().Unix(),
IsNewItem: isNew,
}
if conf.Time > 0 {
grid.ETime = configure.Now().Add(time.Minute * time.Duration(conf.Time)).Unix()
}
items = append(items, grid)
add = append(add, grid)
leftnum = 0
break
} else {
leftnum -= int64(conf.UpperLimit)
grid := &pb.DB_UserItemData{
GridId: primitive.NewObjectID().Hex(),
UId: uid,
ItemId: itemId,
Amount: uint32(conf.UpperLimit),
CTime: configure.Now().Unix(),
IsNewItem: isNew,
}
if conf.Time > 0 {
grid.ETime = configure.Now().Add(time.Minute * time.Duration(conf.Time)).Unix()
}
items = append(items, grid)
add = append(add, grid)
index++
}
if index > GridMaxNUm { //格子已达上限
break
}
}
}
return
}
//购买门票
func (this *ModelItemsComp) buyTicket(session comm.IUserSession, buy int32) (info *pb.DBUserExpand, code pb.ErrorCode) {
var (
need *cfg.Gameatn
needs []*cfg.Gameatn
maxbuy, vipbuy int
err error
)
if info, err = this.module.ModuleUser.GetUserExpand(session.GetUserId()); err != nil {
code = pb.ErrorCode_CacheReadError
return
}
this.module.modelItems.recoverTicket(session)
if maxbuy, err = this.module.configure.GetchallengeDataCount(); err != nil {
code = pb.ErrorCode_ConfigNoFound
return
}
vipbuy = int(this.module.privilege.GetCountByPrivilegeId(session.GetUserId(), comm.PrivilegeType3))
needs = make([]*cfg.Gameatn, 0)
for i := int32(0); i < buy; i++ {
if int(info.Buyunifiedticket+i+1) > maxbuy+vipbuy {
code = pb.ErrorCode_ArenaTicketBuyUp
return
}
if need = this.module.configure.GetchallengeData(int(info.Buyunifiedticket + i + 1)); err != nil || need == nil {
code = pb.ErrorCode_ConfigNoFound
return
}
needs = append(needs, need)
}
if code = this.module.ConsumeRes(session, needs, true); code != pb.ErrorCode_Success {
return
}
atn := this.module.ModuleTools.GetGlobalConf().CopsBuyGet
res := &cfg.Gameatn{
A: atn.A,
T: atn.T,
N: atn.N * buy,
}
info.Buyunifiedticket += buy
if code = this.module.DispenseRes(session, []*cfg.Gameatn{res}, true); code != pb.ErrorCode_Success {
return
}
this.module.ModuleUser.ChangeUserExpand(session.GetUserId(), map[string]interface{}{
"buyunifiedticket": info.Buyunifiedticket,
"lasttimeunifiedticket": info.Lasttimeunifiedticket,
"recovertimeunifiedticket": info.Recovertimeunifiedticket,
})
return
}
///回复门票
func (this *ModelItemsComp) recoverTicket(session comm.IUserSession) (code pb.ErrorCode) {
var (
user *pb.DBUser
info *pb.DBUserExpand
duration time.Duration
ticketitem *cfg.Gameatn
ticket int32
ticketNum int32
err error
)
if ticketitem = this.module.ModuleTools.GetGlobalConf().CopsBuyGet; ticketitem == nil {
code = pb.ErrorCode_ConfigNoFound
// data = &pb.ErrorData{
// Title: code.ToString(),
// Message: comm.NewNotFoundConfErr(modelName, "global.json", "PsItem").Error(),
// }
return
}
if user = this.module.ModuleUser.GetUser(session.GetUserId()); user == nil {
code = pb.ErrorCode_CacheReadError
return
}
if info, err = this.module.ModuleUser.GetUserExpand(session.GetUserId()); err != nil {
code = pb.ErrorCode_CacheReadError
return
}
if time.Unix(info.Lasttimeunifiedticket, 0).Day() < configure.Now().Day() {
info.Lasttimeunifiedticket = configure.Now().Unix()
info.Buyunifiedticket = 0
}
global := this.module.ModuleTools.GetGlobalConf()
playerlv := this.module.configure.GetPlayerlvConf(user.Lv)
ticket = int32(this.module.ModuleItems.QueryItemAmount(session.GetUserId(), ticketitem.T))
if ticket < global.DreamlandFightnum && info.Recovertimeunifiedticket > 0 {
duration = configure.Now().Sub(time.Unix(info.Recovertimeunifiedticket, 0))
ticketNum = int32(math.Floor(duration.Seconds() / float64(global.CopsRecoveryTime)))
if ticketNum > 0 {
if ticketNum+ticket > playerlv.CopsPsCeiling {
ticketNum = playerlv.CopsPsCeiling - ticket
}
this.module.DispenseRes(session, []*cfg.Gameatn{{A: ticketitem.A, T: ticketitem.T, N: ticketNum}}, true)
info.Recovertimeunifiedticket = time.Unix(info.Recovertimeunifiedticket, 0).Add(time.Duration(ticketNum) * time.Minute).Unix()
}
}
this.module.ModuleUser.ChangeUserExpand(session.GetUserId(), map[string]interface{}{
"buyunifiedticket": info.Buyunifiedticket,
"lasttimeunifiedticket": info.Lasttimeunifiedticket,
"recovertimeunifiedticket": info.Recovertimeunifiedticket,
})
return
}