You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
616 lines
17 KiB
616 lines
17 KiB
package common |
|
|
|
import ( |
|
"fmt" |
|
"math/rand" |
|
"reflect" |
|
"server/call" |
|
"server/common" |
|
"server/config" |
|
"server/db" |
|
"server/util" |
|
"time" |
|
|
|
"github.com/liangdas/mqant/log" |
|
"gorm.io/gorm" |
|
) |
|
|
|
// 老的分享结算方案暂不使用 |
|
func initTimer() { |
|
// 结算分享 |
|
// ShareSettle() |
|
// 结算重置每日数据 |
|
// ShareReset() |
|
// 分享机器人 |
|
ShareRobotTimer() |
|
// slots奖池活动机器人 |
|
ActivitySlotsRobotTimer() |
|
// slots奖池活动结算 |
|
ActivitySlotsSettleTimer() |
|
} |
|
|
|
var ( |
|
ShareSettleTime = 3 * time.Minute |
|
Day5Minute int64 = 288 // 一天有288个5分钟 |
|
) |
|
|
|
type updateShare struct { |
|
Level int |
|
MyBets int64 // 自己本次结算下注额 |
|
Bets int64 // 记录需要更新的总下注 |
|
Reals int // 记录需要更新的有效下线个数 |
|
Rewards int64 // 自己的佣金 |
|
UpRewards int64 // 对上级的贡献佣金 |
|
} |
|
|
|
func ShareRobotTimer() { |
|
robots := call.GetConfigShareRobot() |
|
// 每5分钟刷新一次数据 |
|
for _, v := range robots { |
|
if v.RobotID == 0 { |
|
continue |
|
} |
|
if db.Mysql().Exist(&common.PlayerDBInfo{Id: v.RobotID}) { |
|
log.Error("invalid robotid:%v", v.RobotID) |
|
continue |
|
} |
|
one := &common.ShareInfo{UID: v.RobotID} |
|
diff := v.DayCashUp - v.DayCashDown |
|
if diff <= 0 { |
|
continue |
|
} |
|
add := rand.Int63n(diff) + v.DayCashDown |
|
add /= Day5Minute |
|
db.Mysql().Get(one) |
|
if one.ID == 0 { |
|
one.Share = util.GetShareCode(one.UID) |
|
one.BetReward = v.InitCash + add |
|
db.Mysql().Create(one) |
|
} else { |
|
db.Mysql().Update(&common.ShareInfo{UID: v.RobotID}, map[string]interface{}{"bet_reward": gorm.Expr("bet_reward + ?", add)}) |
|
} |
|
} |
|
minute := time.Now().Minute() |
|
next := minute % 5 |
|
if next == 0 { |
|
next = 5 |
|
} |
|
log.Debug("next robot timer:%v", next) |
|
time.AfterFunc(time.Duration(5)*time.Minute, ShareRobotTimer) |
|
} |
|
|
|
/* |
|
每日使用10个AI在数字900-990之间随机分别选取一个数字(若选取数字大于910的AI玩家小于3,则重新选取直到选取数字大于910的玩家大于3) |
|
每日使用5个AI在数字850-900之间随机分别选取一个数字 |
|
每日中午12点至下午6点每隔一小时随机上场一个ai,6点后每隔15~25分钟上场一个 |
|
*/ |
|
func ActivitySlotsRobotTimer() { |
|
now := time.Now() |
|
hour := now.Hour() |
|
var next int64 |
|
defer func() { |
|
log.Debug("next ActivitySlotsRobotTimer:%v", next) |
|
time.AfterFunc(time.Duration(next)*time.Second, ActivitySlotsRobotTimer) |
|
}() |
|
if !config.GetBase().Release { |
|
next = 5 * 60 |
|
ActivitySlotsRobotJoin() |
|
return |
|
} |
|
if hour < 12 { |
|
next = util.GetZeroTime(now).Unix() + 12*60*60 + 1 - now.Unix() |
|
return |
|
} else if hour < 18 { |
|
// 一小时内随机生成一个机器人 |
|
diff := util.GetZeroTime(now).Unix() + int64(hour+1)*60*60 - time.Now().Unix() |
|
next = diff |
|
ran := rand.Intn(int(diff)) + 1 |
|
log.Debug("next ActivitySlotsRobotJoin:%v", ran) |
|
time.AfterFunc(time.Duration(ran)*time.Second, func() { |
|
ActivitySlotsRobotJoin() |
|
}) |
|
return |
|
} else if hour < 23 { |
|
ran := rand.Int63n(10) + 15 |
|
next = ran * 60 |
|
log.Debug("next ActivitySlotsRobotJoin:%v", ran) |
|
ActivitySlotsRobotJoin() |
|
} else { |
|
next = util.GetZeroTime(now.AddDate(0, 0, 1)).Unix() + 12*60*60 + 1 - now.Unix() |
|
} |
|
} |
|
|
|
const ( |
|
Max910Robot = 3 // 数字大于910的机器人 |
|
Max900Robot = 7 // 900-990的机器人数 |
|
Max850Robot = 5 // 850-900的机器人数 |
|
MaxRobotCount = 15 |
|
) |
|
|
|
// 每日结算后初始10个随机低分机器人 |
|
func ActivitySlotsFirstRobotJoin() { |
|
list := []*common.ActivitySlotsData{} |
|
_, err := db.Mysql().QueryAll("role = 2", "uid asc", &common.ActivitySlotsData{}, &list) |
|
if err != nil { |
|
log.Error("err:%v", err) |
|
return |
|
} |
|
log.Debug("ActivitySlotsFirstRobotJoin,list:%v", len(list)) |
|
isSingle := call.IsActivitySingleDay(common.ActivityIDSlots) |
|
for i := 0; i < 10; i++ { |
|
phone := util.CheckPhone("") |
|
avatar := call.RandomUserAvatar() |
|
robotUID := 100 + i |
|
number := rand.Intn(400) + 1 |
|
if i < len(list) { |
|
u := map[string]interface{}{"best_number2": number, "time2": time.Now().Unix(), "nick": phone, "avatar": avatar} |
|
if isSingle { |
|
u = map[string]interface{}{"best_number1": number, "time1": time.Now().Unix(), "nick": phone, "avatar": avatar} |
|
} |
|
db.Mysql().Update(&common.ActivitySlotsData{ID: list[i].ID}, u) |
|
continue |
|
} |
|
data := &common.ActivitySlotsData{UID: robotUID, Role: 2, Nick: phone, Avatar: avatar} |
|
if isSingle { |
|
data.BestNumber1 = number |
|
data.Time1 = time.Now().Unix() |
|
} else { |
|
data.BestNumber2 = number |
|
data.Time2 = time.Now().Unix() |
|
} |
|
db.Mysql().Create(data) |
|
} |
|
} |
|
|
|
// 生成一个机器人 |
|
func ActivitySlotsRobotJoin() { |
|
isSingle := call.IsActivitySingleDay(common.ActivityIDSlots) |
|
zero := util.GetZeroTime(time.Now()).Unix() |
|
list := []*common.ActivitySlotsData{} |
|
_, err := db.Mysql().QueryAll("role = 1", "uid asc", &common.ActivitySlotsData{}, &list) |
|
if err != nil { |
|
return |
|
} |
|
var count850, count900, count910 int |
|
var canUpdate *common.ActivitySlotsData |
|
for i, v := range list { |
|
ref := reflect.ValueOf(v).Elem() |
|
index := 2 |
|
if isSingle { |
|
index = 1 |
|
} |
|
t := ref.FieldByName(fmt.Sprintf("Time%d", index)).Int() |
|
if t < zero { |
|
if canUpdate == nil { |
|
canUpdate = list[i] |
|
} |
|
continue |
|
} |
|
number := ref.FieldByName(fmt.Sprintf("BestNumber%d", index)).Int() |
|
if number < 900 { |
|
count850++ |
|
} else if number <= 910 { |
|
count900++ |
|
} else { |
|
count910++ |
|
} |
|
} |
|
total := count850 + count900 + count910 |
|
if total >= MaxRobotCount { |
|
return |
|
} |
|
all := make([]int, 3) |
|
all[0] = Max850Robot - count850 |
|
all[1] = Max900Robot - count900 |
|
all[2] = Max910Robot - count910 |
|
ran := rand.Intn(all[0] + all[1] + all[2]) |
|
this := 0 |
|
index := 0 |
|
for i := 0; i < 3; i++ { |
|
this += all[i] |
|
if ran < this { |
|
index = i |
|
break |
|
} |
|
} |
|
number := 0 |
|
switch index { |
|
case 0: |
|
number = rand.Intn(50) + 850 |
|
case 1: |
|
number = rand.Intn(11) + 900 |
|
case 2: |
|
number = rand.Intn(89) + 911 |
|
} |
|
if number == 0 { |
|
return |
|
} |
|
phone := util.CheckPhone("") |
|
avatar := call.RandomUserAvatar() |
|
if canUpdate != nil { |
|
u := map[string]interface{}{"best_number2": number, "time2": time.Now().Unix(), "nick": phone, "avatar": avatar} |
|
if isSingle { |
|
u = map[string]interface{}{"best_number1": number, "time1": time.Now().Unix(), "nick": phone, "avatar": avatar} |
|
} |
|
db.Mysql().Update(&common.ActivitySlotsData{ID: canUpdate.ID}, u) |
|
} else { |
|
robotUID := 2 |
|
if len(list) > 0 { |
|
robotUID = list[len(list)-1].UID + 1 |
|
} |
|
data := &common.ActivitySlotsData{UID: robotUID, Role: 1, Nick: phone, Avatar: avatar} |
|
if isSingle { |
|
data.BestNumber1 = number |
|
data.Time1 = time.Now().Unix() |
|
} else { |
|
data.BestNumber2 = number |
|
data.Time2 = time.Now().Unix() |
|
} |
|
db.Mysql().Create(data) |
|
} |
|
} |
|
|
|
func ActivitySlotsSettleTimer() { |
|
now := time.Now() |
|
next := util.GetZeroTime(now.AddDate(0, 0, 1)).Unix() + 5 - now.Unix() // 零点过5秒结算 |
|
if !config.GetBase().Release { |
|
next = util.GetNext5MinUnix() - now.Unix() |
|
} |
|
defer func() { |
|
log.Debug("next ActivitySlotsSettleTimer:%v", next) |
|
time.AfterFunc(time.Duration(next)*time.Second, ActivitySlotsSettleTimer) |
|
}() |
|
// if !call.IsActivityValid(common.ActivityIDSlots) { |
|
// return |
|
// } |
|
date := now.AddDate(0, 0, -1).Format("20060102") |
|
record := &common.ActivitySlotsRecord{ |
|
UID: -1, // 代表系统结算标志 |
|
Date: date, |
|
} |
|
db.Mysql().Get(record) |
|
if record.Settle == 1 { |
|
return |
|
} |
|
con := call.GetConfigActivitySlots() |
|
if len(con) == 0 { |
|
return |
|
} |
|
|
|
list := []*common.ActivitySlotsData{} |
|
order := "best_number1 desc,time1 asc" |
|
str := "time1" |
|
isSingle := call.IsActivitySingleDay(common.ActivityIDSlots) |
|
|
|
if !config.GetBase().Release { |
|
if !isSingle { // 测试服结算当天的 |
|
order = "best_number2 desc,time2 asc" |
|
str = "time2" |
|
} |
|
} else { |
|
if isSingle { // 由于是结算前一天,所以查询逻辑是相反的 |
|
order = "best_number2 desc,time2 asc" |
|
str = "time2" |
|
} |
|
} |
|
db.Mysql().QueryList(0, con[len(con)-1].RankUp, fmt.Sprintf("%s >= %d", str, util.GetZeroTime(time.Now().AddDate(0, 0, -1)).Unix()), |
|
order, &common.ActivitySlotsData{}, &list) |
|
|
|
for i, v := range list { |
|
if i == 0 { |
|
if config.GetBase().Release { |
|
if isSingle { |
|
record.BestNumber = v.BestNumber2 |
|
} else { |
|
record.BestNumber = v.BestNumber1 |
|
} |
|
} else { |
|
if isSingle { |
|
record.BestNumber = v.BestNumber1 |
|
} else { |
|
record.BestNumber = v.BestNumber2 |
|
} |
|
} |
|
} |
|
if v.Role > 0 { |
|
continue |
|
} |
|
reward := call.GetConfigActivitySlotsRewardByRank(i + 1) |
|
if reward == 0 { |
|
continue |
|
} |
|
// call.UpdateCurrencyPro(&common.UpdateCurrency{ |
|
// CurrencyBalance: &common.CurrencyBalance{ |
|
// UID: v.UID, |
|
// Time: now.Unix(), |
|
// Value: reward, |
|
// Type: common.CurrencyBrazil, |
|
// Event: common.CurrencyEventActivitySlots, |
|
// NeedBet: call.GetConfigCurrencyResourceNeedBet(common.CurrencyResourceBonus, reward), |
|
// }, |
|
// }) |
|
one := &common.ActivitySlotsRecord{Date: date, UID: v.UID, Reward: reward, BestNumber: record.BestNumber, Settle: 0, Rank: i + 1} |
|
if config.GetBase().Release { |
|
if isSingle { |
|
one.MyNumber = v.BestNumber2 |
|
} else { |
|
one.MyNumber = v.BestNumber1 |
|
} |
|
} else { |
|
if isSingle { |
|
one.MyNumber = v.BestNumber1 |
|
} else { |
|
one.MyNumber = v.BestNumber2 |
|
} |
|
} |
|
db.Mysql().Create(one) |
|
} |
|
record.Settle = 1 |
|
db.Mysql().Create(record) |
|
|
|
ActivitySlotsFirstRobotJoin() |
|
} |
|
|
|
// func ShareSettle() { |
|
// if !config.GetBase().Release { |
|
// ShareSettleTime = 30 * time.Second |
|
// } |
|
// log.Debug("next ShareSettle:%v", ShareSettleTime) |
|
// time.AfterFunc(ShareSettleTime, func() { |
|
// defer ShareSettle() |
|
// all := map[int]*updateShare{} |
|
// ret := []*common.ShareInfo{} |
|
// db.Mysql().QueryAll("bet>0 and up>0", "", &common.ShareInfo{}, &ret) |
|
// log.Debug("settle:%v", ret) |
|
// if len(ret) == 0 { |
|
// return |
|
// } |
|
// for _, v := range ret { |
|
// bet := v.Bet |
|
// reals := 0 |
|
// if v.TotalBet == 0 { // 产生有效投注,需要更新上级有效下线个数 |
|
// reals = 1 |
|
// PddUpdate(v.UID, v.UP) // 产生有效投注,更新pdd数据 |
|
// } |
|
// // 循环查询结算上级 |
|
// this := v |
|
// lastLevel := 0 // 上一次结算时的上级等级,需要比较该值确定上级是否还能分得佣金 |
|
// for { |
|
// log.Debug("this:%+v", this) |
|
// if this.UP == 0 { |
|
// break |
|
// } |
|
// upInfo := &common.ShareInfo{UID: this.UP} |
|
// db.Mysql().Get(upInfo) |
|
// if upInfo.ID <= 0 { |
|
// break |
|
// } |
|
// u, ok := all[upInfo.UID] |
|
// if !ok { |
|
// u = &updateShare{ |
|
// Bets: bet, |
|
// Reals: reals, |
|
// } |
|
// all[upInfo.UID] = u |
|
// } else { |
|
// u.Bets += bet |
|
// u.Reals += reals |
|
// } |
|
// // 首先计算是否升级 |
|
// con := call.GetConfigShareLevelByBet(upInfo.TotalAgentsBet + u.Bets) |
|
// if con != nil { |
|
// // 升级了标记 |
|
// if con.Level > upInfo.Level { |
|
// u.Level = con.Level |
|
// } |
|
// // 计算等级差 |
|
// var per int64 |
|
// if con.Level > lastLevel { |
|
// if lastLevel == 0 { |
|
// per = con.Per |
|
// } else { |
|
// lastCon := call.GetConfigShareByLevel(lastLevel) |
|
// if lastCon != nil { |
|
// per = con.Per - lastCon.Per |
|
// } |
|
// } |
|
// lastLevel = con.Level |
|
// } |
|
// if per > 0 { |
|
// reward := per * bet / 10000 |
|
// if reward > 0 { |
|
// u.Rewards += reward |
|
// thisU, ok := all[this.UID] |
|
// if !ok { |
|
// all[this.UID] = &updateShare{ |
|
// UpRewards: reward, |
|
// } |
|
// } else { |
|
// thisU.UpRewards += reward |
|
// } |
|
// } |
|
// } |
|
// } |
|
// this = upInfo |
|
// } |
|
// // 结算完后,更新自己的下注 |
|
// my, ok := all[v.UID] |
|
// if !ok { |
|
// all[v.UID] = &updateShare{ |
|
// MyBets: bet, |
|
// } |
|
// } else { |
|
// my.MyBets = bet |
|
// } |
|
// } |
|
// // 计算完成后统一更新玩家数据 |
|
// log.Debug("start share update:%d", len(all)) |
|
// success := 0 |
|
// fail := 0 |
|
// for uid, v := range all { |
|
// update := map[string]interface{}{} |
|
// if v.MyBets > 0 { |
|
// update["bet"] = gorm.Expr("bet - ?", v.MyBets) |
|
// update["today_bet"] = gorm.Expr("today_bet + ?", v.MyBets) |
|
// update["total_bet"] = gorm.Expr("total_bet + ?", v.MyBets) |
|
// } |
|
// if v.Bets > 0 { |
|
// update["today_agents_bet"] = gorm.Expr("today_agents_bet + ?", v.Bets) |
|
// update["total_agents_bet"] = gorm.Expr("total_agents_bet + ?", v.Bets) |
|
// } |
|
// if v.Reals > 0 { |
|
// update["today_real_agents"] = gorm.Expr("today_real_agents + ?", v.Reals) |
|
// update["total_real_agents"] = gorm.Expr("total_real_agents + ?", v.Reals) |
|
// } |
|
// if v.Rewards > 0 { |
|
// update["today_reward"] = gorm.Expr("today_reward + ?", v.Rewards) |
|
// update["total_reward"] = gorm.Expr("total_reward + ?", v.Rewards) |
|
// update["available_reward"] = gorm.Expr("available_reward + ?", v.Rewards) |
|
// } |
|
// if v.UpRewards > 0 { |
|
// update["today_up_reward"] = gorm.Expr("today_up_reward + ?", v.UpRewards) |
|
// } |
|
// err := db.Mysql().Update(&common.ShareInfo{UID: uid}, update) |
|
// if err != nil { |
|
// fail++ |
|
// } else { |
|
// success++ |
|
// } |
|
// } |
|
// log.Debug("finish share update:%d,success:%d,fail:%d", len(all), success, fail) |
|
// }) |
|
// } |
|
|
|
var ( |
|
ShareQueryNum = 5000 |
|
) |
|
|
|
// func ShareReset() { |
|
// next := time.Until(util.GetZeroTime(time.Now().AddDate(0, 0, 1)).Add(5 * time.Second)) |
|
// log.Debug("next ShareReset:%v", next) |
|
// time.AfterFunc(next, func() { |
|
// defer ShareReset() |
|
// recordTime := time.Now().AddDate(0, 0, -1) |
|
// recordTimeUnix := recordTime.Unix() |
|
// recordTimeDate := recordTime.Format("20060102") |
|
// start := 0 |
|
// for { |
|
// ret := []common.ShareInfo{} |
|
// db.Mysql().QueryListW(start, ShareQueryNum, "", &common.ShareInfo{}, &ret, "today_agents_bet+today_agents>0") |
|
// for _, v := range ret { |
|
// uid := v.UID |
|
// db.ES().InsertToESGO(common.ESIndexShareProfitReport, &common.ESShareProfitReport{ |
|
// UID: uid, |
|
// Date: recordTimeDate, |
|
// Regist: v.TodayAgents, |
|
// Bet: v.TodayAgentsBet, |
|
// Level: v.Level, |
|
// Time: recordTimeUnix, |
|
// Reward: v.TodayReward, |
|
// }) |
|
// thisStart := 0 |
|
// for { |
|
// agents := []common.ShareInfo{} |
|
// db.Mysql().QueryListW(thisStart, ShareQueryNum, "", &common.ShareInfo{}, &agents, fmt.Sprintf("up = %d", uid)) |
|
// for _, v := range agents { |
|
// one := &common.ESShareProfitRecord{ |
|
// UID: v.UID, |
|
// Bet: v.TodayBet, |
|
// DownBet: v.TodayAgentsBet, |
|
// Up: uid, |
|
// Reward: v.TodayUpReward, |
|
// Date: recordTimeDate, |
|
// Time: recordTimeUnix, |
|
// } |
|
// db.ES().InsertToESGO(common.ESIndexShareProfitRecord, one) |
|
// } |
|
// if len(agents) < ShareQueryNum { |
|
// break |
|
// } |
|
// thisStart++ |
|
// } |
|
// } |
|
// if len(ret) < ShareQueryNum { |
|
// break |
|
// } |
|
// start++ |
|
// } |
|
// db.Mysql().UpdateW(&common.ShareInfo{}, map[string]interface{}{"today_agents_bet": 0, "today_agents": 0, "today_real_agents": 0, "today_reward": 0, "today_bet": 0}, |
|
// "today_agents_bet+today_agents>0") |
|
// }) |
|
// } |
|
|
|
// 更新玩家pdd邀请数据 |
|
func PddUpdate(uid, referer int) { |
|
if referer == 0 { |
|
return |
|
} |
|
con := call.GetConfigActivityPdd() |
|
if con == nil { |
|
return |
|
} |
|
now := time.Now().Unix() |
|
pddData := &common.PddData{UID: referer} |
|
db.Mysql().Get(pddData) |
|
if now-pddData.Time >= con.Expire*60 { |
|
return |
|
} |
|
db.Mysql().Update(&common.PddData{UID: referer, Time: pddData.Time}, map[string]interface{}{"spin": gorm.Expr("spin + 1")}) |
|
user, _ := call.GetUserXInfo(uid, "nick", "avatar") |
|
db.ES().InsertToESGO(common.ESIndexBackPddRecord, common.ESPddRecord{ |
|
UID: uid, |
|
Referer: referer, |
|
Time: now, |
|
Nick: user.Nick, |
|
Avatar: user.Avatar, |
|
}) |
|
} |
|
|
|
// initRecordCurrency 记录玩家身上货币,可退出货币 |
|
func initRecordCurrency() { |
|
next := time.Until(util.GetZeroTime(time.Now().AddDate(0, 0, 1)).Add(time.Second)) |
|
// next := time.Until(time.Now().Add(time.Minute)) |
|
time.AfterFunc(next, recordCurrency) |
|
log.Debug("next initRecordCurrency:%v", next) |
|
} |
|
|
|
func recordCurrency() { |
|
initRecordCurrency() |
|
// var total, totalCash int64 |
|
// channel := call.GetChannelListReal() |
|
// con := call.GetConfigWithdrawProduct(common.WithdrawSorceBank) |
|
// var least int64 // 最低退出所需金币 |
|
// for _, v := range con { |
|
// if least == 0 || v.PayGold < least { |
|
// least = v.PayGold |
|
// } |
|
// } |
|
// for _, v := range channel { |
|
// sql := fmt.Sprintf("channel_id = %v and role <> %v and status = %v", v.ChannelID, common.PlayerRoleRobot, common.AccountStatusNormal) |
|
// err := db.Mysql().C().Table("users").Where(sql).Select("sum(bind_cash+cash)").Scan(&total).Error |
|
// if err != nil { |
|
// log.Error("err:%v", err) |
|
// } |
|
// tsql := sql + fmt.Sprintf(" and cash > %v", least) |
|
// err = db.Mysql().C().Table("users").Where(tsql).Select("sum(cash)").Scan(&totalCash).Error |
|
// if err != nil { |
|
// log.Error("err:%v", err) |
|
// } |
|
// if total == 0 && totalCash == 0 { |
|
// continue |
|
// } |
|
// brl := db.Mysql().Sum(&common.PlayerCurrency{}, "", "brl") |
|
// usdt := db.Mysql().Sum(&common.PlayerCurrency{}, "", "usdt") |
|
|
|
// recordDate := time.Now().AddDate(0, 0, -1) |
|
// date := recordDate.Format("2006-01-02") |
|
|
|
// log.Debug("record date:%v,total:%v,totalCash:%v", date, total, totalCash) |
|
// db.ES().InsertToESGO(common.ESIndexBackDailyData, &common.ESDailySysData{ |
|
// Date: date, |
|
// Channel: v.ChannelID, |
|
// BRL: brl, |
|
// USDT: usdt, |
|
// }) |
|
// } |
|
}
|
|
|