package player import ( nameActor "f1-game/internal/name/actor" nameRemote "f1-game/internal/name/remote" "f1-game/internal/sessions" "f1-game/nodes/game/internal/db" "time" cstring "github.com/cherry-game/cherry/extend/string" cfacade "github.com/cherry-game/cherry/facade" clog "github.com/cherry-game/cherry/logger" cactor "github.com/cherry-game/cherry/net/actor" ) // actor 玩家管理 type actor struct { cactor.Base cleanChildTime time.Duration } func NewActor() *actor { return &actor{ cleanChildTime: 10 * time.Minute, } } func (p *actor) AliasID() string { return nameActor.GamePlayer } func (p *actor) OnInit() { p.Timer().Add(p.cleanChildTime, p.cleanChildTimer) } func (p *actor) OnLocalReceived(m *cfacade.Message) (bool, bool) { playerID := m.Session.GetString(sessions.PlayerID) if playerID == "" { clog.Warnf("[OnLocalReceived] player not found. m = %+v", m) return false, false } if child, found := p.Child().Get(playerID); found { child.PostLocal(m) } return false, false } func (p *actor) OnRemoteReceived(m *cfacade.Message) (next bool, invoke bool) { if m.TargetPath().IsParent() { // 不拦截父actor的remote消息 return true, false } childID := m.TargetPath().ChildID playerID, ok := cstring.ToInt64(childID) if !ok { return false, false } if m.FuncName != nameRemote.Player_OnEnter { if _, found := db.GetPlayerTable(playerID); !found { clog.Warnf("player table not found. [playerID = %d, target = %s]", playerID, m.Target) return false, false } } return true, false } func (p *actor) OnFindChild(m *cfacade.Message) (cfacade.IActor, bool) { childID := m.TargetPath().ChildID playerID, ok := cstring.ToInt64(childID) if !ok { return nil, false } childPlayer := newActorPlayer(playerID) childActor, err := p.Child().Create(childID, &childPlayer) if err != nil { return nil, false } clog.Debugf("[actor] create child. actorID = %s, targetPath = %v", childActor.ActorID(), m.TargetPath(), ) return childActor, true } // cleanChildTimer 定期清理actorPlayer func (p *actor) cleanChildTimer() { // 玩家已下线,并且超过childExitTime时间没有收发消息,则退出actor //deadline := ctime.Now().Add(-p.cleanChildTime).Unix() deadline := time.Now().Add(-p.cleanChildTime).Unix() p.Child().Each(func(iActor cfacade.IActor) { if iActor.LastAt() < deadline { p.Call(iActor.Path().String(), nameRemote.Player_OnCheckExit, nil) } }) }