From bbe1228821d1b12b9e38e387966ebdc3366fbaa8 Mon Sep 17 00:00:00 2001 From: Fedorov Vladimir Date: Wed, 16 Sep 2026 19:02:22 +0700 Subject: [PATCH] add map --- internal/app/game_map.go | 94 ++++++++++++++++++++++++++++++++++++++++ internal/app/server.go | 82 ----------------------------------- 2 files changed, 94 insertions(+), 82 deletions(-) create mode 100644 internal/app/game_map.go diff --git a/internal/app/game_map.go b/internal/app/game_map.go new file mode 100644 index 0000000..4dcc6eb --- /dev/null +++ b/internal/app/game_map.go @@ -0,0 +1,94 @@ +package app + +import ( + "context" + "errors" + + "evening_detective_server/internal/repos/game_map_repo" + proto "evening_detective_server/proto" + + "google.golang.org/grpc/codes" + "google.golang.org/grpc/status" +) + +func (s *server) GetGameMap(ctx context.Context, req *proto.GetGameMapReq) (*proto.GetGameMapRsp, error) { + if !canManageScreens(ctx) { + return nil, status.Error(codes.PermissionDenied, "permission denied") + } + if req == nil || req.GameId <= 0 { + return nil, status.Error(codes.InvalidArgument, "некорректный идентификатор игры") + } + game, err := s.gameService.GetFullGame(ctx, int(req.GameId)) + if err != nil { + return nil, status.Error(codes.NotFound, "игра не найдена") + } + for _, team := range game.Teams { + if team.ParticipationStatus == "cancelled" { + continue + } + if err := s.mapRepo.Ensure(ctx, int(req.GameId), "team", team.ID); err != nil { + return nil, status.Error(codes.Internal, "не удалось сохранить карту") + } + } + screens, err := s.screenRepo.ListByGame(ctx, int(req.GameId)) + if err != nil { + return nil, status.Error(codes.Internal, "не удалось получить экраны") + } + for _, screen := range screens { + if err := s.mapRepo.Ensure(ctx, int(req.GameId), "screen", screen.ID); err != nil { + return nil, status.Error(codes.Internal, "не удалось сохранить карту") + } + } + items, err := s.mapRepo.List(ctx, int(req.GameId)) + if err != nil { + return nil, status.Error(codes.Internal, "не удалось получить карту") + } + teamNames := map[int]string{} + for _, team := range game.Teams { + if team.ParticipationStatus == "cancelled" { + continue + } + teamNames[team.ID] = team.Name + } + screenStates := map[int]*proto.ScreenState{} + for _, screen := range screens { + screenStates[screen.ID] = screenState(screen) + } + result := make([]*proto.MapItem, 0, len(items)) + for _, item := range items { + _, teamExists := teamNames[item.ItemID] + if (item.Kind == "team" && !teamExists) || (item.Kind == "screen" && screenStates[item.ItemID] == nil) { + if err := s.mapRepo.Delete(ctx, item); err != nil { + return nil, status.Error(codes.Internal, "не удалось обновить карту") + } + continue + } + mapped := &proto.MapItem{Kind: item.Kind, ItemId: int32(item.ItemID), X: int32(item.X), Y: int32(item.Y), Hidden: item.Hidden} + if item.Kind == "team" { + mapped.Label = teamNames[item.ItemID] + } + if state := screenStates[item.ItemID]; item.Kind == "screen" && state != nil { + mapped.Label = "Экран " + state.Id + mapped.Status = state.Status + mapped.SoundEnabled = state.SoundEnabled + } + result = append(result, mapped) + } + return &proto.GetGameMapRsp{Items: result}, nil +} + +func (s *server) UpdateGameMapItem(ctx context.Context, req *proto.UpdateGameMapItemReq) (*proto.UpdateGameMapItemRsp, error) { + if !canManageScreens(ctx) { + return nil, status.Error(codes.PermissionDenied, "permission denied") + } + if req == nil || req.GameId <= 0 || req.ItemId <= 0 || (req.Kind != "team" && req.Kind != "screen") { + return nil, status.Error(codes.InvalidArgument, "некорректный объект карты") + } + if err := s.mapRepo.Update(ctx, game_map_repo.Item{GameID: int(req.GameId), Kind: req.Kind, ItemID: int(req.ItemId), X: int(req.X), Y: int(req.Y), Hidden: req.Hidden}); err != nil { + if errors.Is(err, game_map_repo.ErrItemNotFound) { + return nil, status.Error(codes.NotFound, "объект карты не найден") + } + return nil, status.Error(codes.Internal, "не удалось изменить карту") + } + return &proto.UpdateGameMapItemRsp{}, nil +} diff --git a/internal/app/server.go b/internal/app/server.go index fbf23b3..5b64ecb 100644 --- a/internal/app/server.go +++ b/internal/app/server.go @@ -66,88 +66,6 @@ func NewServer( } } -func (s *server) GetGameMap(ctx context.Context, req *proto.GetGameMapReq) (*proto.GetGameMapRsp, error) { - if !canManageScreens(ctx) { - return nil, status.Error(codes.PermissionDenied, "permission denied") - } - if req == nil || req.GameId <= 0 { - return nil, status.Error(codes.InvalidArgument, "некорректный идентификатор игры") - } - game, err := s.gameService.GetFullGame(ctx, int(req.GameId)) - if err != nil { - return nil, status.Error(codes.NotFound, "игра не найдена") - } - for _, team := range game.Teams { - if team.ParticipationStatus == "cancelled" { - continue - } - if err := s.mapRepo.Ensure(ctx, int(req.GameId), "team", team.ID); err != nil { - return nil, status.Error(codes.Internal, "не удалось сохранить карту") - } - } - screens, err := s.screenRepo.ListByGame(ctx, int(req.GameId)) - if err != nil { - return nil, status.Error(codes.Internal, "не удалось получить экраны") - } - for _, screen := range screens { - if err := s.mapRepo.Ensure(ctx, int(req.GameId), "screen", screen.ID); err != nil { - return nil, status.Error(codes.Internal, "не удалось сохранить карту") - } - } - items, err := s.mapRepo.List(ctx, int(req.GameId)) - if err != nil { - return nil, status.Error(codes.Internal, "не удалось получить карту") - } - teamNames := map[int]string{} - for _, team := range game.Teams { - if team.ParticipationStatus == "cancelled" { - continue - } - teamNames[team.ID] = team.Name - } - screenStates := map[int]*proto.ScreenState{} - for _, screen := range screens { - screenStates[screen.ID] = screenState(screen) - } - result := make([]*proto.MapItem, 0, len(items)) - for _, item := range items { - _, teamExists := teamNames[item.ItemID] - if (item.Kind == "team" && !teamExists) || (item.Kind == "screen" && screenStates[item.ItemID] == nil) { - if err := s.mapRepo.Delete(ctx, item); err != nil { - return nil, status.Error(codes.Internal, "не удалось обновить карту") - } - continue - } - mapped := &proto.MapItem{Kind: item.Kind, ItemId: int32(item.ItemID), X: int32(item.X), Y: int32(item.Y), Hidden: item.Hidden} - if item.Kind == "team" { - mapped.Label = teamNames[item.ItemID] - } - if state := screenStates[item.ItemID]; item.Kind == "screen" && state != nil { - mapped.Label = "Экран " + state.Id - mapped.Status = state.Status - mapped.SoundEnabled = state.SoundEnabled - } - result = append(result, mapped) - } - return &proto.GetGameMapRsp{Items: result}, nil -} - -func (s *server) UpdateGameMapItem(ctx context.Context, req *proto.UpdateGameMapItemReq) (*proto.UpdateGameMapItemRsp, error) { - if !canManageScreens(ctx) { - return nil, status.Error(codes.PermissionDenied, "permission denied") - } - if req == nil || req.GameId <= 0 || req.ItemId <= 0 || (req.Kind != "team" && req.Kind != "screen") { - return nil, status.Error(codes.InvalidArgument, "некорректный объект карты") - } - if err := s.mapRepo.Update(ctx, game_map_repo.Item{GameID: int(req.GameId), Kind: req.Kind, ItemID: int(req.ItemId), X: int(req.X), Y: int(req.Y), Hidden: req.Hidden}); err != nil { - if errors.Is(err, game_map_repo.ErrItemNotFound) { - return nil, status.Error(codes.NotFound, "объект карты не найден") - } - return nil, status.Error(codes.Internal, "не удалось изменить карту") - } - return &proto.UpdateGameMapItemRsp{}, nil -} - func (s *server) Ping(_ context.Context, _ *proto.PingReq) (*proto.PingRsp, error) { return &proto.PingRsp{}, nil }