增加fruit服务
This commit is contained in:
parent
19bb96b315
commit
181fd7716f
25
server/roserver/config/fruit_config.yaml
Normal file
25
server/roserver/config/fruit_config.yaml
Normal file
@ -0,0 +1,25 @@
|
||||
#服务器都对内监听处理(处理服务器之间的连接)
|
||||
#loglevel
|
||||
# Debug 1
|
||||
# Info 2
|
||||
# Warning 3
|
||||
# Error 4
|
||||
# Fatal 5
|
||||
# 服务器类型节点Type:[1 gate] [2 game] [3 db] [4 auth] [5 social chat mail] [10 map] [12 pve] [13 boss]
|
||||
server:
|
||||
- node:
|
||||
nodename: fruit
|
||||
addr: 0.0.0.0:51601
|
||||
type: 13
|
||||
id: 1
|
||||
zone: 1
|
||||
logfile: ../../logs
|
||||
loglevel: 1
|
||||
config: ./config
|
||||
etcdaddr: 127.0.0.1:2379
|
||||
concern: [game]
|
||||
#处理redis连接使用
|
||||
db:
|
||||
redisaddr: [127.0.0.1:6379]
|
||||
password: Luna2024!
|
||||
dbindex: 2
|
||||
72
server/roserver/fruit/main.go
Normal file
72
server/roserver/fruit/main.go
Normal file
@ -0,0 +1,72 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"io/ioutil"
|
||||
_ "net/http/pprof"
|
||||
"os"
|
||||
"rocommon"
|
||||
"rocommon/service"
|
||||
_ "rocommon/socket"
|
||||
_ "rocommon/socket/tcp"
|
||||
"roserver/baseserver"
|
||||
"roserver/baseserver/model"
|
||||
self "roserver/fruit/model"
|
||||
_ "roserver/fruit/msg"
|
||||
"runtime"
|
||||
"strconv"
|
||||
"syscall"
|
||||
)
|
||||
|
||||
// todo...
|
||||
// 单点有状态服务器
|
||||
func main() {
|
||||
//记录battleboss pid用来做关闭操作
|
||||
sysType := runtime.GOOS
|
||||
if sysType != "windows" {
|
||||
if pid := syscall.Getpid(); pid != 1 {
|
||||
fileName := "battleboss_server.pid" + strconv.Itoa(pid)
|
||||
ioutil.WriteFile(fileName, []byte(strconv.Itoa(pid)), 0777)
|
||||
defer os.Remove(fileName)
|
||||
}
|
||||
}
|
||||
|
||||
//go func(){
|
||||
// log.Println(http.ListenAndServe("localhost:8005", nil))
|
||||
//}()
|
||||
|
||||
//CPU
|
||||
//prof := profile.Start(profile.CPUProfile, profile.ProfilePath("./pprof/serverboss.pprof"), profile.NoShutdownHook)
|
||||
|
||||
baseserver.Init(model.SERVICE_NODE_TYPE_FRUIT_STR, self.ConfigInit, &self.FruitUpdate{})
|
||||
|
||||
//prof := profile.Start(profile.MemProfile, profile.ProfilePath("./pprof/serverbossmem.pprof"), profile.NoShutdownHook)
|
||||
|
||||
sConfig := service.GetServiceConfig()
|
||||
//先建立服务器对应的连接,在监听客户端
|
||||
//创建监听器
|
||||
var acceNode rocommon.ServerNode = nil
|
||||
if sConfig.Node.Addr != "" {
|
||||
acceNode = baseserver.CreateAcceptor(baseserver.ServiceParam{
|
||||
ServiceType: "tcpAcceptor",
|
||||
ServiceName: model.SERVICE_NODE_TYPE_FRUIT_STR,
|
||||
ProcName: "common.backend",
|
||||
LisAddr: sConfig.Node.Addr,
|
||||
}, sConfig)
|
||||
}
|
||||
|
||||
for _, concern := range sConfig.Node.Concern {
|
||||
//建立需要链接的服务器,可以通过服务器发现etcd来处理(包含在了CreateConnector中)
|
||||
baseserver.CreateConnector(baseserver.ServiceParam{
|
||||
DiscoveryServiceName: concern,
|
||||
DiscoveryServiceZone: sConfig.Node.Zone,
|
||||
ServiceType: "tcpConnector",
|
||||
ServiceName: model.SERVICE_NODE_TYPE_FRUIT_STR,
|
||||
ProcName: "common.backend",
|
||||
})
|
||||
}
|
||||
|
||||
baseserver.Wait()
|
||||
//CPU
|
||||
//prof.Stop()
|
||||
baseserver.Exit(acceNode)
|
||||
}
|
||||
20
server/roserver/fruit/model/fruit_config.go
Normal file
20
server/roserver/fruit/model/fruit_config.go
Normal file
@ -0,0 +1,20 @@
|
||||
package model
|
||||
|
||||
import (
|
||||
"rocommon/service"
|
||||
"rocommon/util"
|
||||
"roserver/baseserver/model"
|
||||
"runtime/debug"
|
||||
)
|
||||
|
||||
func ConfigInit() {
|
||||
defer func() {
|
||||
if err := recover(); err != nil {
|
||||
util.InfoF("Stack---::%v\n%s\n", err, string(debug.Stack()))
|
||||
panic(nil)
|
||||
}
|
||||
}()
|
||||
|
||||
sConfig := service.GetServiceConfig()
|
||||
model.BaseConfigInit(sConfig)
|
||||
}
|
||||
757
server/roserver/fruit/model/fruit_manager.go
Normal file
757
server/roserver/fruit/model/fruit_manager.go
Normal file
@ -0,0 +1,757 @@
|
||||
package model
|
||||
|
||||
import (
|
||||
"rocommon/service"
|
||||
"rocommon/util"
|
||||
"roserver/baseserver/model"
|
||||
"roserver/baseserver/set"
|
||||
"roserver/serverproto"
|
||||
"time"
|
||||
)
|
||||
|
||||
const MAX_AOI_LINE_BOSS_NUM = 100
|
||||
const MAX_BOSS_CHALLENGE_PLAYER_NUM = 8
|
||||
const BOSS_REWARD_MAIL_CONFIG_ID_Other = 2
|
||||
|
||||
const (
|
||||
BOSS_RESULT_WIN = 1
|
||||
BOSS_RESULT_TIME_OUT = 2
|
||||
|
||||
INIT_STATE_NONE = 0
|
||||
INIT_STATE_INIT = 1 //获取数据
|
||||
INIT_STATE_FINISH = 2 //初始化完成
|
||||
)
|
||||
const NO_AOILINE_BOSS = "NOAOI"
|
||||
const MAX_NO_AOILINE_BOSS_NUM = 20
|
||||
|
||||
type RefreshBossInfo struct {
|
||||
posId int32
|
||||
summonTimeIdx int
|
||||
bossData *model.ConvertWorldBossData
|
||||
|
||||
refreshTime time.Time //刷新boss的时间错,逻辑中使用
|
||||
|
||||
stop bool
|
||||
}
|
||||
|
||||
func (this *RefreshBossInfo) printDebugString(addStr string) {
|
||||
util.DebugF("msg=%v pos=%v bossid=%v summonidx=%v refreshtime=%v", addStr, this.posId,
|
||||
this.bossData.Id, this.summonTimeIdx, this.refreshTime.String())
|
||||
}
|
||||
|
||||
////////////////////////////////AoiLineBossManager
|
||||
type WorldBossManager struct {
|
||||
mapRouterNode string
|
||||
socialNode string
|
||||
updateTimer util.ServerTimer //定时器
|
||||
|
||||
bossList map[uint64]*PlayerBoss //[bossId *PlayerBoss]
|
||||
|
||||
//挑战玩家所在boss场景
|
||||
challengePlayerList map[uint64]*PlayerBoss
|
||||
|
||||
initStartUp int32 //维护时需要加载维护前的boss状态信息(血量,攻击记录)
|
||||
refreshBossInfoList map[int32]*RefreshBossInfo
|
||||
refreshBossInfoActivityList map[int32]*RefreshBossInfo
|
||||
|
||||
startUpDayTime time.Time //开服整数点时间
|
||||
startDiffDay int32 //当前距离开服时间的天数
|
||||
}
|
||||
|
||||
func newWorldBossManager() *WorldBossManager {
|
||||
mag := &WorldBossManager{
|
||||
bossList: map[uint64]*PlayerBoss{},
|
||||
challengePlayerList: map[uint64]*PlayerBoss{},
|
||||
mapRouterNode: "",
|
||||
socialNode: "",
|
||||
refreshBossInfoList: map[int32]*RefreshBossInfo{},
|
||||
refreshBossInfoActivityList: map[int32]*RefreshBossInfo{},
|
||||
}
|
||||
|
||||
mag.challengePlayerList = map[uint64]*PlayerBoss{}
|
||||
mag.updateTimer = util.NewDurationTimer(util.GetTimeMilliseconds(), 500)
|
||||
|
||||
mag.initRefresh()
|
||||
|
||||
return mag
|
||||
}
|
||||
|
||||
//获取最近一天的boss刷新时间
|
||||
func (this *WorldBossManager) getCurrentDayBossData(currentDay int32, pos int32) *model.ConvertWorldBossData {
|
||||
valList, ok := model.ConvertWorldBoss[pos]
|
||||
if !ok {
|
||||
return nil
|
||||
}
|
||||
|
||||
var retData *model.ConvertWorldBossData = nil
|
||||
for idx := 0; idx < len(valList); idx++ {
|
||||
if valList[idx].StartDay <= currentDay {
|
||||
retData = valList[idx]
|
||||
} else if valList[idx].StartDay > currentDay {
|
||||
break
|
||||
}
|
||||
}
|
||||
if retData == nil {
|
||||
if len(valList) > 0 {
|
||||
retData = valList[len(valList)-1]
|
||||
}
|
||||
}
|
||||
return retData
|
||||
}
|
||||
|
||||
func (this *WorldBossManager) initRefresh() bool {
|
||||
startUpTime := service.GetServiceStartupTime() //ms
|
||||
if startUpTime <= 0 {
|
||||
return false
|
||||
}
|
||||
|
||||
this.startUpDayTime = util.GetDayByTimeStr2(startUpTime)
|
||||
this.startDiffDay = util.GetDurationDay1(startUpTime, uint64(util.GetTimeMilliseconds())) + 1
|
||||
|
||||
//util.DebugF("nowhourtime=%v", nowHourTime.String())
|
||||
//普通世界boss
|
||||
for key := range model.ConvertWorldBoss {
|
||||
tmp := this.getRefreshInfo(key)
|
||||
tmp.printDebugString("initrefresh")
|
||||
}
|
||||
//活动世界boss(变身)
|
||||
for _, bossDataInfo := range model.ConvertWorldBossChangePlayList {
|
||||
this.getRefreshInfoChangePlay(bossDataInfo)
|
||||
}
|
||||
|
||||
this.initStartUp = INIT_STATE_FINISH
|
||||
|
||||
//开服时间
|
||||
return true
|
||||
}
|
||||
|
||||
func (this *WorldBossManager) getRefreshInfo(pos int32) *RefreshBossInfo {
|
||||
bFind := false
|
||||
k := 0
|
||||
tmpStartDiffDay := this.startDiffDay
|
||||
nowHourTime := util.GetHourByTime(0)
|
||||
//key == 0 表示最后一个位置
|
||||
bossDataInfo := this.getCurrentDayBossData(tmpStartDiffDay, pos)
|
||||
if bossDataInfo == nil {
|
||||
return nil
|
||||
}
|
||||
for k = 0; k < len(bossDataInfo.SummonTime); k++ {
|
||||
if bossDataInfo.SummonTime[k].After(nowHourTime) {
|
||||
bFind = true
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
if !bFind {
|
||||
k = 0
|
||||
tmpStartDiffDay++
|
||||
bossDataInfo = this.getCurrentDayBossData(tmpStartDiffDay, pos)
|
||||
if bossDataInfo != nil && len(bossDataInfo.SummonTime) > 0 {
|
||||
bFind = true
|
||||
}
|
||||
}
|
||||
|
||||
if bFind {
|
||||
tmpTime := this.startUpDayTime.AddDate(0, 0, int(tmpStartDiffDay-1))
|
||||
tmpSummonTime := bossDataInfo.SummonTime[k].Hour()*60*60 + bossDataInfo.SummonTime[k].Minute()*60 + bossDataInfo.SummonTime[k].Second()
|
||||
tmpTime = tmpTime.Add(time.Duration(tmpSummonTime) * time.Second)
|
||||
//util.DebugF("%v tmpTime:%v :%v", key, tmpTime.String(), tmpSummonTime)
|
||||
refreshInfo := &RefreshBossInfo{
|
||||
posId: bossDataInfo.RefreshId,
|
||||
bossData: bossDataInfo,
|
||||
refreshTime: tmpTime,
|
||||
}
|
||||
refreshInfo.summonTimeIdx = k + int(tmpStartDiffDay-1)*len(bossDataInfo.SummonTime)
|
||||
this.refreshBossInfoList[pos] = refreshInfo
|
||||
return refreshInfo
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (this *WorldBossManager) getRefreshInfoChangePlay(bossDataInfo *model.ConvertWorldBossData) *RefreshBossInfo {
|
||||
tmpStartDiffDay := this.startDiffDay
|
||||
nowHourTime := util.GetHourByTime(0)
|
||||
|
||||
//<=0表示根据给定的时间来开启[BossBeginTime,BossEndTime]
|
||||
if bossDataInfo.StartDay <= 0 {
|
||||
bFind := false
|
||||
k := 0
|
||||
for k = 0; k < len(bossDataInfo.SummonTime); k++ {
|
||||
if bossDataInfo.SummonTime[k].After(nowHourTime) {
|
||||
bFind = true
|
||||
break
|
||||
}
|
||||
}
|
||||
if !bFind {
|
||||
k = 0
|
||||
tmpStartDiffDay++
|
||||
bFind = true
|
||||
}
|
||||
|
||||
tmpTime := this.startUpDayTime.AddDate(0, 0, int(tmpStartDiffDay-1))
|
||||
tmpSummonTime := bossDataInfo.SummonTime[k].Hour()*60*60 + bossDataInfo.SummonTime[k].Minute()*60 + bossDataInfo.SummonTime[k].Second()
|
||||
tmpTime = tmpTime.Add(time.Duration(tmpSummonTime) * time.Second)
|
||||
|
||||
refreshInfo := &RefreshBossInfo{
|
||||
bossData: bossDataInfo,
|
||||
refreshTime: tmpTime,
|
||||
}
|
||||
refreshInfo.summonTimeIdx = k + int(tmpStartDiffDay-1)*len(bossDataInfo.SummonTime)
|
||||
this.refreshBossInfoActivityList[refreshInfo.bossData.Id] = refreshInfo
|
||||
|
||||
util.DebugF("getRefreshInfoChangePlay bossid=%v summonidx=%v refreshtime=%v",
|
||||
bossDataInfo.Id, refreshInfo.summonTimeIdx, tmpTime.String())
|
||||
return refreshInfo
|
||||
} else {
|
||||
//todo...
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (this *WorldBossManager) refreshBoss() {
|
||||
if len(this.refreshBossInfoList) <= 0 {
|
||||
return
|
||||
}
|
||||
|
||||
nowTime := util.GetCurrentTimeNow()
|
||||
for _, info := range this.refreshBossInfoList {
|
||||
//util.InfoF("now=%v summon=%v", nowHourTime.String(), info.bossData.SummonTime[info.summonTimeIdx].String())
|
||||
if nowTime.After(info.refreshTime) {
|
||||
//refresh key-pos boss
|
||||
//1,remove old-pos boss
|
||||
//2,add new-pos boss
|
||||
bRefresh := true
|
||||
for _, bossVal := range this.bossList {
|
||||
if bossVal.summonBossType != model.SummonBossType_Normal {
|
||||
continue
|
||||
}
|
||||
if int32(bossVal.bossUid)%4 == info.posId {
|
||||
//正在挑战中的boss不进行刷新处理
|
||||
if bossVal.GetState() == BOSS_STATE_FIGHTING {
|
||||
bRefresh = false
|
||||
} else {
|
||||
DelWorldBossList(bossVal)
|
||||
delete(this.bossList, bossVal.bossUid)
|
||||
}
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
if bRefresh {
|
||||
this.AddBossFromRefresh(info.bossData, int32(info.summonTimeIdx))
|
||||
}
|
||||
|
||||
tmpIdx := info.summonTimeIdx % len(info.bossData.SummonTime)
|
||||
//if tmpIdx <= 0 && info.summonTimeIdx > 0 {
|
||||
// tmpIdx = len(info.bossData.SummonTime)
|
||||
//}
|
||||
startUpTime := service.GetServiceStartupTime()
|
||||
this.startDiffDay = util.GetDurationDay1(startUpTime, uint64(util.GetTimeMilliseconds())) + 1
|
||||
tmpAddDay := this.startDiffDay
|
||||
|
||||
if len(info.bossData.SummonTime) <= tmpIdx+1 {
|
||||
//boss存活时间可能到下一天
|
||||
//判断下一天是否有新的boss刷新
|
||||
if info.refreshTime.Day() == nowTime.Day() {
|
||||
//如果当前刷新时间已经用完,则直接找第二天的刷新时间(需要判断刷新时对应的天数和当前时间做比较)
|
||||
tmpAddDay++
|
||||
}
|
||||
nextBossInfo := this.getCurrentDayBossData(tmpAddDay, info.posId)
|
||||
info.bossData = nextBossInfo
|
||||
}
|
||||
|
||||
if nowTime.Day() != info.refreshTime.Day() { //应对测试期间之前改天数的方式
|
||||
tmpPosId := info.posId
|
||||
info = this.getRefreshInfo(tmpPosId)
|
||||
} else {
|
||||
info.summonTimeIdx++
|
||||
|
||||
k := info.summonTimeIdx % len(info.bossData.SummonTime)
|
||||
tmpTime := this.startUpDayTime.AddDate(0, 0, int(tmpAddDay-1))
|
||||
tmpSummonTime := info.bossData.SummonTime[k].Hour()*60*60 + info.bossData.SummonTime[k].Minute()*60 + info.bossData.SummonTime[k].Second()
|
||||
tmpTime = tmpTime.Add(time.Duration(tmpSummonTime) * time.Second)
|
||||
info.refreshTime = tmpTime
|
||||
}
|
||||
info.printDebugString("RefreshBoss")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func (this *WorldBossManager) refreshBossChangePlay(ms uint64) {
|
||||
if len(this.refreshBossInfoActivityList) <= 0 {
|
||||
return
|
||||
}
|
||||
nowTime := util.GetTimeByUint64(ms)
|
||||
for key, info := range this.refreshBossInfoActivityList {
|
||||
//活动过期
|
||||
if nowTime.After(info.bossData.BossEndTime) {
|
||||
bossVal, ok := this.bossList[uint64(info.bossData.Id)]
|
||||
if ok {
|
||||
bossVal.SwitchState(int32(BOSS_STATE_TIME_OUT), nil)
|
||||
delete(this.bossList, uint64(info.bossData.Id))
|
||||
}
|
||||
delete(this.refreshBossInfoActivityList, key)
|
||||
continue
|
||||
}
|
||||
|
||||
if nowTime.Before(info.refreshTime) || nowTime.Before(info.bossData.BossBeginTime) {
|
||||
continue
|
||||
}
|
||||
|
||||
bRefresh := true
|
||||
bossVal, ok := this.bossList[uint64(info.bossData.Id)]
|
||||
if ok {
|
||||
if bossVal.GetState() == BOSS_STATE_FIGHTING {
|
||||
bRefresh = false
|
||||
} else {
|
||||
DelWorldBossList(bossVal)
|
||||
delete(this.bossList, bossVal.bossUid)
|
||||
}
|
||||
}
|
||||
if bRefresh {
|
||||
this.AddBossFromRefresh(info.bossData, int32(info.summonTimeIdx))
|
||||
}
|
||||
|
||||
tmpIdx := info.summonTimeIdx % len(info.bossData.SummonTime)
|
||||
startUpTime := service.GetServiceStartupTime()
|
||||
this.startDiffDay = util.GetDurationDay1(startUpTime, uint64(util.GetTimeMilliseconds())) + 1
|
||||
tmpAddDay := this.startDiffDay
|
||||
if len(info.bossData.SummonTime) <= tmpIdx+1 {
|
||||
//boss存活时间可能到下一天
|
||||
//判断下一天是否有新的boss刷新
|
||||
if info.refreshTime.Day() == nowTime.Day() {
|
||||
//如果当前刷新时间已经用完,则直接找第二天的刷新时间(需要判断刷新时对应的天数和当前时间做比较)
|
||||
tmpAddDay++
|
||||
}
|
||||
info.summonTimeIdx = 0
|
||||
} else {
|
||||
info.summonTimeIdx++
|
||||
}
|
||||
|
||||
if nowTime.Day() != info.refreshTime.Day() { //应对测试期间之前改天数的方式
|
||||
info = this.getRefreshInfoChangePlay(info.bossData)
|
||||
} else {
|
||||
//info.summonTimeIdx++
|
||||
|
||||
k := info.summonTimeIdx % len(info.bossData.SummonTime)
|
||||
tmpTime := this.startUpDayTime.AddDate(0, 0, int(tmpAddDay-1))
|
||||
tmpSummonTime := info.bossData.SummonTime[k].Hour()*60*60 + info.bossData.SummonTime[k].Minute()*60 + info.bossData.SummonTime[k].Second()
|
||||
tmpTime = tmpTime.Add(time.Duration(tmpSummonTime) * time.Second)
|
||||
info.refreshTime = tmpTime
|
||||
}
|
||||
|
||||
if bRefresh {
|
||||
util.DebugF("nextWorldBossRefreshTime=%v", info.refreshTime.String())
|
||||
}
|
||||
|
||||
info.printDebugString("RefreshBoss")
|
||||
}
|
||||
}
|
||||
|
||||
func (this *WorldBossManager) PlayerOffline(uid uint64) {
|
||||
if playerBoss, ok := this.challengePlayerList[uid]; ok {
|
||||
playerBoss.leaveNotify(uid)
|
||||
}
|
||||
}
|
||||
|
||||
func (this *WorldBossManager) Update(ms uint64) {
|
||||
switch this.initStartUp {
|
||||
case INIT_STATE_NONE:
|
||||
if GetWorldBossList(this) {
|
||||
this.initStartUp = INIT_STATE_INIT
|
||||
util.InfoF("load from db worldboss len=%v", len(this.bossList))
|
||||
} else {
|
||||
this.initStartUp = INIT_STATE_NONE
|
||||
return
|
||||
}
|
||||
case INIT_STATE_INIT:
|
||||
if !this.initRefresh() {
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
if !this.updateTimer.IsStart() || !this.updateTimer.IsExpired(ms) ||
|
||||
this.initStartUp != INIT_STATE_FINISH {
|
||||
return
|
||||
}
|
||||
|
||||
for _, boss := range this.bossList {
|
||||
boss.broadcastBossHp()
|
||||
if boss.finish {
|
||||
//不从列表中删除,客户端实现需要
|
||||
//delete(this.bossList, boss.bossUid)
|
||||
continue
|
||||
}
|
||||
if !boss.checkTimeValid(ms) {
|
||||
boss.SwitchState(int32(BOSS_STATE_TIME_OUT), nil)
|
||||
}
|
||||
|
||||
//处理boss的定时掉血。
|
||||
if boss.GetState() != BOSS_STATE_TIME_OUT && boss.GetState() != BOSS_STATE_DIED {
|
||||
boss.updateBossHp(ms)
|
||||
}
|
||||
}
|
||||
|
||||
//判断是否需要重新刷新boss
|
||||
this.refreshBoss() //普通世界boss
|
||||
this.refreshBossChangePlay(ms) //活动世界boss
|
||||
}
|
||||
|
||||
//DB中加载获取boss状态信息
|
||||
func (this *WorldBossManager) AddBossFromDB(stateInfo *serverproto.WorldBossStateInfo) bool {
|
||||
var summonId int32 = 0
|
||||
if stateInfo.SummonBossType == model.SummonBossType_Normal {
|
||||
cfgData, ok := model.ConvertWorldBossList[stateInfo.BossId]
|
||||
if !ok {
|
||||
return false
|
||||
}
|
||||
summonId = cfgData.SummonId
|
||||
} else {
|
||||
cfgData, ok := model.ConvertWorldBossChangePlayList[stateInfo.BossId]
|
||||
if !ok {
|
||||
return false
|
||||
}
|
||||
summonId = cfgData.SummonId
|
||||
}
|
||||
|
||||
npcCfgData, ok1 := serverproto.NpcCfgLoader[summonId]
|
||||
if !ok1 {
|
||||
return false
|
||||
}
|
||||
|
||||
playerBoss := newPlayerBoss(this)
|
||||
playerBoss.bossUid = uint64(stateInfo.BossId)
|
||||
playerBoss.summonBossId = summonId
|
||||
playerBoss.summonBossType = stateInfo.SummonBossType
|
||||
playerBoss.summonTime = stateInfo.SummonTime
|
||||
playerBoss.durationTime = uint64(stateInfo.DurationTime) * 1000
|
||||
playerBoss.summonBossIdx = stateInfo.SummonIdx
|
||||
playerBoss.SetTotalHp(stateInfo.Hp)
|
||||
playerBoss.maxHp = int32(npcCfgData.Hp)
|
||||
playerBoss.lastHPReduceTime = 0
|
||||
if playerBoss.totalHp < playerBoss.maxHp {
|
||||
playerBoss.lastHPReduceTime = util.GetTimeMilliseconds()
|
||||
}
|
||||
//add challenge uid
|
||||
for idx := 0; idx < len(stateInfo.UidList); idx++ {
|
||||
playerBoss.allChallengeList.Add(stateInfo.UidList[idx])
|
||||
}
|
||||
|
||||
nowTime := util.GetTimeMilliseconds()
|
||||
endTime := stateInfo.SummonTime + uint64(stateInfo.DurationTime)*1000
|
||||
if endTime <= nowTime {
|
||||
playerBoss.SwitchState(int32(BOSS_STATE_TIME_OUT), true) //表示来自db
|
||||
} else {
|
||||
|
||||
if playerBoss.totalHp <= 0 {
|
||||
playerBoss.SwitchState(int32(BOSS_STATE_DIED), true) //表示来自db
|
||||
} else {
|
||||
playerBoss.SwitchState(int32(BOSS_STATE_FIGHTING), nil)
|
||||
}
|
||||
}
|
||||
|
||||
this.bossList[playerBoss.bossUid] = playerBoss
|
||||
|
||||
util.DebugF("msg=AddBossFromDB bossid=%v summonidx=%v", playerBoss.bossUid, playerBoss.summonBossIdx)
|
||||
return true
|
||||
}
|
||||
|
||||
const SystemMessageType_WorldBoss = 6 //召喚世界BOSS通知
|
||||
func (this *WorldBossManager) AddBossFromRefresh(bossData *model.ConvertWorldBossData, summonIdx int32) bool {
|
||||
var summonId int32 = 0
|
||||
if bossData.SummonType == model.SummonBossType_Normal {
|
||||
cfgData, ok := serverproto.WorldBossCfgLoader[bossData.Id]
|
||||
if !ok {
|
||||
util.InfoF("AddBossFromRefresh WorldBossCfgLoader not find boss=%v ", bossData.Id)
|
||||
return false
|
||||
}
|
||||
|
||||
summonId = cfgData.SummonId
|
||||
} else {
|
||||
cfgData, ok := serverproto.WorldBossChangePlayCfgLoader[bossData.Id]
|
||||
if !ok {
|
||||
util.InfoF("AddBossFromRefresh WorldBossChangePlayCfgLoader not find boss=%v ", bossData.Id)
|
||||
return false
|
||||
}
|
||||
|
||||
summonId = cfgData.SummonId
|
||||
}
|
||||
|
||||
npcCfgData, ok1 := serverproto.NpcCfgLoader[summonId]
|
||||
if !ok1 {
|
||||
util.InfoF("AddBossFromRefresh npc data not find summonid=%v ", summonId)
|
||||
return false
|
||||
}
|
||||
summonHp := int32(npcCfgData.Hp)
|
||||
|
||||
playerBoss := newPlayerBoss(this)
|
||||
playerBoss.bossUid = uint64(bossData.Id)
|
||||
playerBoss.summonBossId = summonId
|
||||
playerBoss.summonTime = util.GetTimeMilliseconds()
|
||||
playerBoss.durationTime = uint64(bossData.DurationTime) * 1000
|
||||
playerBoss.summonBossIdx = summonIdx
|
||||
playerBoss.SetTotalHp(summonHp)
|
||||
playerBoss.lastHPReduceTime = 0
|
||||
playerBoss.summonBossType = bossData.SummonType
|
||||
|
||||
playerBoss.SwitchState(int32(BOSS_STATE_FIGHTING), nil)
|
||||
|
||||
this.bossList[playerBoss.bossUid] = playerBoss
|
||||
|
||||
//add to db
|
||||
UpdateWorldBossList(playerBoss)
|
||||
|
||||
util.DebugF("msg=AddBossFromRefresh bossid=%v summonidx=%v", bossData.Id, summonIdx)
|
||||
|
||||
//发送给所有game服务器
|
||||
ssMsgNtf := &serverproto.SSSystemMessageNtf{}
|
||||
ssMsg := &serverproto.SystemMessage{
|
||||
Type: SystemMessageType_WorldBoss,
|
||||
ParamId: []int32{int32(playerBoss.bossUid), bossData.SummonType},
|
||||
SendTime: util.GetTimeMilliseconds(),
|
||||
}
|
||||
ssMsgNtf.SysMsg = append(ssMsgNtf.SysMsg, ssMsg)
|
||||
SendToAllGame(ssMsgNtf)
|
||||
|
||||
return true
|
||||
}
|
||||
|
||||
func (this *WorldBossManager) PlayerChallengeSummonBoss(uid, challengeBossUid uint64, clientId model.ClientID,
|
||||
fightInfo *serverproto.FightRoleInfo) serverproto.ErrorCode {
|
||||
//当前玩家是否正在挑战boss
|
||||
if bossInfo, ok := this.challengePlayerList[uid]; ok {
|
||||
if bossInfo.finish {
|
||||
delete(this.challengePlayerList, uid)
|
||||
} else {
|
||||
bossInfo.leaveNotify(uid)
|
||||
//util.InfoF("PlayerChallengeSummonBoss already in other boss=%v uid=%v", bossInfo, uid)
|
||||
//return serverproto.ErrorCode_ERROR_AOI_BOSS_CHALLENGING
|
||||
}
|
||||
}
|
||||
|
||||
//查找是否存在Boss
|
||||
bossInfo, ok := this.bossList[challengeBossUid]
|
||||
if !ok {
|
||||
return serverproto.ErrorCode_ERROR_AOI_BOSS_NOT_FOUND
|
||||
}
|
||||
|
||||
ret := bossInfo.canChallenge(uid)
|
||||
if ret != serverproto.ErrorCode_ERROR_OK {
|
||||
return ret
|
||||
}
|
||||
|
||||
//添加挑战玩家信息
|
||||
bossInfo.addChallengePlayer(uid, clientId, fightInfo)
|
||||
|
||||
return serverproto.ErrorCode_ERROR_OK
|
||||
}
|
||||
|
||||
func (this *WorldBossManager) DoSummonHp(uid, bossUid uint64, damageHp int32) {
|
||||
bossInfo, ok := this.challengePlayerList[uid]
|
||||
if !ok {
|
||||
util.InfoF("DoSummonHp boss not find uId=%v boss=%v damageHp=%v", uid, bossUid, damageHp)
|
||||
return
|
||||
}
|
||||
|
||||
if bossInfo.bossUid != bossUid {
|
||||
util.InfoF("DoSummonHp bossId invalid uid=%v boss=%v dobossid=%v", uid, bossInfo.bossUid, bossUid)
|
||||
return
|
||||
}
|
||||
|
||||
bossInfo.ProcessBattle(damageHp)
|
||||
}
|
||||
|
||||
func (this *WorldBossManager) GetWorldBossInfo(bossUid uint64) *serverproto.WorldBossContentInfo {
|
||||
bossInfo, ok1 := this.bossList[bossUid]
|
||||
if !ok1 {
|
||||
return nil
|
||||
}
|
||||
|
||||
info := &serverproto.WorldBossContentInfo{
|
||||
BossId: int32(bossInfo.bossUid),
|
||||
CfgId: bossInfo.summonBossId,
|
||||
FighterNum: int32(len(bossInfo.challengeList)),
|
||||
ExpireTime: bossInfo.summonTime + bossInfo.durationTime,
|
||||
TotalHp: bossInfo.maxHp,
|
||||
CurHp: bossInfo.totalHp,
|
||||
BossSummonType: bossInfo.summonBossType,
|
||||
}
|
||||
|
||||
return info
|
||||
}
|
||||
|
||||
func (this *WorldBossManager) getBossRefreshInfo(posIdx int32) *RefreshBossInfo {
|
||||
if data, ok := this.refreshBossInfoList[posIdx]; ok {
|
||||
return data
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (this *WorldBossManager) getBossRefreshInfoChangePlay(bossId int32) *RefreshBossInfo {
|
||||
if data, ok := this.refreshBossInfoActivityList[bossId]; ok {
|
||||
refreshTime := uint64(data.refreshTime.Unix()) * 1000
|
||||
if data.bossData.BossEndTimeStmp > refreshTime {
|
||||
return data
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (this *WorldBossManager) GetWorldBossList() *serverproto.SCPlayerWorldBossListAck {
|
||||
if len(this.bossList) <= 0 {
|
||||
var tmpAckMsg = &serverproto.SCPlayerWorldBossListAck{}
|
||||
//if len(tmpAckMsg.WorldBossList) > 0 {
|
||||
// return tmpAckMsg
|
||||
//}
|
||||
//普通世界boss
|
||||
for _, val := range this.refreshBossInfoList {
|
||||
npcCfgData, ok1 := serverproto.NpcCfgLoader[val.bossData.SummonId]
|
||||
if !ok1 {
|
||||
util.InfoF("NpcCfgLoader npc data not find summonid=%v ", val.bossData.SummonId)
|
||||
continue
|
||||
}
|
||||
|
||||
info := &serverproto.WorldBossContentInfo{
|
||||
BossId: int32(val.bossData.Id),
|
||||
CfgId: val.bossData.SummonId,
|
||||
FighterNum: 0,
|
||||
ExpireTime: 0,
|
||||
NextRefreshTime: uint64(val.refreshTime.Unix()) * 1000,
|
||||
TotalHp: int32(npcCfgData.Hp),
|
||||
CurHp: int32(npcCfgData.Hp),
|
||||
}
|
||||
tmpAckMsg.WorldBossList = append(tmpAckMsg.WorldBossList, info)
|
||||
}
|
||||
//变身类活动世界boss
|
||||
nowTime := util.GetCurrentTimeNow()
|
||||
for _, val := range this.refreshBossInfoActivityList {
|
||||
npcCfgData, ok1 := serverproto.NpcCfgLoader[val.bossData.SummonId]
|
||||
if !ok1 {
|
||||
util.InfoF("NpcCfgLoader npc data not find summonid=%v ", val.bossData.SummonId)
|
||||
continue
|
||||
}
|
||||
if nowTime.Before(val.bossData.BossBeginTime) || nowTime.After(val.bossData.BossEndTime) {
|
||||
continue
|
||||
}
|
||||
|
||||
info := &serverproto.WorldBossContentInfo{
|
||||
BossId: int32(val.bossData.Id),
|
||||
CfgId: val.bossData.SummonId,
|
||||
FighterNum: 0,
|
||||
ExpireTime: 0,
|
||||
NextRefreshTime: uint64(val.refreshTime.Unix()) * 1000,
|
||||
TotalHp: int32(npcCfgData.Hp),
|
||||
CurHp: int32(npcCfgData.Hp),
|
||||
BossSummonType: val.bossData.SummonType,
|
||||
}
|
||||
tmpAckMsg.WorldBossList = append(tmpAckMsg.WorldBossList, info)
|
||||
}
|
||||
return tmpAckMsg
|
||||
} else {
|
||||
ackMsg := &serverproto.SCPlayerWorldBossListAck{}
|
||||
nowTime := util.GetTimeMilliseconds()
|
||||
hasBossList := set.New(set.NonThreadSafe)
|
||||
hasChangePlayBossList := set.New(set.NonThreadSafe)
|
||||
for _, bossInfo := range this.bossList {
|
||||
if bossInfo.summonBossType <= 0 {
|
||||
hasBossList.Add(int32(bossInfo.bossUid) % 4)
|
||||
} else {
|
||||
hasChangePlayBossList.Add(int32(bossInfo.bossUid))
|
||||
}
|
||||
info := &serverproto.WorldBossContentInfo{
|
||||
BossId: int32(bossInfo.bossUid),
|
||||
BossSummonIdx: bossInfo.summonBossIdx,
|
||||
CfgId: bossInfo.summonBossId,
|
||||
FighterNum: int32(len(bossInfo.challengeList)),
|
||||
//ExpireTime: bossInfo.summonTime + bossInfo.durationTime,
|
||||
TotalHp: bossInfo.maxHp,
|
||||
CurHp: bossInfo.totalHp,
|
||||
BossSummonType: bossInfo.summonBossType,
|
||||
}
|
||||
|
||||
expireTime := bossInfo.summonTime + bossInfo.durationTime
|
||||
if bossInfo.summonBossType == model.SummonBossType_ChangePlay {
|
||||
changBossDataInfo, ok := model.ConvertWorldBossChangePlayList[int32(bossInfo.bossUid)]
|
||||
if ok {
|
||||
if expireTime > changBossDataInfo.BossEndTimeStmp {
|
||||
expireTime = changBossDataInfo.BossEndTimeStmp
|
||||
}
|
||||
}
|
||||
}
|
||||
info.ExpireTime = expireTime
|
||||
|
||||
if nowTime > expireTime || bossInfo.totalHp <= 0 {
|
||||
info.FighterNum = 0
|
||||
info.ExpireTime = 0
|
||||
|
||||
switch bossInfo.summonBossType {
|
||||
case model.SummonBossType_Normal:
|
||||
bossRefreshInfo := this.getBossRefreshInfo(info.BossId % 4)
|
||||
if bossRefreshInfo != nil {
|
||||
info.NextRefreshTime = uint64(bossRefreshInfo.refreshTime.Unix()) * 1000
|
||||
}
|
||||
case model.SummonBossType_ChangePlay:
|
||||
bossRefreshInfo := this.getBossRefreshInfoChangePlay(info.BossId)
|
||||
if bossRefreshInfo != nil {
|
||||
info.NextRefreshTime = uint64(bossRefreshInfo.refreshTime.Unix()) * 1000
|
||||
} else {
|
||||
continue
|
||||
}
|
||||
}
|
||||
}
|
||||
ackMsg.WorldBossList = append(ackMsg.WorldBossList, info)
|
||||
}
|
||||
|
||||
for _, val := range this.refreshBossInfoList {
|
||||
if hasBossList.Has(val.posId) {
|
||||
continue
|
||||
}
|
||||
npcCfgData, ok1 := serverproto.NpcCfgLoader[val.bossData.SummonId]
|
||||
if !ok1 {
|
||||
util.InfoF("NpcCfgLoader npc data not find summonid=%v ", val.bossData.SummonId)
|
||||
continue
|
||||
}
|
||||
|
||||
info := &serverproto.WorldBossContentInfo{
|
||||
BossId: int32(val.bossData.Id),
|
||||
CfgId: val.bossData.SummonId,
|
||||
FighterNum: 0,
|
||||
ExpireTime: 0,
|
||||
NextRefreshTime: uint64(val.refreshTime.Unix()) * 1000,
|
||||
TotalHp: int32(npcCfgData.Hp),
|
||||
CurHp: int32(npcCfgData.Hp),
|
||||
}
|
||||
ackMsg.WorldBossList = append(ackMsg.WorldBossList, info)
|
||||
}
|
||||
|
||||
nowTime1 := util.GetCurrentTimeNow()
|
||||
for _, val := range this.refreshBossInfoActivityList {
|
||||
if hasChangePlayBossList.Has(val.bossData.Id) {
|
||||
continue
|
||||
}
|
||||
npcCfgData, ok1 := serverproto.NpcCfgLoader[val.bossData.SummonId]
|
||||
if !ok1 {
|
||||
util.InfoF("NpcCfgLoader npc data not find summonid=%v ", val.bossData.SummonId)
|
||||
continue
|
||||
}
|
||||
if nowTime1.Before(val.bossData.BossBeginTime) || nowTime1.After(val.bossData.BossEndTime) {
|
||||
continue
|
||||
}
|
||||
|
||||
info := &serverproto.WorldBossContentInfo{
|
||||
BossId: int32(val.bossData.Id),
|
||||
CfgId: val.bossData.SummonId,
|
||||
FighterNum: 0,
|
||||
ExpireTime: 0,
|
||||
NextRefreshTime: uint64(val.refreshTime.Unix()) * 1000,
|
||||
TotalHp: int32(npcCfgData.Hp),
|
||||
CurHp: int32(npcCfgData.Hp),
|
||||
BossSummonType: val.bossData.SummonType,
|
||||
}
|
||||
ackMsg.WorldBossList = append(ackMsg.WorldBossList, info)
|
||||
}
|
||||
|
||||
return ackMsg
|
||||
}
|
||||
}
|
||||
28
server/roserver/fruit/model/fruit_model.go
Normal file
28
server/roserver/fruit/model/fruit_model.go
Normal file
@ -0,0 +1,28 @@
|
||||
package model
|
||||
|
||||
import (
|
||||
"rocommon"
|
||||
)
|
||||
|
||||
var (
|
||||
updateList []interface{}
|
||||
|
||||
AoiLineMag *WorldBossManager = nil
|
||||
)
|
||||
|
||||
type FruitUpdate struct {
|
||||
rocommon.UpdateModule //eventqueue.go
|
||||
}
|
||||
|
||||
// 定义初始化模块,比方说角色管理模块,任务模块等,然后通过update来处理定时器相关的处理
|
||||
func (this *FruitUpdate) Init() {
|
||||
AoiLineMag = newWorldBossManager()
|
||||
updateList = append(updateList, AoiLineMag)
|
||||
}
|
||||
|
||||
func (this *FruitUpdate) Update(ms uint64) {
|
||||
//对管理器进行更新操作
|
||||
for _, data := range updateList {
|
||||
data.(rocommon.UpdateLogic).Update(ms)
|
||||
}
|
||||
}
|
||||
129
server/roserver/fruit/model/fruit_orm_helper.go
Normal file
129
server/roserver/fruit/model/fruit_orm_helper.go
Normal file
@ -0,0 +1,129 @@
|
||||
package model
|
||||
|
||||
import (
|
||||
"encoding/base64"
|
||||
"rocommon"
|
||||
"rocommon/service"
|
||||
"rocommon/util"
|
||||
"roserver/baseserver/model"
|
||||
"roserver/serverproto"
|
||||
"strconv"
|
||||
)
|
||||
|
||||
const (
|
||||
WorldBossStatePrefix = "wb_state_"
|
||||
WorldBossStateUidListPrefix = "wb_state_list_"
|
||||
)
|
||||
|
||||
func GetWorldBossList(bossMag *WorldBossManager) bool {
|
||||
wbList, err := service.GetRedis().HGetAll(WorldBossStatePrefix).Result()
|
||||
if err != nil && err != service.NIL {
|
||||
util.InfoF("GetWorldBossList key=%v err=%v", WorldBossStatePrefix, err)
|
||||
return false
|
||||
}
|
||||
|
||||
for key, val := range wbList {
|
||||
worldBossId, _ := model.Str2Num(key)
|
||||
if worldBossId > 0 {
|
||||
msgStr, err := base64.StdEncoding.DecodeString(val)
|
||||
if err != nil {
|
||||
util.InfoF("GetWorldBossList key=%v err=%v", key, err)
|
||||
continue
|
||||
}
|
||||
stateInfo := &serverproto.WorldBossStateInfo{}
|
||||
err = rocommon.GetCodec().Unmarshal(msgStr, stateInfo)
|
||||
if err != nil {
|
||||
continue
|
||||
}
|
||||
|
||||
//challenge uid list
|
||||
key := WorldBossStateUidListPrefix + key
|
||||
uidListLen, err := service.GetRedis().LLen(key).Result()
|
||||
if uidListLen > 0 {
|
||||
var idx int64 = 0
|
||||
for {
|
||||
uidStrList, _ := service.GetRedis().LRange(key, idx, idx+200).Result()
|
||||
if len(uidStrList) <= 0 {
|
||||
break
|
||||
}
|
||||
for idx := 0; idx < len(uidStrList); idx++ {
|
||||
tmpUid, _ := model.Str2NumU64(uidStrList[idx])
|
||||
if tmpUid > 0 {
|
||||
stateInfo.UidList = append(stateInfo.UidList, tmpUid)
|
||||
}
|
||||
}
|
||||
|
||||
idx += 100
|
||||
if idx >= uidListLen {
|
||||
break
|
||||
}
|
||||
}
|
||||
}
|
||||
util.InfoF("GetWorldBossList key=%v err=%v len=%v", key, err, uidListLen)
|
||||
//add failed,then remove current item
|
||||
if !bossMag.AddBossFromDB(stateInfo) {
|
||||
service.GetRedis().HDel(WorldBossStatePrefix, key)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return true
|
||||
}
|
||||
|
||||
func UpdateWorldBossList(bossInfo *PlayerBoss) bool {
|
||||
if bossInfo.bossUid <= 0 {
|
||||
util.InfoF("UpdateWorldBossList bossId=%v", bossInfo.bossUid)
|
||||
return false
|
||||
}
|
||||
|
||||
stateInfo := &serverproto.WorldBossStateInfo{
|
||||
BossId: int32(bossInfo.bossUid),
|
||||
Hp: bossInfo.totalHp,
|
||||
SummonTime: bossInfo.summonTime,
|
||||
DurationTime: int32(bossInfo.durationTime / 1000),
|
||||
SummonIdx: bossInfo.summonBossIdx,
|
||||
SummonBossType: bossInfo.summonBossType,
|
||||
}
|
||||
|
||||
msgData, err := rocommon.GetCodec().Marshal(stateInfo)
|
||||
if err != nil {
|
||||
util.InfoF("UpdateWorldBossList bossId=%v err=%v", bossInfo.bossUid, err)
|
||||
return false
|
||||
}
|
||||
msgStr := base64.StdEncoding.EncodeToString(msgData.([]byte))
|
||||
fieldStr := strconv.Itoa(int(bossInfo.bossUid))
|
||||
service.GetRedis().HSet(WorldBossStatePrefix, fieldStr, msgStr)
|
||||
|
||||
return true
|
||||
}
|
||||
|
||||
func DelWorldBossList(bossInfo *PlayerBoss) bool {
|
||||
if bossInfo.bossUid <= 0 {
|
||||
util.InfoF("UpdateWorldBossList bossId=%v", bossInfo.bossUid)
|
||||
return false
|
||||
}
|
||||
|
||||
//boss info
|
||||
fieldStr := strconv.Itoa(int(bossInfo.bossUid))
|
||||
service.GetRedis().HDel(WorldBossStatePrefix, fieldStr)
|
||||
|
||||
//boss challenge uid list
|
||||
bossIdStr := strconv.Itoa(int(bossInfo.bossUid))
|
||||
keyStr := WorldBossStateUidListPrefix + bossIdStr
|
||||
service.GetRedis().Del(keyStr)
|
||||
|
||||
return true
|
||||
}
|
||||
|
||||
func WorldBossListAddChallenge(bossInfo *PlayerBoss, uid uint64) bool {
|
||||
if uid <= 0 || bossInfo.bossUid <= 0 {
|
||||
util.ErrorF("UpdateWorldBossList bossId=%v", bossInfo.bossUid)
|
||||
return false
|
||||
}
|
||||
|
||||
bossIdStr := strconv.Itoa(int(bossInfo.bossUid))
|
||||
keyStr := WorldBossStateUidListPrefix + bossIdStr
|
||||
service.GetRedis().LPush(keyStr, uid)
|
||||
|
||||
return true
|
||||
}
|
||||
455
server/roserver/fruit/model/fruit_player.go
Normal file
455
server/roserver/fruit/model/fruit_player.go
Normal file
@ -0,0 +1,455 @@
|
||||
package model
|
||||
|
||||
import (
|
||||
"container/heap"
|
||||
"math/rand"
|
||||
"rocommon/util"
|
||||
"roserver/baseserver/model"
|
||||
"roserver/baseserver/set"
|
||||
"roserver/serverproto"
|
||||
"sort"
|
||||
)
|
||||
|
||||
////////////////////////////////PlayerBoss
|
||||
type BossRoom struct {
|
||||
roomId int32
|
||||
uidList map[uint64]struct{}
|
||||
}
|
||||
|
||||
func (this *BossRoom) AddUid(uid uint64) {
|
||||
this.uidList[uid] = struct{}{}
|
||||
}
|
||||
|
||||
func (this *BossRoom) RemUid(uid uint64) {
|
||||
delete(this.uidList, uid)
|
||||
}
|
||||
|
||||
type PlayerBoss struct {
|
||||
model.StateMachineCore
|
||||
|
||||
mag *WorldBossManager
|
||||
bossUid uint64 //worldbosscfgid
|
||||
summonBossId int32 //bossCfgId
|
||||
summonBossType int32 //SummonBossType
|
||||
summonBossIdx int32 //召唤次数
|
||||
summonTime uint64 //召唤时间戳
|
||||
durationTime uint64 //boss持续时间s
|
||||
totalHp int32
|
||||
maxHp int32
|
||||
hpDirty bool
|
||||
|
||||
SummonRewardList []*serverproto.KeyValueType //参与boss挑战奖励
|
||||
KillNormalRewardList, KillSpecialRewardList serverproto.KeyValueType //击杀参与奖 drop //击杀大奖 drop
|
||||
|
||||
challengeList map[uint64]model.ClientID //当前正在挑战的玩家列表
|
||||
allChallengeList set.Interface //挑战玩家列表,包行当前正在挑战玩家
|
||||
challengeDataList map[uint64]*serverproto.FightRoleInfo //玩家数据
|
||||
|
||||
maxPoint int32 //最大点数
|
||||
|
||||
uidRoomList map[uint64]int32 //[uid,roomId]
|
||||
roomList map[int32]*BossRoom //[roomId,[uid...]]
|
||||
freeRoomList *model.MinHeap //[roomId]
|
||||
maxRoomId int32
|
||||
lastHPReduceTime uint64
|
||||
|
||||
finish bool
|
||||
}
|
||||
|
||||
func newPlayerBoss(mag *WorldBossManager) *PlayerBoss {
|
||||
playerBoss := &PlayerBoss{
|
||||
mag: mag,
|
||||
roomList: map[int32]*BossRoom{},
|
||||
uidRoomList: map[uint64]int32{},
|
||||
}
|
||||
playerBoss.challengeList = map[uint64]model.ClientID{}
|
||||
playerBoss.allChallengeList = set.New(set.NonThreadSafe)
|
||||
playerBoss.challengeDataList = map[uint64]*serverproto.FightRoleInfo{}
|
||||
//min heap
|
||||
playerBoss.freeRoomList = &model.MinHeap{}
|
||||
heap.Init(playerBoss.freeRoomList)
|
||||
|
||||
return playerBoss
|
||||
}
|
||||
|
||||
func (this *PlayerBoss) Init() {
|
||||
this.InitState()
|
||||
|
||||
this.RegisterState(int32(BOSS_STATE_FIGHTING), bossStateFighting)
|
||||
this.RegisterState(int32(BOSS_STATE_DIED), bossStateDie)
|
||||
this.RegisterState(int32(BOSS_STATE_TIME_OUT), bossStateTimeout)
|
||||
}
|
||||
|
||||
func (this *PlayerBoss) SetTotalHp(hp int32) {
|
||||
this.totalHp = hp
|
||||
this.maxHp = hp
|
||||
}
|
||||
|
||||
func (this *PlayerBoss) clear() {
|
||||
for uid, _ := range this.challengeList {
|
||||
delete(this.mag.challengePlayerList, uid)
|
||||
delete(this.challengeList, uid)
|
||||
}
|
||||
|
||||
this.allChallengeList.Clear()
|
||||
this.challengeDataList = map[uint64]*serverproto.FightRoleInfo{}
|
||||
|
||||
this.maxRoomId = 0
|
||||
this.uidRoomList = map[uint64]int32{}
|
||||
this.roomList = map[int32]*BossRoom{}
|
||||
}
|
||||
|
||||
//是否在挑战boss时间内
|
||||
func (this *PlayerBoss) checkTimeValid(nowTime uint64) bool {
|
||||
if this.summonTime > 0 {
|
||||
oldTime := this.summonTime + this.durationTime
|
||||
return oldTime > nowTime
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
func (this *PlayerBoss) addChallengePlayer(uid uint64, id model.ClientID, roleData *serverproto.FightRoleInfo) {
|
||||
if !this.allChallengeList.Has(uid) {
|
||||
this.allChallengeList.Add(uid)
|
||||
WorldBossListAddChallenge(this, uid)
|
||||
}
|
||||
|
||||
//self
|
||||
this.bossChangePlay(roleData)
|
||||
this.challengeList[uid] = id
|
||||
this.challengeDataList[uid] = roleData
|
||||
|
||||
//manager
|
||||
this.mag.challengePlayerList[uid] = this
|
||||
|
||||
//use for notify(enter/leave)
|
||||
var tmpRoomId int32 = 0
|
||||
if this.freeRoomList.Len() > 0 {
|
||||
tmpRoomId = heap.Pop(this.freeRoomList).(int32)
|
||||
} else {
|
||||
this.maxRoomId++
|
||||
tmpRoomId = this.maxRoomId
|
||||
}
|
||||
this.uidRoomList[uid] = tmpRoomId
|
||||
if this.roomList[tmpRoomId] == nil {
|
||||
this.roomList[tmpRoomId] = &BossRoom{
|
||||
uidList: map[uint64]struct{}{},
|
||||
}
|
||||
}
|
||||
this.roomList[tmpRoomId].AddUid(uid)
|
||||
if len(this.roomList[tmpRoomId].uidList) < MAX_BOSS_CHALLENGE_PLAYER_NUM {
|
||||
heap.Push(this.freeRoomList, tmpRoomId)
|
||||
}
|
||||
|
||||
//通知自己和其他玩家
|
||||
this.enterNotify(uid, tmpRoomId)
|
||||
}
|
||||
|
||||
//玩家挑战boss触发变身操作
|
||||
func (this *PlayerBoss) bossChangePlay(roleData *serverproto.FightRoleInfo) {
|
||||
switch this.summonBossType {
|
||||
case model.SummonBossType_ChangePlay:
|
||||
cfgData, ok := model.ConvertWorldBossChangePlayList[int32(this.bossUid)]
|
||||
if !ok {
|
||||
util.InfoF("AddBossFromRefresh WorldBossChangePlayCfgLoader not find boss=%v ", this.summonBossId)
|
||||
return
|
||||
}
|
||||
changePlayId := cfgData.RandChangePlayId()
|
||||
if changePlayId > 0 {
|
||||
roleData.ChangePlayId = changePlayId
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func (this *PlayerBoss) canChallenge(uid uint64) serverproto.ErrorCode {
|
||||
if len(this.challengeList) >= 1000 {
|
||||
return serverproto.ErrorCode_ERROR_AOI_BOSS_CHALLENGE_NUM_LIMIT
|
||||
}
|
||||
|
||||
if this.totalHp <= 0 {
|
||||
return serverproto.ErrorCode_ERROR_AOI_BOSS_NOT_FOUND
|
||||
}
|
||||
|
||||
return serverproto.ErrorCode_ERROR_OK
|
||||
}
|
||||
|
||||
//通知自己和其他玩家
|
||||
func (this *PlayerBoss) enterNotify(enterUid uint64, roomId int32) {
|
||||
//发送其他玩家信息给自己,并发送自己信息给其他玩家
|
||||
selfNtfMsg := &serverproto.SSPlayerEnterChallengeNtf{
|
||||
BossUid: this.bossUid,
|
||||
EnterUid: enterUid,
|
||||
SelfChangePlayId: this.challengeDataList[enterUid].ChangePlayId,
|
||||
SummonBossType: this.summonBossType,
|
||||
}
|
||||
otherNtfMsg := &serverproto.SSPlayerEnterChallengeNtf{
|
||||
BossUid: this.bossUid,
|
||||
EnterUid: enterUid,
|
||||
SummonBossType: this.summonBossType,
|
||||
}
|
||||
otherNtfMsg.FightList = append(otherNtfMsg.FightList, this.challengeDataList[enterUid])
|
||||
|
||||
var otherSendList = map[string][]uint64{}
|
||||
roomInfo := this.roomList[roomId]
|
||||
for tmpUid, _ := range roomInfo.uidList {
|
||||
if tmpUid == enterUid {
|
||||
continue
|
||||
}
|
||||
tmpUidCli, ok := this.challengeList[tmpUid]
|
||||
if !ok {
|
||||
continue
|
||||
}
|
||||
selfNtfMsg.FightList = append(selfNtfMsg.FightList, this.challengeDataList[tmpUid])
|
||||
otherSendList[tmpUidCli.ServiceID] = append(otherSendList[tmpUidCli.ServiceID], tmpUid)
|
||||
}
|
||||
|
||||
sort.Slice(selfNtfMsg.FightList, func(i, j int) bool {
|
||||
return selfNtfMsg.FightList[i].BriefInfo.Uid < selfNtfMsg.FightList[j].BriefInfo.Uid
|
||||
})
|
||||
//send self
|
||||
this.mag.SendGame(selfNtfMsg, this.challengeList[enterUid].ServiceID, 0)
|
||||
|
||||
//send other
|
||||
for idx := range otherSendList {
|
||||
otherNtfMsg.NotifyList = otherNtfMsg.NotifyList[:0]
|
||||
otherNtfMsg.NotifyList = append(otherSendList[idx])
|
||||
this.mag.SendGame(otherNtfMsg, idx, 0)
|
||||
}
|
||||
}
|
||||
|
||||
//离开boss,发送其他玩家信息给当前玩家
|
||||
func (this *PlayerBoss) leaveNotify(leaveUid uint64) {
|
||||
var notifyList = map[string][]uint64{}
|
||||
if leaveUidData, ok := this.challengeList[leaveUid]; ok {
|
||||
//需要做rand点处理
|
||||
_, ok := this.mag.challengePlayerList[leaveUid]
|
||||
if ok {
|
||||
//需要做rand点处理
|
||||
pointNtfMsg := &serverproto.SCPlayerWorldBossRandNtf{
|
||||
PointInfo: &serverproto.WorldBossRandPointInfo{
|
||||
BossSummonType: this.summonBossType,
|
||||
},
|
||||
}
|
||||
pointNtfMsg.PointInfo.BossId = int32(this.bossUid)
|
||||
pointNtfMsg.PointInfo.BossSummonIdx = this.summonBossIdx
|
||||
this.mag.SendGame(pointNtfMsg, leaveUidData.ServiceID, leaveUid)
|
||||
|
||||
delete(this.mag.challengePlayerList, leaveUid)
|
||||
}
|
||||
delete(this.challengeList, leaveUid)
|
||||
|
||||
if roomId, ok := this.uidRoomList[leaveUid]; ok {
|
||||
roomInfo := this.roomList[roomId]
|
||||
for tmpUid, _ := range roomInfo.uidList {
|
||||
if tmpUid == leaveUid {
|
||||
continue
|
||||
}
|
||||
|
||||
if notifyData, ok := this.challengeList[tmpUid]; ok {
|
||||
notifyList[notifyData.ServiceID] = append(notifyList[notifyData.ServiceID], tmpUid)
|
||||
}
|
||||
}
|
||||
|
||||
roomInfo.RemUid(leaveUid)
|
||||
bPushed := false
|
||||
for idx := 0; idx < this.freeRoomList.Len(); idx++ {
|
||||
if this.freeRoomList.ItemList[idx] == roomId {
|
||||
bPushed = true
|
||||
break
|
||||
}
|
||||
}
|
||||
if !bPushed {
|
||||
heap.Push(this.freeRoomList, roomId)
|
||||
}
|
||||
delete(this.uidRoomList, leaveUid)
|
||||
}
|
||||
}
|
||||
|
||||
leaveNtfMsg := &serverproto.SSPlayerLeaveChallengeNtf{
|
||||
LeaveUid: leaveUid,
|
||||
}
|
||||
for serviceNode := range notifyList {
|
||||
leaveNtfMsg.NotifyList = leaveNtfMsg.NotifyList[:0]
|
||||
leaveNtfMsg.NotifyList = append(notifyList[serviceNode])
|
||||
this.mag.SendGame(leaveNtfMsg, serviceNode, 0)
|
||||
}
|
||||
}
|
||||
|
||||
func (this *PlayerBoss) updateBossHp(ms uint64) {
|
||||
//boss没人打过,则不触发掉血
|
||||
if this.GetState() == BOSS_STATE_TIME_OUT {
|
||||
return
|
||||
}
|
||||
if this.totalHp >= this.maxHp || this.lastHPReduceTime == 0 {
|
||||
return
|
||||
}
|
||||
cfgData, ok := model.ConvertWorldBossList[int32(this.bossUid)]
|
||||
if !ok || cfgData.ReduceHp.Key <= 0 || cfgData.ReduceHp.Value <= 0 {
|
||||
return
|
||||
}
|
||||
|
||||
if ms > this.lastHPReduceTime+uint64(cfgData.ReduceHp.Key)*1000 {
|
||||
reduceHp := (this.maxHp / 10000) * cfgData.ReduceHp.Value
|
||||
if reduceHp > 0 {
|
||||
this.hpDirty = true
|
||||
this.totalHp -= reduceHp
|
||||
if this.totalHp <= 0 {
|
||||
this.totalHp = 0
|
||||
util.InfoF("update world boss reduce hp bossid= %v hp= %v", this.bossUid, cfgData.ReduceHp.Value)
|
||||
this.SwitchState(int32(BOSS_STATE_DIED), nil)
|
||||
}
|
||||
this.lastHPReduceTime = ms
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func (this *PlayerBoss) broadcastBossHp() {
|
||||
if len(this.challengeList) <= 0 {
|
||||
return
|
||||
}
|
||||
|
||||
if !this.hpDirty {
|
||||
return
|
||||
}
|
||||
this.hpDirty = false
|
||||
|
||||
//update to db
|
||||
UpdateWorldBossList(this)
|
||||
|
||||
var notifyList = map[string][]uint64{}
|
||||
for uid, data := range this.challengeList {
|
||||
notifyList[data.ServiceID] = append(notifyList[data.ServiceID], uid)
|
||||
}
|
||||
|
||||
hpNtfMsg := &serverproto.SSPlayerChallengeHpNtf{
|
||||
CurBossHp: this.totalHp,
|
||||
}
|
||||
sendCount := 50
|
||||
for serviceNode := range notifyList {
|
||||
uidLen := len(notifyList[serviceNode])
|
||||
if uidLen <= 0 {
|
||||
continue
|
||||
}
|
||||
|
||||
idx := 0
|
||||
if uidLen > sendCount {
|
||||
idx = 0
|
||||
}
|
||||
for {
|
||||
if idx+sendCount < uidLen {
|
||||
hpNtfMsg.NotifyList = notifyList[serviceNode][idx : idx+sendCount]
|
||||
idx += sendCount
|
||||
} else {
|
||||
hpNtfMsg.NotifyList = notifyList[serviceNode][idx:uidLen]
|
||||
this.mag.SendGame(hpNtfMsg, serviceNode, 0)
|
||||
break
|
||||
}
|
||||
this.mag.SendGame(hpNtfMsg, serviceNode, 0)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func (this *PlayerBoss) broadcastResult(result int32) {
|
||||
if len(this.challengeList) <= 0 {
|
||||
return
|
||||
}
|
||||
var notifyList = map[string][]uint64{}
|
||||
for uid, data := range this.challengeList {
|
||||
notifyList[data.ServiceID] = append(notifyList[data.ServiceID], uid)
|
||||
}
|
||||
|
||||
resultNtfMsg := &serverproto.SSPlayerChallengeResultNtf{
|
||||
Result: result,
|
||||
}
|
||||
for serviceNode := range notifyList {
|
||||
resultNtfMsg.NotifyList = resultNtfMsg.NotifyList[:0]
|
||||
resultNtfMsg.NotifyList = append(notifyList[serviceNode])
|
||||
this.mag.SendGame(resultNtfMsg, serviceNode, 0)
|
||||
}
|
||||
}
|
||||
|
||||
func (this *PlayerBoss) battleTimeOut(fromDB bool) {
|
||||
util.InfoF("battleTimeOut bossid=%v", this.bossUid)
|
||||
|
||||
if !fromDB {
|
||||
//非正常结束战斗
|
||||
this.broadcastResult(BOSS_RESULT_TIME_OUT)
|
||||
}
|
||||
|
||||
this.finish = true
|
||||
//清理数据
|
||||
this.clear()
|
||||
}
|
||||
|
||||
func (this *PlayerBoss) battleBossDie(fromDB bool) {
|
||||
util.InfoF("battleWin bossid=%v", this.bossUid)
|
||||
|
||||
if !fromDB {
|
||||
this.broadcastResult(BOSS_RESULT_WIN)
|
||||
this.battleReward()
|
||||
}
|
||||
|
||||
this.finish = true
|
||||
//清理数据
|
||||
this.clear()
|
||||
}
|
||||
|
||||
func (this *PlayerBoss) battleReward() {
|
||||
if len(this.challengeList) > 0 {
|
||||
//需要做rand点处理
|
||||
pointNtfMsg := &serverproto.SCPlayerWorldBossRandNtf{
|
||||
PointInfo: &serverproto.WorldBossRandPointInfo{},
|
||||
}
|
||||
|
||||
for uid, data := range this.challengeList {
|
||||
pointNtfMsg.PointInfo.BossId = int32(this.bossUid)
|
||||
this.mag.SendGame(pointNtfMsg, data.ServiceID, uid)
|
||||
}
|
||||
}
|
||||
|
||||
////参与boss奖励
|
||||
//// 发送邮件奖励
|
||||
//cfgData, ok := model.ConvertWorldBossList[int32(this.bossUid)]
|
||||
//if ok {
|
||||
// normalMailNtfMsg := &serverproto.SSAddMailNtf{
|
||||
// MailConfigId: BOSS_REWARD_MAIL_CONFIG_ID_Other,
|
||||
// MailType: int32(serverproto.MailType_MailType_Boss),
|
||||
// }
|
||||
// normalMailNtfMsg.RewardList = append(normalMailNtfMsg.RewardList, cfgData.SummonRewardList...)
|
||||
// normalMailNtfMsg.MailParamList = append(normalMailNtfMsg.MailParamList, cfgData.Id)
|
||||
//
|
||||
// for _, data := range this.allChallengeList.List() {
|
||||
// normalMailNtfMsg.NotifyList = append(normalMailNtfMsg.NotifyList, data.(uint64))
|
||||
// }
|
||||
//
|
||||
// this.mag.SendSocial(normalMailNtfMsg)
|
||||
//}
|
||||
}
|
||||
|
||||
//boss战斗
|
||||
func (this *PlayerBoss) ProcessBattle(damageHp int32) {
|
||||
if this.totalHp > 0 && damageHp > 0 {
|
||||
this.hpDirty = true
|
||||
this.totalHp -= damageHp
|
||||
if this.totalHp <= 0 {
|
||||
this.totalHp = 0
|
||||
util.InfoF("ProcessBattle battle finish success")
|
||||
this.SwitchState(int32(BOSS_STATE_DIED), nil)
|
||||
}
|
||||
this.lastHPReduceTime = util.GetTimeMilliseconds()
|
||||
}
|
||||
}
|
||||
|
||||
func (this *PlayerBoss) RandPoint(uid uint64) (serverproto.ErrorCode, bool, int32) {
|
||||
_, ok := this.challengeDataList[uid]
|
||||
if !ok {
|
||||
return serverproto.ErrorCode_ERROR_FAIL, false, 0
|
||||
}
|
||||
|
||||
rand.Seed(int64(util.GetTimeMilliseconds()))
|
||||
randNum := rand.Int31n(100) + 1
|
||||
if randNum >= this.maxPoint {
|
||||
return serverproto.ErrorCode_ERROR_OK, true, randNum
|
||||
}
|
||||
return serverproto.ErrorCode_ERROR_OK, false, randNum
|
||||
}
|
||||
40
server/roserver/fruit/model/fruit_player_state.go
Normal file
40
server/roserver/fruit/model/fruit_player_state.go
Normal file
@ -0,0 +1,40 @@
|
||||
package model
|
||||
|
||||
import (
|
||||
"roserver/baseserver/model"
|
||||
"unsafe"
|
||||
)
|
||||
|
||||
const (
|
||||
BOSS_STATE_FIGHTING = 1 //正在战斗中
|
||||
BOSS_STATE_DIED = 2 //死亡
|
||||
BOSS_STATE_TIME_OUT = 3 //召唤持续时间达到上限
|
||||
BOSS_STATE_REFRESH = 4 //系统刷新方式
|
||||
)
|
||||
|
||||
var bossStateFighting = func(r *model.StateMachineCore, data interface{}) int32 {
|
||||
//parent := unsafe.Pointer(r)
|
||||
//return (*PlayerBoss)(parent).pullingRoleList()
|
||||
//return ROLE_STATE_PULLING_LIST
|
||||
return BOSS_STATE_FIGHTING
|
||||
}
|
||||
|
||||
var bossStateDie = func(r *model.StateMachineCore, data interface{}) int32 {
|
||||
parent := unsafe.Pointer(r)
|
||||
if data != nil {
|
||||
(*PlayerBoss)(parent).battleBossDie(data.(bool))
|
||||
} else {
|
||||
(*PlayerBoss)(parent).battleBossDie(false)
|
||||
}
|
||||
return BOSS_STATE_DIED
|
||||
}
|
||||
|
||||
var bossStateTimeout = func(r *model.StateMachineCore, data interface{}) int32 {
|
||||
parent := unsafe.Pointer(r)
|
||||
if data != nil {
|
||||
(*PlayerBoss)(parent).battleTimeOut(data.(bool))
|
||||
} else {
|
||||
(*PlayerBoss)(parent).battleTimeOut(false)
|
||||
}
|
||||
return BOSS_STATE_TIME_OUT
|
||||
}
|
||||
146
server/roserver/fruit/model/msg_send.go
Normal file
146
server/roserver/fruit/model/msg_send.go
Normal file
@ -0,0 +1,146 @@
|
||||
package model
|
||||
|
||||
import (
|
||||
"rocommon/rpc"
|
||||
"rocommon/util"
|
||||
"roserver/baseserver/model"
|
||||
"roserver/serverproto"
|
||||
)
|
||||
|
||||
/////////////////////////////////////////////发送数据
|
||||
func (this *WorldBossManager) SendMapRouter(msg interface{}, uid uint64) bool {
|
||||
data, meta, err := rpc.EncodeMessage(msg)
|
||||
if err != nil {
|
||||
util.InfoF("[SendMapRouter] EncodeMessage err:%v %v", err, msg)
|
||||
return false
|
||||
}
|
||||
|
||||
if this.mapRouterNode == "" {
|
||||
this.mapRouterNode = model.SelectServiceNode(model.SERVICE_NODE_TYPE_MAP_ROUTER_STR, 0)
|
||||
}
|
||||
if this.mapRouterNode == "" {
|
||||
util.InfoF("[SendMapRouter] map router node not exist msg:%v", msg)
|
||||
return false
|
||||
}
|
||||
|
||||
mapRouterSess := model.GetServiceNode(this.mapRouterNode)
|
||||
if mapRouterSess == nil {
|
||||
util.InfoF("[SendMapRouter] aoiRouter session not exist:%v", this.mapRouterNode)
|
||||
} else {
|
||||
//如果玩家信息存在,ClientId中存放的是玩家ID,否则存放的是玩家的gate sessionId
|
||||
mapRouterSess.Send(&serverproto.ServiceTransmitAck{
|
||||
MsgId: uint32(meta.ID),
|
||||
MsgData: data,
|
||||
//todo...
|
||||
// 对应的玩家 gate channelId channelRoleList[key]
|
||||
// 后续和gate直接通信时使用,如果断线重连需要重新绑定
|
||||
ClientId: uid, //对应的玩家 gate uuid uuidRoleList[key]
|
||||
})
|
||||
}
|
||||
return true
|
||||
}
|
||||
|
||||
func (this *WorldBossManager) SendSocial(msg interface{}) bool {
|
||||
data, meta, err := rpc.EncodeMessage(msg)
|
||||
if err != nil {
|
||||
util.ErrorF("[SendSocial] EncodeMessage err:%v %v", err, msg)
|
||||
return false
|
||||
}
|
||||
|
||||
if this.socialNode == "" {
|
||||
this.socialNode = model.SelectServiceNode(model.SERVICE_NODE_TYPE_SOCIAL_STR, 0)
|
||||
}
|
||||
if this.socialNode == "" {
|
||||
util.ErrorF("[SendSocial] social node not exist msg:%v", msg)
|
||||
return false
|
||||
}
|
||||
|
||||
socialSess := model.GetServiceNode(this.socialNode)
|
||||
if socialSess == nil {
|
||||
util.ErrorF("[SendSocial] social session not exist:%v", this.mapRouterNode)
|
||||
} else {
|
||||
//如果玩家信息存在,ClientId中存放的是玩家ID,否则存放的是玩家的gate sessionId
|
||||
socialSess.Send(&serverproto.ServiceTransmitAck{
|
||||
MsgId: uint32(meta.ID),
|
||||
MsgData: data,
|
||||
})
|
||||
}
|
||||
return true
|
||||
}
|
||||
|
||||
func SendDB(msg interface{}) bool {
|
||||
data, meta, err := rpc.EncodeMessage(msg)
|
||||
if err != nil {
|
||||
util.InfoF("[SendDB] EncodeMessage err:%v %v", err, msg)
|
||||
return false
|
||||
}
|
||||
|
||||
dbNode := model.SelectServiceNode(model.SERVICE_NODE_TYPE_DB_STR, 0)
|
||||
if dbNode == "" {
|
||||
util.InfoF("[SendDB] db node not exist msg:%v", msg)
|
||||
return false
|
||||
}
|
||||
|
||||
dbSess := model.GetServiceNode(dbNode)
|
||||
if dbSess == nil {
|
||||
util.ErrorF("[SendDB] db session not exist:%v", dbSess)
|
||||
return false
|
||||
} else {
|
||||
//如果玩家信息存在,ClientId中存放的是玩家ID,否则存放的是玩家的gate sessionId
|
||||
dbSess.Send(&serverproto.ServiceTransmitAck{
|
||||
MsgId: uint32(meta.ID),
|
||||
MsgData: data,
|
||||
})
|
||||
}
|
||||
return true
|
||||
}
|
||||
|
||||
func (this *WorldBossManager) SendGame(msg interface{}, gameNode string, uid uint64) bool {
|
||||
return this.SendServiceByNode(msg, gameNode, uid)
|
||||
}
|
||||
|
||||
func (this *WorldBossManager) SendServiceByNode(msg interface{}, serviceNode string, uid uint64) bool {
|
||||
data, meta, err := rpc.EncodeMessage(msg)
|
||||
if err != nil {
|
||||
util.InfoF("[SendServiceByNode] EncodeMessage err:%v %v", err, msg)
|
||||
return false
|
||||
}
|
||||
|
||||
nodeSess := model.GetServiceNode(serviceNode)
|
||||
if nodeSess == nil {
|
||||
util.InfoF("[SendServiceByNode] service session not exist:%v", serviceNode)
|
||||
} else {
|
||||
//如果玩家信息存在,ClientId中存放的是玩家ID,否则存放的是玩家的gate sessionId
|
||||
ackMsg := &serverproto.ServiceTransmitAck{
|
||||
MsgId: uint32(meta.ID),
|
||||
MsgData: data,
|
||||
}
|
||||
if uid != 0 {
|
||||
ackMsg.ClientId = uid
|
||||
}
|
||||
nodeSess.Send(ackMsg)
|
||||
}
|
||||
return true
|
||||
}
|
||||
|
||||
func SendToAllGame(msg interface{}) {
|
||||
data, info, err := rpc.EncodeMessage(msg)
|
||||
if err != nil {
|
||||
util.InfoF("[SendGame]EncodeMessage err:%v %v", err, msg)
|
||||
return
|
||||
}
|
||||
sendMsg := &serverproto.ServiceTransmitAck{
|
||||
MsgId: uint32(info.ID),
|
||||
MsgData: data,
|
||||
}
|
||||
|
||||
serviceList := model.GetAllServiceNodeByName(model.SERVICE_NODE_TYPE_GAME_STR)
|
||||
if len(serviceList) > 0 {
|
||||
for _, node := range serviceList {
|
||||
gameSess := model.GetServiceNode(node)
|
||||
if gameSess != nil {
|
||||
gameSess.Send(sendMsg)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
61
server/roserver/fruit/msg/battle_msg.go
Normal file
61
server/roserver/fruit/msg/battle_msg.go
Normal file
@ -0,0 +1,61 @@
|
||||
package msg
|
||||
|
||||
import (
|
||||
"rocommon"
|
||||
"rocommon/util"
|
||||
"roserver/baseserver/model"
|
||||
model2 "roserver/battleboss/model"
|
||||
"roserver/serverproto"
|
||||
)
|
||||
|
||||
func init() {
|
||||
//玩家下线处理/主动离开boss场景
|
||||
serverproto.Handle_BATTLEBOSS_SSPlayerOfflineNtf = model.HandleBackendMessage(func(ev rocommon.ProcEvent, cliId model.ClientID) {
|
||||
msg := ev.Msg().(*serverproto.SSPlayerOfflineNtf)
|
||||
util.InfoF("receive SSPlayerOfflineNtf msg:%v", msg)
|
||||
|
||||
model2.AoiLineMag.PlayerOffline(msg.Uid)
|
||||
})
|
||||
|
||||
//挑战召唤物
|
||||
serverproto.Handle_BATTLEBOSS_CSPlayerChallengeSummonReq = model.HandleBackendMessage(func(ev rocommon.ProcEvent, cliId model.ClientID) {
|
||||
msg := ev.Msg().(*serverproto.CSPlayerChallengeSummonReq)
|
||||
util.InfoF("receive CSPlayerChallengeSummonReq msg:%v", msg)
|
||||
|
||||
ret := model2.AoiLineMag.PlayerChallengeSummonBoss(msg.Uid, msg.ChallengeBossUid, cliId, msg.FightInfo)
|
||||
ackMsg := &serverproto.SCPlayerChallengeSummonAck{
|
||||
Error: int32(ret),
|
||||
BossInfo: model2.AoiLineMag.GetWorldBossInfo(msg.ChallengeBossUid),
|
||||
}
|
||||
|
||||
//删除boss使用
|
||||
if ret == serverproto.ErrorCode_ERROR_AOI_BOSS_NOT_FOUND {
|
||||
ackMsg.BossInfo = &serverproto.WorldBossContentInfo{
|
||||
BossId: int32(msg.ChallengeBossUid),
|
||||
}
|
||||
//更新boss信息
|
||||
} else if ret == serverproto.ErrorCode_ERROR_AOI_BOSS_CHALLENGE_NUM_LIMIT {
|
||||
ackMsg.BossInfo = model2.AoiLineMag.GetWorldBossInfo(msg.ChallengeBossUid)
|
||||
}
|
||||
|
||||
model.ServiceReplay(ev, ackMsg)
|
||||
})
|
||||
|
||||
//血量上报
|
||||
serverproto.Handle_BATTLEBOSS_CSPlayerChallengeHpReq = model.HandleBackendMessage(func(ev rocommon.ProcEvent, cliId model.ClientID) {
|
||||
msg := ev.Msg().(*serverproto.CSPlayerChallengeHpReq)
|
||||
util.InfoF("receive CSPlayerChallengeHpReq msg:%v %v", msg, cliId.SessID)
|
||||
|
||||
model2.AoiLineMag.DoSummonHp(cliId.SessID, msg.ActionUid, msg.DamageHp)
|
||||
})
|
||||
|
||||
//获取WorldBoss列表
|
||||
serverproto.Handle_BATTLEBOSS_CSPlayerWorldBossListReq = model.HandleBackendMessage(func(ev rocommon.ProcEvent, cliId model.ClientID) {
|
||||
msg := ev.Msg().(*serverproto.CSPlayerWorldBossListReq)
|
||||
util.DebugF("receive CSPlayerWorldBossListReq msg:%v %v", msg, cliId.SessID)
|
||||
|
||||
ackMsg := model2.AoiLineMag.GetWorldBossList()
|
||||
|
||||
model.ServiceReplay(ev, ackMsg)
|
||||
})
|
||||
}
|
||||
Loading…
x
Reference in New Issue
Block a user