package play import ( "context" "game-driver/internal/middleware" "game-driver/internal/schema" "game-driver/leaf" "game-driver/pkg/card_reader" "game-driver/pkg/channel" "game-driver/pkg/tts" "go.uber.org/zap" "sync" "time" ) func WaitCard(ctx context.Context) leaf.HandlerFunc { reader, err := card_reader.NewReader("rtu:///dev/ttyUSB0") if err != nil { zap.S().Panicln("读卡器串口连接失败", err) } go func() { <-ctx.Done() _ = reader.Close() }() err = reader.Init() if err != nil { zap.S().Panicln("读卡器初始化失败", err) } return func(c *leaf.Context) { payload := leaf.Value[*schema.PlayModal](c, middleware.PayloadJSONKey) // 读取卡片等待时间 var waitCard time.Duration if a, ok := payload.Game["wait_card"]; ok { if v, ok := a.(float64); ok { waitCard = time.Duration(v) } } // 卡片ID预期值 var cardId string if a, ok := payload.Game["card_id"]; ok { if v, ok := a.(string); ok { cardId = v } } // 卡片比对成功语音内容 var cardOk string if a, ok := payload.Game["card_ok"]; ok { if v, ok := a.(string); ok { cardOk = v } } // 卡片比对失败语音内容 var cardError string if a, ok := payload.Game["card_error"]; ok { if v, ok := a.(string); ok { cardError = v } } // 等待组 var wait sync.WaitGroup defer wait.Wait() // 卡片信息通道 cardInfo := channel.NewClosed[string]() defer cardInfo.Close() // 结束信号通道 cc, cancel := context.WithCancel(context.TODO()) defer cancel() wait.Add(1) go func() { defer wait.Done() reader.OnCardInfo(cc, func(info card_reader.CardInfo) { cardInfo.Send(info.ID) }) }() // 多次读取,直到读取到正确的卡片 for isNeed := true; isNeed; { isNeed = false select { case <-c.Done(): case <-time.After(waitCard * time.Second): case id, ok := <-cardInfo.Data(): // 等待卡片插入 if ok { // 非关闭信号 // 比对卡号是否正确,不正确则重新读取 if cardId != id { zap.S().Infof("读取到卡片数据%q,与预期卡片数据%q不一致", id, cardId) // 播报错误提示 tts.DefaultTTS.Sound(cardError) isNeed = true break } // 播报恭喜语音 tts.DefaultTTS.Sound(cardOk) //TODO: 打开炫酷光效 zap.S().Infof("读取到卡片数据%q,开始打开炫酷光效", id) Default(c) } } } } }