127 lines
4.5 KiB
Go
127 lines
4.5 KiB
Go
package service
|
|
|
|
import (
|
|
"context"
|
|
"time"
|
|
|
|
roomeventsv1 "hyapp.local/api/proto/events/room/v1"
|
|
roomv1 "hyapp.local/api/proto/room/v1"
|
|
"hyapp/pkg/tencentim"
|
|
"hyapp/pkg/xerr"
|
|
"hyapp/services/room-service/internal/room/command"
|
|
"hyapp/services/room-service/internal/room/outbox"
|
|
"hyapp/services/room-service/internal/room/rank"
|
|
"hyapp/services/room-service/internal/room/state"
|
|
)
|
|
|
|
// RobotMicUpInput 是内部机器人编排器占麦输入;调用方必须只传 robot-service 登记过的机器人用户。
|
|
type RobotMicUpInput struct {
|
|
Meta *roomv1.RequestMeta
|
|
TargetUserID int64
|
|
SeatNo int32
|
|
}
|
|
|
|
// RobotVirtualMicUp 把机器人放到静音虚拟麦位,不要求真实 RTC 推流。
|
|
func (s *Service) RobotVirtualMicUp(ctx context.Context, input RobotMicUpInput) (*roomv1.MicUpResponse, error) {
|
|
ctx = contextFromMeta(ctx, input.Meta)
|
|
cmd := command.RobotMicUp{
|
|
Base: baseFromMeta(input.Meta),
|
|
TargetUserID: input.TargetUserID,
|
|
SeatNo: input.SeatNo,
|
|
}
|
|
if cmd.TargetUserID <= 0 {
|
|
cmd.TargetUserID = cmd.ActorUserID()
|
|
}
|
|
cmd.MicSessionID = micSessionIDForCommand(cmd.RoomID(), cmd.ID())
|
|
|
|
result, err := s.mutateRoom(ctx, cmd, true, func(now time.Time, current *state.RoomState, _ *rank.LocalRank) (mutationResult, []outbox.Record, error) {
|
|
if err := requireActiveRoom(current); err != nil {
|
|
return mutationResult{}, nil, err
|
|
}
|
|
if _, exists := current.OnlineUsers[cmd.TargetUserID]; !exists {
|
|
return mutationResult{}, nil, xerr.New(xerr.NotFound, "robot not in room")
|
|
}
|
|
if _, exists := current.SeatByUser(cmd.TargetUserID); exists {
|
|
return mutationResult{}, nil, xerr.New(xerr.Conflict, "robot already on seat")
|
|
}
|
|
index := current.SeatIndex(cmd.SeatNo)
|
|
if index < 0 {
|
|
return mutationResult{}, nil, xerr.New(xerr.InvalidArgument, "seat does not exist")
|
|
}
|
|
if current.MicSeats[index].Locked {
|
|
return mutationResult{}, nil, xerr.New(xerr.PermissionDenied, "seat is locked")
|
|
}
|
|
if current.MicSeats[index].UserID != 0 {
|
|
return mutationResult{}, nil, xerr.New(xerr.Conflict, "seat is occupied")
|
|
}
|
|
|
|
current.Version++
|
|
current.MicSeats[index].UserID = cmd.TargetUserID
|
|
current.MicSeats[index].PublishState = state.MicPublishPublishing
|
|
current.MicSeats[index].MicSessionID = cmd.MicSessionID
|
|
current.MicSeats[index].PublishDeadlineMS = 0
|
|
current.MicSeats[index].MicSessionRoomVersion = current.Version
|
|
current.MicSeats[index].LastPublishEventTimeMS = now.UnixMilli()
|
|
current.MicSeats[index].MicHeartbeatAtMS = now.UnixMilli()
|
|
current.MicSeats[index].MicMuted = true
|
|
seatStatus := current.MicSeats[index].SeatStatus()
|
|
targetGiftValue := roomUserGiftValue(current, cmd.TargetUserID)
|
|
|
|
micEvent, err := outbox.Build(current.RoomID, "RoomMicChanged", current.Version, now, &roomeventsv1.RoomMicChanged{
|
|
ActorUserId: cmd.ActorUserID(),
|
|
TargetUserId: cmd.TargetUserID,
|
|
FromSeat: 0,
|
|
ToSeat: cmd.SeatNo,
|
|
Action: "robot_up",
|
|
MicSessionId: cmd.MicSessionID,
|
|
PublishState: state.MicPublishPublishing,
|
|
PublishDeadlineMs: 0,
|
|
SeatStatus: seatStatus,
|
|
TargetGiftValue: targetGiftValue,
|
|
})
|
|
if err != nil {
|
|
return mutationResult{}, nil, err
|
|
}
|
|
|
|
return mutationResult{
|
|
snapshot: current.ToProto(),
|
|
seatNo: cmd.SeatNo,
|
|
micSessionID: cmd.MicSessionID,
|
|
publishDeadlineMS: 0,
|
|
syncEvent: &tencentim.RoomEvent{
|
|
EventID: micEvent.EventID,
|
|
RoomID: current.RoomID,
|
|
EventType: "room_mic_publish_confirmed",
|
|
ActorUserID: cmd.ActorUserID(),
|
|
TargetUserID: cmd.TargetUserID,
|
|
SeatNo: cmd.SeatNo,
|
|
RoomVersion: current.Version,
|
|
Attributes: map[string]string{
|
|
"action": "robot_up",
|
|
"publish_state": state.MicPublishPublishing,
|
|
"mic_session_id": cmd.MicSessionID,
|
|
"seat_status": seatStatus,
|
|
"mic_muted": "true",
|
|
"target_gift_value": int64String(targetGiftValue),
|
|
},
|
|
},
|
|
}, []outbox.Record{micEvent}, nil
|
|
})
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
if result.micSessionID == "" {
|
|
if seat := protoSeatByUser(result.snapshot, cmd.TargetUserID); seat != nil {
|
|
result.seatNo = seat.GetSeatNo()
|
|
result.micSessionID = seat.GetMicSessionId()
|
|
}
|
|
}
|
|
return &roomv1.MicUpResponse{
|
|
Result: commandResult(result.applied, result.snapshot.GetVersion(), s.clock.Now()),
|
|
SeatNo: result.seatNo,
|
|
Room: result.snapshot,
|
|
MicSessionId: result.micSessionID,
|
|
PublishDeadlineMs: 0,
|
|
}, nil
|
|
}
|