207 lines
4.3 KiB
Go
207 lines
4.3 KiB
Go
|
|
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
|
||
|
|
}
|