feat(player): 添加玩家登录状态检查和等待机制

- 在 Player 结构中添加登录状态标志和登录完成通知通道
- 实现 IsLoggedIn、WaitForLogin、WaitForLoginWithTimeout 和 WaitForLoginWithCtx 方法
- 在登录逻辑中使用 CompleteLogin 标记登录完成并通知等待者
- 在控制器中添加登录状态检查,确保处理已登录玩家的请求
This commit is contained in:
2025-07-17 06:09:52 +08:00
parent bf72b91fc6
commit 84d6d99356
7 changed files with 164 additions and 19 deletions

View File

@@ -2,6 +2,10 @@ package entity
import (
"blazing/cool"
"context"
"fmt"
"sync"
"time"
"github.com/panjf2000/gnet/v2"
)
@@ -10,7 +14,9 @@ type Player struct {
MainConn Conn
UserID uint32 //用户ID
IsLogin bool //是否登录 //TODO 待实现登录包为第一个包,后续再发其他的包
mu sync.Mutex
loginChan chan struct{} // 登录完成通知通道
}
// PlayerOption 定义配置 Player 的函数类型
@@ -30,7 +36,9 @@ func WithConn(c gnet.Conn) PlayerOption {
// NewPlayer 使用 Options 模式创建 Player 实例
func NewPlayer(opts ...PlayerOption) *Player {
p := &Player{}
p := &Player{
loginChan: make(chan struct{}),
}
for _, opt := range opts {
opt(p)
}
@@ -56,3 +64,64 @@ func ConutPlayer() int {
return count
//fmt.Println("元素数量:", count) // 输出: 3
}
// IsLoggedIn 检查是否已登录
func (lw *Player) IsLoggedIn() bool {
lw.mu.Lock()
defer lw.mu.Unlock()
return lw.IsLogin
}
// WaitForLogin 等待登录完成,无超时
func (lw *Player) WaitForLogin() error {
if lw.IsLoggedIn() {
return nil
}
// 阻塞等待登录完成
<-lw.loginChan
return nil
}
// WaitForLoginWithTimeout 带超时的登录等待
func (lw *Player) WaitForLoginWithTimeout(timeout time.Duration) error {
if lw.IsLoggedIn() {
return nil
}
// 使用定时器实现超时
timer := time.NewTimer(timeout)
defer timer.Stop()
select {
case <-lw.loginChan:
return nil
case <-timer.C:
return fmt.Errorf("登录等待超时: %v", timeout)
}
}
// WaitForLoginWithCtx 带上下文的登录等待
func (lw *Player) WaitForLoginWithCtx(ctx context.Context) error {
if lw.IsLoggedIn() {
return nil
}
select {
case <-lw.loginChan:
return nil
case <-ctx.Done():
return ctx.Err() // 上下文取消或超时
}
}
// CompleteLogin 标记登录完成并通知等待者
func (lw *Player) CompleteLogin() {
lw.mu.Lock()
defer lw.mu.Unlock()
if !lw.IsLogin {
lw.IsLogin = true
close(lw.loginChan) // 关闭通道以通知所有等待者
}
}