using Asp.Versioning; using MetaAssets; using Microsoft.AspNetCore.Http; using Microsoft.AspNetCore.Mvc; using StackExchange.Redis; using UGQDataAccess.Repository; using UGQDataAccess.Service; using ServerCommon.UGQ.Models; using System.Globalization; using MongoDB.Driver.Linq; using UGQApiServer.Converter; using UGQDataAccess; using ServerCommon.UGQ; using UGQDatabase.Models; using Amazon.Runtime.Internal; using System.Security.Principal; using Amazon.S3.Model; using Microsoft.Extensions.Caching.Distributed; using ServerCommon.BusinessLogDomain; using ServerCommon; namespace UGQApiServer.Controllers { [ApiController] [ApiVersion("1.0")] [ApiExplorerSettings(GroupName = "ingame")] [Route("api/v{version:apiVersion}/[controller]")] [UGQInGameApi] public class InGameController : ControllerBase { InGameService _inGameService; IConnectionMultiplexer _redis; public InGameController(InGameService inGameService, IConnectionMultiplexer redis) { _inGameService = inGameService; _redis = redis; } /// /// userGuid의 UGQ 계정 정보 얻기 /// [HttpGet] [Route("account/{userGuid}")] public async Task getAccount(string userGuid) { (ServerErrorCode errorCode, var accountEntity) = await _inGameService.getAccount(userGuid); if (errorCode != ServerErrorCode.Success) return Results.BadRequest(ApiResponseFactory.error(errorCode)); if (accountEntity == null) return Results.BadRequest(ApiResponseFactory.error(ServerErrorCode.UgqNullEntity)); return Results.Ok(new UgqAccount { GradeType = accountEntity.GradeType, CreatorPoint = accountEntity.CreatorPoint, }); } /// /// 직접 작성한 퀘스트를 수락해서 완료까지 진행해보기 위해서 Test 상태인 퀘스트 리스트 /// [HttpGet] [Route("user-quests-in-test-state/{userGuid}")] public async Task getUserQuestsInTestState(string userGuid) { var result = await _inGameService.getUserQuests(userGuid, [QuestContentState.Test]); LangEnum langEnum = Culture.ToLangEnum(CultureInfo.CurrentCulture.Name); return Results.Ok(result.Select(x => x.ToProtoUgqQuestInTestState(langEnum, ImageUrlType.BannerImg)).ToList()); } /// /// userGuid가 작성해서 Live 상태로 보낸 퀘스트 리스트 /// [HttpGet] [Route("quest-board/{userGuid}")] public async Task getUserQuestBoard(string userGuid, [FromQuery] UgqQuestBoardRequest request) { int pageSize = Math.Clamp(request.PageSize, 1, UGQConstants.MAX_INPUT_PAGE_SIZE); var result = await _inGameService.getQuestBoard(userGuid, request, pageSize); LangEnum langEnum = Culture.ToLangEnum(CultureInfo.CurrentCulture.Name); return Results.Ok(result.ToProto(langEnum, ImageUrlType.BannerImg)); } /// /// 전체 Live 상태인 퀘스트 리스트 /// [HttpGet] [Route("quest-board")] public async Task getQuestBoard([FromQuery] UgqQuestBoardRequest request) { int pageSize = Math.Clamp(request.PageSize, 1, UGQConstants.MAX_INPUT_PAGE_SIZE); var result = await _inGameService.getQuestBoard(null, request, pageSize); LangEnum langEnum = Culture.ToLangEnum(CultureInfo.CurrentCulture.Name); return Results.Ok(result.ToProto(langEnum, ImageUrlType.BannerImg)); } /// /// userGuid가 북마크한 Live 상태 퀘스트 리스트 /// [HttpGet] [Route("bookmark-quest-board/{userGuid}")] public async Task getBookmarkQuestBoard(string userGuid, [FromQuery] UgqQuestBoardRequest request) { int pageSize = Math.Clamp(request.PageSize, 1, UGQConstants.MAX_INPUT_PAGE_SIZE); var result = await _inGameService.getBookmarkQuests(userGuid, request, pageSize); LangEnum langEnum = Culture.ToLangEnum(CultureInfo.CurrentCulture.Name); return Results.Ok(result.ToProto(langEnum, ImageUrlType.BannerImg)); } /// /// 퀘스트 스포트라이트 /// [HttpGet] [Route("quest-board-spotlight")] public async Task getQuestBoardSpotlight() { var result = await _inGameService.getQuestBoardSpotlight(); LangEnum langEnum = Culture.ToLangEnum(CultureInfo.CurrentCulture.Name); return Results.Ok(result.ToProto(langEnum, ImageUrlType.TitleImg)); } /// /// 퀘스트 자세한 정보 /// [HttpGet] [Route("quest-board-detail/{userGuid}")] public async Task getQuestBoardDetail(string userGuid, [FromQuery] UgqQuestIdRevisionRequest request) { var result = await _inGameService.getQuestBoardDetail(userGuid, request.QuestId, request.Revision); if (result == null) return Results.BadRequest(ApiResponseFactory.error(ServerErrorCode.UgqNullEntity)); LangEnum langEnum = Culture.ToLangEnum(CultureInfo.CurrentCulture.Name); return Results.Ok(result.ToProto(langEnum, ImageUrlType.BannerImg)); } /// /// Test 상태인 퀘스트를 정상적으로 완료시켰을 때 호출해서 Standby 상태로 변경 /// [HttpPost] [Route("set-test-completed/{userGuid}")] public async Task setTestCompleted(string userGuid, [FromQuery] long questId, [FromQuery] long revision) { // 여기에서만 Test -> Standby 가능 (var errorCode, var updated) = await _inGameService.changeQuestStateForInGame(userGuid, questId, revision, [QuestContentState.Test], QuestContentState.Standby); if (errorCode != ServerErrorCode.Success) return Results.BadRequest(ApiResponseFactory.error(errorCode)); return Results.Ok(); } /// /// Test 상태인 퀘스트를 포기했을 때 호출해서 Editable 상태로 변경 /// [HttpPost] [Route("set-test-aborted/{userGuid}")] public async Task setTestAborted(string userGuid, [FromQuery] long questId, [FromQuery] long revision) { // 여기에서만 Test -> Editable 가능 (var errorCode, var updated) = await _inGameService.changeQuestStateForInGame(userGuid, questId, revision, [QuestContentState.Test], QuestContentState.Editable); if (errorCode != ServerErrorCode.Success) return Results.BadRequest(ApiResponseFactory.error(errorCode)); return Results.Ok(); } /// /// 퀘스트를 수락했을 때 호출 /// [HttpPost] [Route("set-quest-accepted/{userGuid}")] public async Task setQuestAccepted(string userGuid, UgqQuestAcceptedRequest request) { var errorCode = await _inGameService.setQuestAccepted(userGuid, request); if (errorCode != ServerErrorCode.Success) return Results.BadRequest(ApiResponseFactory.error(errorCode)); return Results.Ok(); } /// /// 퀘스트를 완료했을 때 호출 /// [HttpPost] [Route("set-quest-completed/{userGuid}")] public async Task setQuestCompleted(string userGuid, UgqQuestCompletedRequest request) { var errorCode = await _inGameService.setQuestCompleted(userGuid, request); if (errorCode != ServerErrorCode.Success) return Results.BadRequest(ApiResponseFactory.error(errorCode)); return Results.Ok(); } /// /// 퀘스트를 포기했을 때 호출 /// [HttpPost] [Route("set-quest-aborted/{userGuid}")] public async Task setQuestAbort(string userGuid, UgqQuestAbortedRequest request) { var errorCode = await _inGameService.setQuestAborted(userGuid, request); if (errorCode != ServerErrorCode.Success) return Results.BadRequest(ApiResponseFactory.error(errorCode)); return Results.Ok(); } /// /// 퀘스트를 북마크 /// [HttpPost] [Route("bookmark")] public async Task bookmark(UgqBookmarkRequest request) { var errorCode = await _inGameService.bookmark(request.QuestId, request.UserGuid); if(errorCode != ServerErrorCode.Success) return Results.BadRequest(ApiResponseFactory.error(errorCode)); return Results.Ok(); } /// /// 퀘스트를 북마크 취소 /// [HttpPost] [Route("unbookmark")] public async Task unbookmark(UgqUnbookmarkRequest request) { var errorCode = await _inGameService.unbookmark(request.QuestId, request.UserGuid); if (errorCode != ServerErrorCode.Success) return Results.BadRequest(ApiResponseFactory.error(errorCode)); return Results.Ok(); } /// /// 퀘스트를 좋아요 /// [HttpPost] [Route("like")] public async Task like(UgqLikeRequest request) { var errorCode = await _inGameService.like(request.QuestId, request.Revision, request.UserGuid); if (errorCode != ServerErrorCode.Success) return Results.BadRequest(ApiResponseFactory.error(errorCode)); return Results.Ok(); } /// /// 퀘스트를 좋아요 취소 /// [HttpPost] [Route("unlike")] public async Task unlike(UgqUnlikeRequest request) { var errorCode = await _inGameService.unlike(request.QuestId, request.Revision, request.UserGuid); if (errorCode != ServerErrorCode.Success) return Results.BadRequest(ApiResponseFactory.error(errorCode)); return Results.Ok(); } /// /// 퀘스트를 신고 /// [HttpPost] [Route("report")] public async Task report(UgqReportRequest request) { var errorCode = await _inGameService.report(request.UserGuid, request.QuestId, request.Revision, request.Contents); if (errorCode != ServerErrorCode.Success) return Results.BadRequest(ApiResponseFactory.error(errorCode)); return Results.Ok(); } /// /// Test 상태인 UGQ QuestScript 정보 얻기 (직접 작성한 퀘스트만 획득 가능) /// [HttpGet] [Route("test-game-quest-data/{userGuid}")] public async Task getTestGameQuestData(string userGuid, [FromQuery] long questId, [FromQuery] long revision) { (ServerErrorCode errorCode, var gameQuestDataEntity) = await _inGameService.getTestGameQuestData(userGuid, questId, revision); if (errorCode != ServerErrorCode.Success) return Results.BadRequest(ApiResponseFactory.error(errorCode)); if (gameQuestDataEntity == null) return Results.BadRequest(ApiResponseFactory.error(ServerErrorCode.UgqNullEntity)); return Results.Ok(gameQuestDataEntity); } /// /// Live 상태인 UGQ QuestScript 정보 얻기 /// [HttpGet] [Route("game-quest-data")] public async Task getGameQuestData([FromQuery] long questId, [FromQuery] long revision) { (ServerErrorCode errorCode, var gameQuestDataEntity) = await _inGameService.getGameQuestData(questId, revision, QuestContentState.Live); if (errorCode != ServerErrorCode.Success) return Results.BadRequest(ApiResponseFactory.error(errorCode)); if (gameQuestDataEntity == null) return Results.BadRequest(ApiResponseFactory.error(ServerErrorCode.UgqNullEntity)); return Results.Ok(gameQuestDataEntity); } /// /// QuestScript 데이터 중 일부만 얻기 /// [HttpGet] [Route("game-quest-data-simple")] public async Task getGameQuestDataSimple([FromQuery] long questId, [FromQuery] long revision, [FromQuery] QuestContentState state) { (ServerErrorCode errorCode, var gameQuestDataEntity) = await _inGameService.getGameQuestData(questId, revision, state); if (errorCode != ServerErrorCode.Success) return Results.BadRequest(ApiResponseFactory.error(errorCode)); if (gameQuestDataEntity == null) return Results.BadRequest(ApiResponseFactory.error(ServerErrorCode.UgqNullEntity)); return Results.Ok(gameQuestDataEntity.ToSimpleDTO()); } /// /// 최신 리비전의 QuestScript 정보 얻기 /// [HttpGet] [Route("latest-revision-game-quest-data")] public async Task getLatestRevisionGameQuestData([FromQuery] long questId) { (ServerErrorCode errorCode, var gameQuestDataEntity) = await _inGameService.getLatestRevisionGameQuestData(questId); if (errorCode != ServerErrorCode.Success) return Results.BadRequest(ApiResponseFactory.error(errorCode)); if (gameQuestDataEntity == null) return Results.BadRequest(ApiResponseFactory.error(ServerErrorCode.UgqNullEntity)); return Results.Ok(gameQuestDataEntity); } /// /// UGQ 로그인 상태를 레디스에서 삭제 /// [HttpPost] [Route("clear-login/{userGuid}")] public async Task clearLogin(string userGuid) { // ugq 로그인 상태를 삭제 시킨다. await _redis.GetDatabase().KeyDeleteAsync($"ugq_login:{userGuid}"); return Results.Ok(); } } }