Files
cellbot/internal/protocol/bot.go

207 lines
4.3 KiB
Go
Raw Normal View History

package protocol
import (
"context"
"sync"
"go.uber.org/zap"
)
// BaseBotInstance 机器人实例基类
type BaseBotInstance struct {
id string
protocol Protocol
status BotStatus
logger *zap.Logger
mu sync.RWMutex
}
// NewBaseBotInstance 创建机器人实例基类
func NewBaseBotInstance(id string, protocol Protocol, logger *zap.Logger) *BaseBotInstance {
return &BaseBotInstance{
id: id,
protocol: protocol,
status: BotStatusStopped,
logger: logger.With(zap.String("bot_id", id)),
}
}
// GetID 获取实例ID
func (b *BaseBotInstance) GetID() string {
return b.id
}
// Name 获取协议名称
func (b *BaseBotInstance) Name() string {
return b.protocol.Name()
}
// Version 获取协议版本
func (b *BaseBotInstance) Version() string {
return b.protocol.Version()
}
// Connect 建立连接
func (b *BaseBotInstance) Connect(ctx context.Context) error {
b.mu.Lock()
b.status = BotStatusStarting
b.mu.Unlock()
if err := b.protocol.Connect(ctx); err != nil {
b.mu.Lock()
b.status = BotStatusError
b.mu.Unlock()
return err
}
b.mu.Lock()
b.status = BotStatusRunning
b.mu.Unlock()
b.logger.Info("Bot instance connected")
return nil
}
// Disconnect 断开连接
func (b *BaseBotInstance) Disconnect(ctx context.Context) error {
b.mu.Lock()
b.status = BotStatusStopping
b.mu.Unlock()
if err := b.protocol.Disconnect(ctx); err != nil {
b.mu.Lock()
b.status = BotStatusError
b.mu.Unlock()
return err
}
b.mu.Lock()
b.status = BotStatusStopped
b.mu.Unlock()
b.logger.Info("Bot instance disconnected")
return nil
}
// IsConnected 检查连接状态
func (b *BaseBotInstance) IsConnected() bool {
b.mu.RLock()
defer b.mu.RUnlock()
return b.status == BotStatusRunning
}
// SendAction 发送动作
func (b *BaseBotInstance) SendAction(ctx context.Context, action Action) (map[string]interface{}, error) {
return b.protocol.SendAction(ctx, action)
}
// HandleEvent 处理事件
func (b *BaseBotInstance) HandleEvent(ctx context.Context, event Event) error {
return b.protocol.HandleEvent(ctx, event)
}
// GetSelfID 获取机器人自身ID
func (b *BaseBotInstance) GetSelfID() string {
return b.protocol.GetSelfID()
}
// Start 启动实例
func (b *BaseBotInstance) Start(ctx context.Context) error {
return b.Connect(ctx)
}
// Stop 停止实例
func (b *BaseBotInstance) Stop(ctx context.Context) error {
return b.Disconnect(ctx)
}
// GetStatus 获取实例状态
func (b *BaseBotInstance) GetStatus() BotStatus {
b.mu.RLock()
defer b.mu.RUnlock()
return b.status
}
// BotManager 机器人管理器
type BotManager struct {
bots map[string]BotInstance
logger *zap.Logger
mu sync.RWMutex
}
// NewBotManager 创建机器人管理器
func NewBotManager(logger *zap.Logger) *BotManager {
return &BotManager{
bots: make(map[string]BotInstance),
logger: logger,
}
}
// Add 添加机器人实例
func (bm *BotManager) Add(bot BotInstance) {
bm.mu.Lock()
defer bm.mu.Unlock()
bm.bots[bot.GetID()] = bot
bm.logger.Info("Bot added", zap.String("bot_id", bot.GetID()))
}
// Remove 移除机器人实例
func (bm *BotManager) Remove(id string) {
bm.mu.Lock()
defer bm.mu.Unlock()
if bot, ok := bm.bots[id]; ok {
bot.Stop(context.Background())
delete(bm.bots, id)
bm.logger.Info("Bot removed", zap.String("bot_id", id))
}
}
// Get 获取机器人实例
func (bm *BotManager) Get(id string) (BotInstance, bool) {
bm.mu.RLock()
defer bm.mu.RUnlock()
bot, ok := bm.bots[id]
return bot, ok
}
// GetAll 获取所有机器人实例
func (bm *BotManager) GetAll() []BotInstance {
bm.mu.RLock()
defer bm.mu.RUnlock()
bots := make([]BotInstance, 0, len(bm.bots))
for _, bot := range bm.bots {
bots = append(bots, bot)
}
return bots
}
// StartAll 启动所有机器人
func (bm *BotManager) StartAll(ctx context.Context) error {
bm.mu.RLock()
defer bm.mu.RUnlock()
for _, bot := range bm.bots {
if err := bot.Start(ctx); err != nil {
bm.logger.Error("Failed to start bot",
zap.String("bot_id", bot.GetID()),
zap.Error(err))
}
}
return nil
}
// StopAll 停止所有机器人
func (bm *BotManager) StopAll(ctx context.Context) error {
bm.mu.RLock()
defer bm.mu.RUnlock()
for _, bot := range bm.bots {
if err := bot.Stop(ctx); err != nil {
bm.logger.Error("Failed to stop bot",
zap.String("bot_id", bot.GetID()),
zap.Error(err))
}
}
return nil
}