go_dreamfactory/modules/caravan/module.go
2024-01-05 11:33:06 +08:00

539 lines
16 KiB
Go

package caravan
import (
"context"
"go_dreamfactory/comm"
"go_dreamfactory/lego/base"
"go_dreamfactory/lego/core"
"go_dreamfactory/lego/sys/log"
"go_dreamfactory/modules"
"go_dreamfactory/pb"
"go_dreamfactory/sys/configure"
cfg "go_dreamfactory/sys/configure/structs"
"go_dreamfactory/sys/db"
"go_dreamfactory/utils"
"math"
"strconv"
"go.mongodb.org/mongo-driver/bson"
"go.mongodb.org/mongo-driver/mongo/options"
)
type Caravan struct {
modules.ModuleBase
modelCaravan *modelCaravan
api *apiComp
configure *configureComp
service base.IRPCXService
mail comm.Imail
rank *ModelRank
}
func NewModule() core.IModule {
return &Caravan{}
}
func (this *Caravan) GetType() core.M_Modules {
return comm.ModuleCaravan
}
func (this *Caravan) Init(service core.IService, module core.IModule, options core.IModuleOptions) (err error) {
if err = this.ModuleBase.Init(service, module, options); err != nil {
return
}
this.service = service.(base.IRPCXService)
return
}
func (this *Caravan) Start() (err error) {
if err = this.ModuleBase.Start(); err != nil {
return
}
var module core.IModule
if module, err = this.service.GetModule(comm.ModuleMail); err != nil {
return
}
this.mail = module.(comm.Imail)
this.service.RegisterFunctionName(string(comm.Rpc_ModuleCaravanSettlement), this.Rpc_ModuleCaravanSettlement)
return
}
func (this *Caravan) OnInstallComp() {
this.ModuleBase.OnInstallComp()
this.api = this.RegisterComp(new(apiComp)).(*apiComp)
this.modelCaravan = this.RegisterComp(new(modelCaravan)).(*modelCaravan)
this.configure = this.RegisterComp(new(configureComp)).(*configureComp)
this.rank = this.RegisterComp(new(ModelRank)).(*ModelRank)
}
// 接口信息 修改数据
func (this *Caravan) ModifyCaravanData(uid string, data map[string]interface{}) (errdata *pb.ErrorData) {
err := this.modelCaravan.modifyCaravanDataByObjId(uid, data)
if err != nil {
errdata = &pb.ErrorData{
Code: pb.ErrorCode_DBError,
Title: pb.ErrorCode_DBError.ToString(),
Message: err.Error(),
}
}
return
}
// 初始化城市信息
func (this *Caravan) InitCaravanCityData(uid string, data *pb.DBCaravan) {
list := this.configure.GetAllCaravanCity()
data.City = make(map[int32]*pb.CityInfo, 0)
for _, v := range list {
city := &pb.CityInfo{
Special: []string{},
Count: map[string]int32{}, // 数量默认0
Exspecial: []string{}, // 想要玩家买的商品
ExspecialPCT: 0,
Nextexspecial: []string{}, // 下一次变动时间
NextexspecialPCT: 0,
}
if len(v.Special) > int(v.Citytypenum) {
ids := utils.RandomNumbers(0, len(v.Special), int(v.Citytypenum))
for _, id := range ids {
city.Special = append(city.Special, v.Special[id])
}
} else {
city.Special = append(city.Special, v.Special...)
}
if len(v.Exspecial) > int(v.ExspecialNum) {
ids := utils.RandomNumbers(0, len(v.Exspecial), int(v.ExspecialNum))
for _, id := range ids {
city.Exspecial = append(city.Exspecial, v.Exspecial[id])
}
} else {
city.Exspecial = append(city.Exspecial, v.Exspecial...)
}
city.ExspecialPCT = v.Exspecialnum[comm.GetRandW(v.ExspecialnumWeight)] // 获取权重
if len(v.Exspecial) > int(v.ExspecialNum) {
ids := utils.RandomNumbers(0, len(v.Exspecial), int(v.ExspecialNum))
for _, id := range ids {
city.Nextexspecial = append(city.Nextexspecial, v.Exspecial[id])
}
} else {
city.Nextexspecial = append(city.Nextexspecial, v.Exspecial...)
}
city.NextexspecialPCT = v.Exspecialnum[int(comm.GetRandW(v.ExspecialnumWeight))] // 获取权重
data.City[v.Id] = city
}
data.Citystime = utils.GetZeroTime(configure.Now().Unix())
data.Rtime = configure.Now().Unix() // 修改时间
}
// 初始化货物信息
func (this *Caravan) InitCaravanItemData(uid string, data *pb.DBCaravan) {
if len(data.Allgoods) != 0 {
return
}
items := this.configure.GetAllCaravanItem()
data.Allgoods = make(map[int32]*pb.GoodsInfo, 0)
if data.Period == nil {
data.Period = make(map[string]*pb.GoodPeriod)
}
var index int32
for index = 0; index < this.configure.GetCityRefreshTime(); index++ {
goodinfo := &pb.GoodsInfo{
Goods: make(map[string]int32, 0),
}
for _, c := range items {
var price int32
if _, ok := data.Period[c.Itemid]; !ok {
data.Period[c.Itemid] = &pb.GoodPeriod{}
}
if _, ok := data.Allgoods[index-1]; ok {
if _, ok := data.Allgoods[index-1].Goods[c.Itemid]; ok {
price = data.Allgoods[index-1].Goods[c.Itemid] // 获取上一次价格
}
}
if price == 0 { //
price = c.Goodsprice // 获取默认值
}
data.Period[c.Itemid].CurPeriod += 1
if len(c.Changeperiod) == 2 && data.Period[c.Itemid].Period == 0 {
data.Period[c.Itemid].Period = comm.GetRandNum(c.Changeperiod[0], c.Changeperiod[1])
data.Period[c.Itemid].Weightpos = comm.GetRandW(c.PriceChangeWeight)
}
if data.Period[c.Itemid].Period < data.Period[c.Itemid].CurPeriod {
data.Period[c.Itemid].Period = comm.GetRandNum(c.Changeperiod[0], c.Changeperiod[1])
data.Period[c.Itemid].CurPeriod = 0
data.Period[c.Itemid].Weightpos = comm.GetRandW(c.PriceChangeWeight) // 随机涨幅
}
bUp := false
if data.Period[c.Itemid].Weightpos == 0 {
if comm.GetRandW(c.PriceChangeWeightOne) == 0 { // 走配置表一类涨幅
bUp = true
}
} else if data.Period[c.Itemid].Weightpos == 1 {
if comm.GetRandW(c.PriceChangeWeightTwo) == 0 {
bUp = true
}
} else if data.Period[c.Itemid].Weightpos == 2 {
if comm.GetRandW(c.PriceChangeWeightThree) == 0 {
bUp = true
}
}
if len(c.FluctuationRange) == 2 {
p := comm.GetRandNum(c.PriceChangeWeightThree[0], c.PriceChangeWeightThree[1])
if bUp { // 价格上涨
price = int32(math.Floor(float64(price) * (1.0 + float64(p)/1000.0)))
} else {
price = int32(math.Floor(float64(price) * (1.0 - float64(p)/1000.0)))
}
}
if price < c.Pricemin { // 设置最小值
price = c.Pricemin
}
if price > c.Pricemax { // 设置最大值
price = c.Pricemax
}
goodinfo.Goods[c.Itemid] = price
}
data.Allgoods[index] = goodinfo
}
}
// 初始化门票和虚拟币
func (this *Caravan) InitCaravanTicket(session comm.IUserSession, conf *cfg.GameCaravanLvData) (errdata *pb.ErrorData) {
var (
res []*cfg.Gameatn
atno []*pb.UserAtno
)
res = append(res, conf.Tickettop)
res = append(res, conf.Moneynumtop)
if errdata, atno = this.DispenseAtno(session, res, true); errdata != nil { // 推送门票和虚拟币资源
return
}
go this.AsynHandleSession(session.Clone(), func(session comm.IUserSession) {
this.WriteUserLog(session.GetUserId(), "", 0, "InitCaravanTicket", atno)
})
return
}
// 刷新城市货物信息
func (this *Caravan) refreshCaravanCityInfo(uid string, caravan *pb.DBCaravan) {
var (
bChange bool
update map[string]interface{}
cityRtime int64
)
update = make(map[string]interface{})
cityRtime = utils.GetZeroTime(configure.Now().Unix())
// 刷新城市货物信息
if cityRtime != caravan.Citystime {
list := this.configure.GetAllCaravanCity()
for _, conf := range list {
if v, ok := caravan.City[conf.Id]; ok {
v.Count = make(map[string]int32) // 初始化城市信息
v.Special = []string{}
if len(conf.Special) > int(conf.Citytypenum) {
ids := utils.RandomNumbers(0, len(conf.Special), int(conf.Citytypenum))
for _, id := range ids {
v.Special = append(v.Special, conf.Special[id])
}
} else {
v.Special = append(v.Special, conf.Special...)
}
if utils.IsToday(caravan.Citystime) {
v.Exspecial = make([]string, 0)
v.Exspecial = append(v.Exspecial, v.Nextexspecial...)
v.ExspecialPCT = v.NextexspecialPCT
} else { // 初始化今天
v.Exspecial = make([]string, 0)
// 初始化下一天的信息
if len(conf.Exspecial) > int(conf.ExspecialNum) {
ids := utils.RandomNumbers(0, len(conf.Exspecial), int(conf.ExspecialNum))
for _, id := range ids {
v.Exspecial = append(v.Exspecial, conf.Exspecial[id])
}
} else {
v.Exspecial = append(v.Exspecial, conf.Exspecial...)
}
v.ExspecialPCT = conf.Exspecialnum[comm.GetRandW(conf.ExspecialnumWeight)] // 获取权重
}
/////////////////////
v.Nextexspecial = []string{}
// 初始化下一天的信息
if len(v.Exspecial) > int(conf.ExspecialNum) {
ids := utils.RandomNumbers(0, len(conf.Exspecial), int(conf.ExspecialNum))
for _, id := range ids {
v.Nextexspecial = append(v.Nextexspecial, conf.Exspecial[id])
}
} else {
v.Nextexspecial = append(v.Nextexspecial, conf.Exspecial...)
}
v.NextexspecialPCT = conf.Exspecialnum[comm.GetRandW(conf.ExspecialnumWeight)] // 获取权重
}
}
caravan.Citystime = cityRtime // 设置第二天0点的时间
update["city"] = caravan.City
update["citystime"] = caravan.Citystime
bChange = true
}
if bChange {
this.modelCaravan.modifyCaravanDataByObjId(uid, update)
}
}
// 校验随机事件是否超时
func (this *Caravan) CheckCaravanTask(session comm.IUserSession, data *pb.DBCaravan) (bTimeOut bool) {
if data.Tasktime != 0 {
if list, err := this.configure.GetCaravanEventById(data.Eventid); err == nil {
// 校验任务是否超时
if configure.Now().Unix()-data.Tasktime > int64(list.Eventtime) { //TODO 任务超时 通知任务模块处理 并清理相关数据
module, err := this.service.GetModule(comm.ModuleWtask)
if err != nil {
return
}
if wt, ok := module.(comm.IWtask); ok {
wt.ClearCaravanTask(session, data.Taskid) // 通知任务模块 任务超时
}
this.CleanCaravanTask(session.GetUserId(), data) //任务超时 清理任务数据
data.Eventid = 0
data.Tasktime = 0
data.Eventid = 0
update := make(map[string]interface{})
update["eventid"] = data.Eventid
update["tasktime"] = data.Tasktime
update["eventid"] = data.Eventid
this.modelCaravan.modifyCaravanDataByObjId(session.GetUserId(), update)
// 任务超时发送任务失败推送
resp := &pb.CaravanTaskCompletePush{}
resp.Eventid = data.Eventid
resp.Tasktime = data.Tasktime
resp.Eventid = data.Eventid
resp.BSuccess = false
bTimeOut = true
if len(list.Unreword) == 2 && list.Unreword[0] == 1 { // 类型为1 的 直接扣除虚拟币
this.ConsumeRes(session, []*cfg.Gameatn{{
A: "attr",
T: "merchantmoney",
N: list.Unreword[1],
}}, true)
resp.Reward = append(resp.Reward, &pb.UserAtno{
A: "attr",
T: "merchantmoney",
N: -list.Unreword[1], // 扣除虚拟币
})
go this.AsynHandleSession(session.Clone(), func(session comm.IUserSession) {
this.WriteUserLog(session.GetUserId(), "", comm.GMResDelType, "CheckCaravanTask", resp.Reward) // 消耗资源
})
}
session.SendMsg(string(this.GetType()), "taskcomplete", resp)
}
}
}
return false
}
func (this *Caravan) CleanCaravanTask(uid string, data *pb.DBCaravan) {
if data.Eventid != 0 {
data.Eventid = 0
data.Taskid = 0
data.Tasktime = 0
update := make(map[string]interface{})
update["eventid"] = data.Eventid
update["taskid"] = data.Taskid
update["tasktime"] = data.Tasktime
this.modelCaravan.modifyCaravanDataByObjId(uid, update)
}
}
func (this *Caravan) TaskComplete(session comm.IUserSession, taskid ...int32) {
this.Debug("Caravan TaskComplete",
log.Field{Key: "session", Value: session.GetUserId()},
log.Field{Key: "taskid", Value: taskid},
)
var (
resp *pb.CaravanTaskCompletePush
)
if !this.IsCross() {
for _, t := range taskid {
list, _ := this.modelCaravan.getCaravanList(session.GetUserId())
if list.Taskid == t {
if conf, err := this.configure.GetCaravanEventById(list.Eventid); err == nil {
this.CleanCaravanTask(session.GetUserId(), list) //任务完成 清理任务数据
resp = &pb.CaravanTaskCompletePush{}
resp.BSuccess = true
var (
atno []*pb.UserAtno
errdata *pb.ErrorData
)
if errdata, atno = this.ModuleBase.DispenseAtno(session, conf.Reword, true); errdata != nil {
this.Errorf("Caravan DispenseRes err:%v", conf.Reword)
} else {
resp.Reward = atno
}
session.SendMsg(string(this.GetType()), "taskcomplete", resp)
go this.AsynHandleSession(session.Clone(), func(session comm.IUserSession) {
this.WriteUserLog(session.GetUserId(), taskid, comm.GMResAddType, "TaskComplete", atno)
})
}
}
}
}
}
// 整理背包 (true 表示背包装不下)
func (this *Caravan) ArrayBag(data *pb.DBCaravan) {
for k, v := range data.Items {
if v.Count == 0 {
delete(data.Items, k)
}
}
return
}
// 校验货物是否超重
func (this *Caravan) CheckOverweight(data *pb.DBCaravan) (b bool) {
var weight int32
for k, v := range data.Items {
if d, err := this.configure.GetCaravanGoods(k); err == nil {
weight += d.Weight * v.Count
if weight > data.Baglimit {
return true
}
}
}
return false
}
// 获得利润判断是否能提升商队等级
func (this *Caravan) CheckCaravavLvUp(data *pb.DBCaravan) (curLv int32) {
curLv = 1
for {
if conf, err := this.configure.GetCaravanLv(curLv); err == nil {
if conf.Newmoneyexp <= int32(data.Profit) {
//data.Profit -= int64(conf.Newmoneyexp)
curLv++
} else {
break
}
} else {
break
}
}
return curLv
}
// 赛季结算
func (this *Caravan) Rpc_ModuleCaravanSettlement(ctx context.Context, args *pb.EmptyReq, reply *pb.EmptyResp) (err error) {
this.Debug("Rpc_ModuleCaravanSettlement",
log.Field{Key: "args", Value: args.String()},
)
go func() {
var (
rankIndex int32
stag string
)
conn_, err := db.Cross() // 获取跨服数据库对象
if err != nil {
return
}
model := db.NewDBModelByExpired(db.CrossTag(), comm.TableCaravanRank, conn_)
if model == nil {
return
}
var maxKey int32
for _, v := range this.configure.GetCaravanReward() {
if v.Key > maxKey {
maxKey = v.Key
}
}
moreReard, err := this.configure.GetCaravanMoreReward() // 超过部分
if err != nil {
return
}
min := this.ModuleTools.GetGlobalConf().BusinessRankmoney
if _data, err := model.DB.Find(comm.TableCaravanRank, bson.M{"merchantmoney": bson.M{"$gte": min}}, options.Find().SetSort(bson.M{"merchantmoney": -1}).SetLimit(int64(comm.MaxRankNum))); err == nil {
//if _data, err := this.modelCaravan.DB.Find(comm.TableUser, bson.M{"merchantmoney": bson.M{"$gt": 0}}, options.Find().SetSort(bson.M{"merchantmoney": -1}).SetLimit(comm.MaxRankList)); err == nil {
for _data.Next(context.TODO()) {
rankIndex++
temp := &pb.DBCaravanRank{}
if err = _data.Decode(temp); err == nil {
if stag, err = comm.UidToSTag(temp.Uid); err != nil {
return
}
if this.service.GetTag() == stag {
if carConf, err := this.configure.GetCaravanRank(rankIndex); err == nil {
this.mail.SendMailByUID(temp.Uid, "CaravanRank", carConf.Reward, []string{strconv.Itoa(int(rankIndex))})
}
if maxKey < temp.Merchantmoney { // 超过部分转换其他奖励发送
var res []*cfg.Gameatn
for _, v := range moreReard.Reward {
if v.N == 0 {
continue
}
atn := &cfg.Gameatn{
A: v.A,
T: v.T,
N: v.N * (temp.Merchantmoney - maxKey),
}
res = append(res, atn)
}
this.mail.SendMailByUID(temp.Uid, "CaravanRewards", res, []string{})
}
}
}
}
}
Query := bson.M{}
Query["merchantmoney"] = 0
Query["profit"] = 0
if _, err = model.DB.UpdateMany(core.SqlTable(comm.TableUser), bson.M{"merchantmoney": bson.M{"$gt": 0}}, bson.M{"$set": Query}, options.MergeUpdateOptions().SetUpsert(true)); err != nil {
this.Errorf("Update Merchantmoney Many error: %v", err)
}
return
}()
return
}
func (this *Caravan) TaskGroupComplete(session comm.IUserSession, group int32) {
if list, err := this.modelCaravan.getCaravanList(session.GetUserId()); err != nil {
if _, ok := list.Group[group]; !ok {
list.Group[group] = true
update := make(map[string]interface{})
update["group"] = list.Group
this.modelCaravan.modifyCaravanDataByObjId(session.GetUserId(), update)
}
}
}