431 lines
13 KiB
Go
431 lines
13 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/utils"
|
|
"math"
|
|
"strconv"
|
|
"time"
|
|
|
|
"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
|
|
}
|
|
|
|
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) {
|
|
err = this.ModuleBase.Init(service, module, options)
|
|
this.service = service.(base.IRPCXService)
|
|
return
|
|
}
|
|
|
|
func (this *Caravan) Start() (err error) {
|
|
err = this.ModuleBase.Start()
|
|
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)
|
|
}
|
|
|
|
// 接口信息 修改数据
|
|
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 字段数据)
|
|
Count: map[string]int32{}, // key 货物ID
|
|
}
|
|
|
|
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...)
|
|
}
|
|
data.City[v.Id] = city
|
|
}
|
|
}
|
|
|
|
// 初始化货物信息
|
|
func (this *Caravan) InitCaravanItemData(uid string, data *pb.DBCaravan) {
|
|
items := this.configure.GetAllCaravanItem()
|
|
data.Goods = make(map[string]*pb.Goods, 0)
|
|
for _, v := range items {
|
|
goods := &pb.Goods{
|
|
Period: 0, // 变动周期
|
|
CurPeriod: 1, // 当前变动周期
|
|
Price: 0, // 当前价格
|
|
}
|
|
if len(v.Changeperiod) == 2 {
|
|
goods.Period = comm.GetRandNum(v.Changeperiod[0], v.Changeperiod[1])
|
|
goods.Price = v.Goodsprice
|
|
data.Goods[v.Itemid] = goods
|
|
}
|
|
data.Oldprice[v.Itemid] = v.Goodsprice
|
|
}
|
|
}
|
|
|
|
// 初始化门票和虚拟币
|
|
func (this *Caravan) InitCaravanTicket(session comm.IUserSession, lv int32) (errdata *pb.ErrorData) {
|
|
|
|
if conf, _ := this.modelCaravan.module.configure.GetCaravanLv(lv); conf != nil {
|
|
var res []*cfg.Gameatn
|
|
res = append(res, conf.Tickettop)
|
|
res = append(res, conf.Moneynumtop)
|
|
errdata = this.DispenseRes(session, res, true) // 推送门票和虚拟币资源
|
|
}
|
|
return
|
|
}
|
|
|
|
// 刷新城市货物信息
|
|
func (this *Caravan) refreshCaravanCityInfo(uid string, caravan *pb.DBCaravan) {
|
|
var (
|
|
bChange bool
|
|
update map[string]interface{}
|
|
changeTime int32
|
|
)
|
|
update = make(map[string]interface{})
|
|
changeTime = this.configure.GetCityRefreshTime() // 180
|
|
if int32(configure.Now().Unix()-caravan.Citystime) >= changeTime {
|
|
bChange = true
|
|
for k, v := range caravan.City {
|
|
if c, _ := this.configure.GetCaravanCity(k); c != nil {
|
|
v.Count = make(map[string]int32) // 初始化城市信息
|
|
v.Special = []string{}
|
|
if len(c.Special) > int(c.Citytypenum) {
|
|
ids := utils.RandomNumbers(0, len(c.Special), int(c.Citytypenum))
|
|
for _, id := range ids {
|
|
v.Special = append(v.Special, c.Special[id])
|
|
}
|
|
} else {
|
|
v.Special = append(v.Special, c.Special...)
|
|
}
|
|
}
|
|
}
|
|
subTime := configure.Now().Unix() - caravan.Citystime
|
|
icount := int32(subTime / int64(changeTime)) // 循环周期
|
|
caravan.Citystime += int64(changeTime * icount)
|
|
for k, v := range caravan.Goods {
|
|
if c, err := this.configure.GetCaravanGoods(k); err == nil {
|
|
caravan.Oldprice[k] = v.Price
|
|
if icount > 50 { //超过一定的周期 则不计算
|
|
// 随机出新的变动周期
|
|
v.Period = comm.GetRandNum(c.Changeperiod[0], c.Changeperiod[1])
|
|
v.CurPeriod = 0
|
|
} else {
|
|
for i := 0; i < int(icount); i++ { // 计算当前的价格
|
|
// 价格涨跌权重 PriceChangeWeight
|
|
bUp := false // true 涨
|
|
ipos := comm.GetRandW(c.PriceChangeWeight)
|
|
if ipos == 1 {
|
|
if comm.GetRandW(c.PriceChangeWeightOne) == 0 {
|
|
bUp = true
|
|
}
|
|
} else if ipos == 2 {
|
|
if comm.GetRandW(c.PriceChangeWeightTwo) == 0 {
|
|
bUp = true
|
|
}
|
|
} else if ipos == 3 {
|
|
if comm.GetRandW(c.PriceChangeWeightThree) == 0 {
|
|
bUp = true
|
|
}
|
|
}
|
|
|
|
if bUp { // 价格上涨
|
|
v.Price = int32(math.Floor(float64(v.Price) * (1.0 + float64(c.FluctuationRange)/1000.0)))
|
|
} else {
|
|
v.Price = int32(math.Floor(float64(v.Price) * (1.0 - float64(c.FluctuationRange)/1000.0)))
|
|
}
|
|
|
|
if v.Price < c.Pricemin { // 设置最小值
|
|
v.Price = c.Pricemin
|
|
}
|
|
|
|
if v.Price > c.Pricemax { // 设置最大值
|
|
v.Price = c.Pricemax
|
|
}
|
|
v.CurPeriod += 1 // 更新周期+1
|
|
if v.CurPeriod+icount > v.Period {
|
|
// 随机出新的变动周期
|
|
v.Period = comm.GetRandNum(c.Changeperiod[0], c.Changeperiod[1])
|
|
v.CurPeriod = 0
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
if configure.Now().Unix() >= caravan.Resettime {
|
|
sTime := int64(this.ModuleTools.GetGlobalConf().BusinessRewardday * 24 * 3600) // 单位s
|
|
openTime := this.service.GetOpentime().Unix() // 获取开服时间
|
|
subTime := configure.Now().Unix() - openTime
|
|
caravan.Resettime = configure.Now().Unix() - (subTime % sTime) + sTime
|
|
update["resettime"] = caravan.Resettime
|
|
bChange = true
|
|
}
|
|
if bChange {
|
|
update["city"] = caravan.City
|
|
update["goods"] = caravan.Goods
|
|
update["oldprice"] = caravan.Oldprice
|
|
update["citystime"] = caravan.Citystime
|
|
this.modelCaravan.modifyCaravanDataByObjId(uid, update)
|
|
}
|
|
}
|
|
|
|
// 校验随机事件是否超时
|
|
func (this *Caravan) CheckCaravanTask(session comm.IUserSession, data *pb.DBCaravan) (bTimeOut bool) {
|
|
|
|
if data.Eventid != 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.ModuleWorldtask)
|
|
if err != nil {
|
|
return
|
|
}
|
|
if wt, ok := module.(comm.IWorldtask); ok {
|
|
wt.UpdateTaskStatus(session.GetUserId(), data.Taskid) // 通知任务模块 任务超时
|
|
}
|
|
|
|
this.CleanCaravanTask(session.GetUserId(), data) //任务超时 清理任务数据
|
|
// 任务超时发送任务失败推送
|
|
resp := &pb.CaravanTaskCompletePush{}
|
|
resp.Data = data
|
|
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.UserAssets{
|
|
A: "attr",
|
|
T: "merchantmoney",
|
|
N: -list.Unreword[1], // 扣除虚拟币
|
|
})
|
|
}
|
|
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() {
|
|
if conf, err := this.configure.GetCaravanEventById(taskid); err == nil {
|
|
list, _ := this.modelCaravan.getCaravanList(session.GetUserId())
|
|
if list.Taskid == taskid {
|
|
this.CleanCaravanTask(session.GetUserId(), list) //任务完成 清理任务数据
|
|
resp = &pb.CaravanTaskCompletePush{}
|
|
resp.Data = list
|
|
resp.BSuccess = true
|
|
for _, v := range conf.Reword {
|
|
resp.Reward = append(resp.Reward, &pb.UserAssets{
|
|
A: v.A,
|
|
T: v.T,
|
|
N: v.N,
|
|
})
|
|
}
|
|
if errdata := this.ModuleBase.DispenseRes(session, conf.Reword, true); errdata != nil {
|
|
this.Errorf("Caravan DispenseRes err:%v", conf.Reword)
|
|
}
|
|
session.SendMsg(string(this.GetType()), "taskcomplete", resp)
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
// 整理背包 (true 表示背包装不下)
|
|
func (this *Caravan) ArrayBag(data *pb.DBCaravan, limit int32) (bFull bool) {
|
|
var count int32
|
|
for k, v := range data.Items {
|
|
if v.Count == 0 {
|
|
delete(data.Items, k)
|
|
} else {
|
|
tmp := v.Count
|
|
for {
|
|
count++
|
|
if tmp > limit {
|
|
tmp -= limit
|
|
} else {
|
|
break
|
|
}
|
|
}
|
|
}
|
|
}
|
|
if count > data.Baglimit {
|
|
return true
|
|
}
|
|
data.UseCount = count
|
|
return false
|
|
}
|
|
|
|
// 获得利润判断是否能提升商队等级
|
|
func (this *Caravan) CheckCaravavLvUp(data *pb.DBCaravan) (curLv int32) {
|
|
curLv = data.Lv
|
|
for {
|
|
if conf, err := this.configure.GetCaravanLv(curLv + 1); err == nil {
|
|
if conf.Newmoneyexp <= int32(data.Profit) {
|
|
curLv++
|
|
} else {
|
|
break
|
|
}
|
|
} else {
|
|
break
|
|
}
|
|
}
|
|
return curLv
|
|
}
|
|
|
|
func (this *Caravan) TestFunc(session comm.IUserSession) {
|
|
this.modelCaravan.module.api.GetList(session, &pb.CaravanGetListReq{})
|
|
this.modelCaravan.module.api.BuyOrSell(session, &pb.CaravanBuyOrSellReq{
|
|
City: 105,
|
|
Items: map[string]int32{
|
|
//6: 80,
|
|
},
|
|
IsBuy: true,
|
|
})
|
|
}
|
|
|
|
// 赛季结算
|
|
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() {
|
|
sTime := time.Now()
|
|
var rankIndex int32
|
|
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.DBUser{}
|
|
if err = _data.Decode(temp); err == nil {
|
|
c, err := this.configure.GetCaravanRank(rankIndex)
|
|
if err == nil {
|
|
this.mail.SendMailByUID(temp.Uid, "CaravanRank", c.Reward, []string{strconv.Itoa(int(rankIndex))})
|
|
}
|
|
}
|
|
}
|
|
}
|
|
// 发送虚拟币奖励
|
|
if _data, err := this.modelCaravan.DB.Find(comm.TableUser, bson.M{"merchantmoney": bson.M{"$gt": comm.CaravanMerchantmoney}}); err == nil {
|
|
for _data.Next(context.TODO()) {
|
|
temp := &pb.DBUser{}
|
|
|
|
if err = _data.Decode(temp); err == nil {
|
|
|
|
for _, v := range this.configure.GetCaravanReward() {
|
|
s := v.Moneystart
|
|
e := v.Moneyend
|
|
more := false
|
|
if e == -1 {
|
|
e = math.MaxInt32
|
|
more = true
|
|
}
|
|
|
|
if s < temp.Merchantmoney && e <= temp.Merchantmoney {
|
|
var res []*cfg.Gameatn
|
|
if more { // 超过的部分
|
|
r := this.ModuleTools.GetGlobalConf().BusinessMaxintReward
|
|
m := this.ModuleTools.GetGlobalConf().BusinessMaxint
|
|
n := (temp.Merchantmoney - s) / m
|
|
atn := &cfg.Gameatn{
|
|
A: r.A,
|
|
T: r.T,
|
|
N: r.N * n,
|
|
}
|
|
res = append(res, atn)
|
|
}
|
|
res = append(res, v.Reward...)
|
|
this.mail.SendMailByUID(temp.Uid, "CaravanRewards", v.Reward, []string{})
|
|
}
|
|
|
|
}
|
|
}
|
|
}
|
|
}
|
|
Query := bson.M{}
|
|
Query["merchantmoney"] = 0
|
|
_, err := this.modelCaravan.DB.UpdateMany(core.SqlTable(comm.TableUser), bson.M{"merchantmoney": bson.M{"$gt": 0}}, bson.M{"$set": Query}, options.MergeUpdateOptions().SetUpsert(true)) //, new(options.UpdateOptions).SetUpsert(true)
|
|
if err != nil {
|
|
this.Errorf("UpdateMany error: %v", err)
|
|
}
|
|
|
|
this.Debugf("sub time:%d", time.Now().Local().Sub(sTime).Milliseconds())
|
|
}()
|
|
|
|
return
|
|
}
|