| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200 |
- package mapPlayer
- import (
- capp "f1-game/internal/cherry_app"
- "f1-game/internal/code"
- "f1-game/internal/component/rate"
- "f1-game/internal/enum"
- "f1-game/internal/event"
- nameLocal "f1-game/internal/name/local"
- nameRemote "f1-game/internal/name/remote"
- "f1-game/internal/pb"
- "f1-game/internal/types"
- mapCall "f1-game/nodes/map/internal/call"
- "f1-game/nodes/map/internal/db"
- mapFacade "f1-game/nodes/map/internal/facade"
- ctime "github.com/cherry-game/cherry/extend/time"
- cfacade "github.com/cherry-game/cherry/facade"
- cherryActor "github.com/cherry-game/cherry/net/actor"
- )
- // actorPlayer 每个玩家一个PlayerActor
- type actorPlayer struct {
- capp.ActorLogger
- playerID int64 // 当前玩家id
- isOnline bool // 玩家是否在线
- now *ctime.CherryTime // 玩家当前时间
- funcLimiter rate.FuncLimiter // 函数访问限速
- funcErrCode int32 // 函数访问的错误码
- // 战斗处理器
- battleHandlers map[enum.TileBattleType]func(*pb.BattleReq, *pb.BattleRsp)
- }
- func newActorPlayer(playerID int64) actorPlayer {
- now := ctime.Now()
- return actorPlayer{
- ActorLogger: capp.NewLoggerPrefix("playerID", playerID),
- playerID: playerID,
- now: &now,
- funcLimiter: rate.NewFuncLimiter(30, 3, code.NodeRateLimiter),
- funcErrCode: code.NodeRateLimiter,
- }
- }
- func (p *actorPlayer) OnInit() {
- p.initRateLimits()
- p.initRemote()
- p.initPlayerLeague()
- p.initMap()
- p.initFacility()
- p.initPlayerTeam()
- p.initConscript()
- p.initQuest()
- p.initBattle()
- p.initAsset()
- p.initHero()
- p.initAssemble()
- p.initShop()
- p.initExchange()
- p.initShow()
- p.initPlayerStats()
- p.initSignIn()
- p.initSeason()
- p.initEvent()
- }
- func (p *actorPlayer) initRemote() {
- p.Remote().Register(nameRemote.MapPlayer_OnSessionClosed, p.onSessionClosed)
- p.Remote().Register(nameRemote.MapPlayer_OnCheckExit, p.onCheckExit)
- p.Remote().Register(nameRemote.MapPlayer_SyncData, p.syncData)
- p.Remote().Register(nameRemote.MapPlayer_SyncVip, p.syncVipAttrs)
- }
- func (p *actorPlayer) OnStop() {
- p.Info("[actorPlayer] OnStop() playerID = %d", p.playerID)
- p.Timer().RemoveAll()
- p.ActorLogger.Destory()
- }
- func (p *actorPlayer) OnLocalReceived(m *cfacade.Message) (bool, bool) {
- // 玩家未登录时,第一条消息必须是 map.player.login
- if !p.isOnline && m.FuncName != nameLocal.MapPlayer_Login {
- p.ResponseCode(m.Session, code.PlayerNotLogin)
- return false, false
- }
- p.funcErrCode = p.funcLimiter.Check(m.BuildTime, m.FuncName)
- if code.IsFail(p.funcErrCode) {
- p.ResponseCode(m.Session, p.funcErrCode)
- return false, false
- }
- return false, true
- }
- func (p *actorPlayer) OnRemoteReceived(m *cfacade.Message) (bool, bool) {
- if p.playerID == 0 {
- p.Warn("[OnRemoteReceive] player not found: Source = %s, Target = %s, FuncName = %s", m.Source, m.Target, m.FuncName)
- return false, false
- }
- // 如果找不到玩家表,直接返回错误
- if db.GetMapPlayerTable(p.playerID) == nil {
- p.Warn("[OnRemoteReceive] player not found: Source = %s, Target = %s, FuncName = %s", m.Source, m.Target, m.FuncName)
- return false, false
- }
- return false, true
- }
- func (p *actorPlayer) updateNowTime() {
- now := ctime.Now()
- p.now = &now
- }
- func (p *actorPlayer) initRateLimits() {
- p.funcLimiter.Add(nameLocal.MapPlayer_March, 1000, 10, code.OperationTooFast)
- p.funcLimiter.Add(nameLocal.MapPlayer_MarchStop, 1000, 10, code.OperationTooFast)
- p.funcLimiter.Add(nameLocal.MapPlayer_Retreat, 1000, 10, code.OperationTooFast)
- p.funcLimiter.Add(nameLocal.MapPlayer_Assemble, 1000, 10, code.OperationTooFast)
- p.funcLimiter.Add(nameLocal.MapPlayer_AssembleJoin, 1000, 10, code.OperationTooFast)
- p.funcLimiter.Add(nameLocal.MapPlayer_FindPath, 1000, 10, code.OperationTooFast)
- p.funcLimiter.Add(nameLocal.MapPlayer_MapObjectPosition, 1000, 10, code.OperationTooFast)
- }
- func (p *actorPlayer) EventRegister(name string, fn cherryActor.IEventFunc) {
- p.Event().Register(name, fn, p.playerID)
- }
- // 同步玩家数据
- func (p *actorPlayer) syncData(req *pb.SyncMapPlayerRequest) {
- p.Debug("sync player data: req = %+v", req)
- playerTable := db.GetMapPlayerTable(p.playerID)
- // 同步必要的数据
- playerTable.SyncData(req)
- // 抛事件
- p.PostEvent(event.NewMapWatcherSync(p.playerID, &event.MapWatcherData{
- PlayerID: p.playerID,
- PlayerName: req.PlayerName,
- IconID: req.IconID,
- FrameID: req.FrameID,
- }))
- }
- // 同步vip属性
- func (p *actorPlayer) syncVipAttrs(req *pb.SyncMapPlayerVip) {
- p.Debug("sync player vip attrs: req = %+v", req)
- playerTable := db.GetMapPlayerTable(p.playerID)
- vipAttrs := types.NewAttrs()
- for _, attr := range req.Attrs.List {
- vipAttrs.Set(attr.Key, attr.Value)
- }
- playerTable.SyncVip(req.Level, vipAttrs, req.ExpireTime)
- // 抛事件
- p.PostEvent(event.NewVipActive(p.playerID, vipAttrs, req.ExpireTime))
- }
- func (p *actorPlayer) onSessionClosed() {
- p.Info("[onLogout] playerID = %d", p.playerID)
- // 不在线则忽略
- if !p.isOnline {
- return
- }
- // 必需设置为 false,如果玩家被顶号,actor 不会被销毁,不设置会导致玩家无法登录
- p.isOnline = false
- //移除当前玩家所有定时器
- p.Timer().RemoveAll()
- if playerTable := db.GetMapPlayerTable(p.playerID); playerTable != nil {
- if playerTable.ObjectID > 0 {
- mapCall.AOI.Leave(playerTable.ObjectID, enum.ObjectType_Player)
- }
- mapFacade.ServiceOnLogout(playerTable)
- playerTable.Save2Queue()
- }
- p.Info("[onLogout] finished! playerID = %d", p.playerID)
- }
- // 父actor检测到当前子actor很久收到消息,确认是否要退出
- func (p *actorPlayer) onCheckExit() {
- // 不在线则销毁当前actor
- if !p.isOnline {
- p.Exit()
- }
- }
|