509 lines
22 KiB
C#
509 lines
22 KiB
C#
using System.Net;
|
|
using System.Net.Http.Json;
|
|
using System.Security.Cryptography;
|
|
using System.Text;
|
|
using System.Xml.Linq;
|
|
|
|
|
|
using Amazon.Runtime.Internal.Endpoints.StandardLibrary;
|
|
using Google.Protobuf.WellKnownTypes;
|
|
using Microsoft.AspNetCore.Mvc.Formatters;
|
|
using Microsoft.Extensions.Hosting;
|
|
using Newtonsoft.Json;
|
|
using Org.BouncyCastle.Asn1.Ocsp;
|
|
|
|
|
|
using ServerCore; using ServerBase;
|
|
using ServerCommon;
|
|
using ServerCommon.UGQ.Models;
|
|
|
|
|
|
using UGQDatabase.Models;
|
|
|
|
|
|
namespace GameServer
|
|
{
|
|
public class UgqApiManager
|
|
{
|
|
HttpClient http_client = new();
|
|
string url_prefix = string.Empty;
|
|
|
|
|
|
|
|
private static readonly object lock_object = new object();
|
|
private static bool is_task_running = false;
|
|
|
|
private static Task? inspection_check_task = null;
|
|
private static Int32 api_server_check_state = 0; //0이면 서버 정상 상태, -1이면 서버 죽거나 ip주소 바뀌어서 접속 안되는 상태
|
|
private const Int32 inspection_state = -1;
|
|
private const Int32 active_state = 0;
|
|
|
|
private const string connection_test_str = "connection-test";
|
|
|
|
|
|
public async Task onInit()
|
|
{
|
|
await Task.CompletedTask;
|
|
|
|
http_client.BaseAddress = new Uri(GameServerApp.getServerLogic().getServerConfig().UgqApiServerConfig.ApiServerAddress);
|
|
url_prefix = GameServerApp.getServerLogic().getServerConfig().UgqApiServerConfig.UrlInGamePrefix;
|
|
}
|
|
|
|
public async Task<Result> checkConnection()
|
|
{
|
|
(var result, var ret) = await sendUgqRequestToApiServer<UgqBoardSearchResult>(http_client, HttpMethod.Get, connection_test_str, new(), string.Empty);
|
|
return (result);
|
|
}
|
|
|
|
|
|
public async Task<(Result, UgqBoardSearchResult?)> getPagedGradeUgqFromBoard(Dictionary<string, string> dictionaries, LanguageType langType)
|
|
{
|
|
string url_str = $"quest-board?";
|
|
var url_builder_str = makeGetParamString(url_str, dictionaries);
|
|
|
|
var headers = UgqApiHelper.makeDictionaryFromLanguageTypeWithMediaType(langType);
|
|
|
|
(var result, var ret) = await sendUgqRequestToApiServer<UgqBoardSearchResult>(http_client, HttpMethod.Get, url_builder_str, headers, string.Empty);
|
|
return (result, ret);
|
|
}
|
|
|
|
public async Task<(Result, UgqBoardItemDetail?)> getUgqDetailFromBoard(Dictionary<string, string> dictionaries, string userGuid, LanguageType langType)
|
|
{
|
|
string url_str = $"quest-board-detail/{userGuid}?";
|
|
var url_builder_str = makeGetParamString(url_str, dictionaries);
|
|
|
|
var headers = UgqApiHelper.makeDictionaryFromLanguageTypeWithMediaType(langType);
|
|
|
|
(var result, var ret) = await sendUgqRequestToApiServer<UgqBoardItemDetail>(http_client, HttpMethod.Get, url_builder_str, headers, string.Empty);
|
|
return (result, ret);
|
|
}
|
|
|
|
public async Task<(Result, UgqBoardSportlightResult?)> getPagedSpotLightUgqFromBoard(Dictionary<string, string> dictionaries)
|
|
{
|
|
(var result, var ret) = await sendUgqRequestToApiServer<UgqBoardSportlightResult>(http_client, HttpMethod.Get, "quest-board-spotlight", dictionaries, string.Empty);
|
|
return (result, ret);
|
|
|
|
}
|
|
public async Task<(Result, UgqBoardSearchResult?)> getPagedBookmarkUgqFromBoard(Dictionary<string, string> dictionaries, string userGuid)
|
|
{
|
|
string url_str = $"bookmark-quest-board/{userGuid}?";
|
|
var url_builder_str = makeGetParamString(url_str, dictionaries);
|
|
(var result, var ret) = await sendUgqRequestToApiServer<UgqBoardSearchResult>(http_client, HttpMethod.Get, url_builder_str, dictionaries, string.Empty);
|
|
return (result, ret);
|
|
}
|
|
|
|
|
|
public async Task<Result> ugqRegisterBookmark(Dictionary<string, string> dict, UInt32 questId, string userGuid)
|
|
{
|
|
UgqBookmarkRequest request = new();
|
|
request.QuestId = questId;
|
|
request.UserGuid = userGuid;
|
|
(var result, var _) = await sendUgqRequestToApiServer<object>(http_client, HttpMethod.Post, $"bookmark", dict, JsonConvert.SerializeObject(request));
|
|
return result;
|
|
}
|
|
|
|
public async Task<Result> ugqDeRegisterBookmark(Dictionary<string, string> dict, UInt32 questId, string userGuid)
|
|
{
|
|
UgqUnbookmarkRequest request = new();
|
|
request.QuestId = questId;
|
|
request.UserGuid = userGuid;
|
|
(var result, var _) = await sendUgqRequestToApiServer<object>(http_client, HttpMethod.Post, $"unbookmark", dict, JsonConvert.SerializeObject(request));
|
|
return result;
|
|
}
|
|
|
|
public async Task<Result> ugqRegisterLike(Dictionary<string, string> dict, UInt32 questId, UInt32 questRevision, string userGuid)
|
|
{
|
|
UgqLikeRequest request = new();
|
|
request.QuestId = questId;
|
|
request.Revision = questRevision;
|
|
request.UserGuid = userGuid;
|
|
(var result, var _) = await sendUgqRequestToApiServer<object>(http_client, HttpMethod.Post, $"like", dict, JsonConvert.SerializeObject(request));
|
|
return result;
|
|
}
|
|
|
|
public async Task<Result> setUgqQuestAccepted(string userGuid, UInt32 questId, UInt32 QuestRevision, LanguageType langType)
|
|
{
|
|
var dict = UgqApiHelper.makeDictionaryFromLanguageTypeWithMediaType(langType);
|
|
UgqQuestAcceptedRequest request = new();
|
|
request.QuestId = questId;
|
|
request.Revision = QuestRevision;
|
|
request.Reason = UGQAcceptReason.Player;
|
|
|
|
string url_str = $"set-quest-accepted/{userGuid}";
|
|
|
|
(var result, var _) = await sendUgqRequestToApiServer<object>(http_client, HttpMethod.Post, url_str, dict, JsonConvert.SerializeObject(request));
|
|
return result;
|
|
}
|
|
|
|
public async Task<Result> setTestUgqQuestCompleted(string userGuid, UInt32 questId, UInt32 QuestRevision, LanguageType langType)
|
|
{
|
|
var dict = UgqApiHelper.makeDictionaryForUgqQuestId(questId, QuestRevision);
|
|
string url_str = $"set-test-completed/{userGuid}?";
|
|
var url_builder_str = makeGetParamString(url_str, dict);
|
|
|
|
var headers = UgqApiHelper.makeDictionaryFromLanguageTypeWithMediaType(langType);
|
|
(var result, var _) = await sendUgqRequestToApiServer<UgqBoardItemDetail>(http_client, HttpMethod.Post, url_builder_str, headers, string.Empty);
|
|
return result;
|
|
}
|
|
|
|
public async Task<Result> setTestUgqQuestAborted(string userGuid, UInt32 questId, UInt32 QuestRevision, LanguageType langType)
|
|
{
|
|
var dict = UgqApiHelper.makeDictionaryForUgqQuestId(questId, QuestRevision);
|
|
string url_str = $"set-test-aborted/{userGuid}?";
|
|
var url_builder_str = makeGetParamString(url_str, dict);
|
|
var headers = UgqApiHelper.makeDictionaryFromLanguageTypeWithMediaType(langType);
|
|
(var result, var _) = await sendUgqRequestToApiServer<UgqBoardItemDetail>(http_client, HttpMethod.Post, url_builder_str, headers, string.Empty);
|
|
return result;
|
|
}
|
|
|
|
public async Task<Result> setUgqQuestCompleted(string userGuid, UInt32 questId, UInt32 QuestRevision, Int32 amount, LanguageType langType)
|
|
{
|
|
var dict = UgqApiHelper.makeDictionaryFromLanguageTypeWithMediaType(langType);
|
|
UgqQuestCompletedRequest request = new();
|
|
request.QuestId = questId;
|
|
request.Revision = QuestRevision;
|
|
request.Amount = amount;
|
|
|
|
string url_str = $"set-quest-completed/{userGuid}";
|
|
|
|
(var result, var _) = await sendUgqRequestToApiServer<object>(http_client, HttpMethod.Post, url_str, dict, JsonConvert.SerializeObject(request));
|
|
return result;
|
|
}
|
|
|
|
public async Task<Result> setUgqQuestAborted(string userGuid, UInt32 questId, UInt32 QuestRevision, UGQAbortReason reason, LanguageType langType)
|
|
{
|
|
var dict = UgqApiHelper.makeDictionaryFromLanguageTypeWithMediaType(langType);
|
|
UgqQuestAbortedRequest request = new();
|
|
request.QuestId = questId;
|
|
request.Revision = QuestRevision;
|
|
request.Reason = reason;
|
|
string url_str = $"set-quest-aborted/{userGuid}";
|
|
(var result, var _) = await sendUgqRequestToApiServer<object>(http_client, HttpMethod.Post, url_str, dict, JsonConvert.SerializeObject(request));
|
|
return result;
|
|
}
|
|
|
|
|
|
|
|
public async Task<Result> ugqDeregisterLike(Dictionary<string, string> dict, UInt32 questId, UInt32 questRevision, string userGuid)
|
|
{
|
|
UgqUnlikeRequest request = new();
|
|
request.QuestId = questId;
|
|
request.Revision = questRevision;
|
|
request.UserGuid = userGuid;
|
|
var req_param = JsonContent.Create(new { questId = questId, revision = questRevision, userGuid = userGuid });
|
|
(var result, var _) = await sendUgqRequestToApiServer<object>(http_client, HttpMethod.Post, $"unlike", dict, JsonConvert.SerializeObject(request));
|
|
return result;
|
|
}
|
|
|
|
public async Task<Result> ugqReport(Dictionary<string, string> dict, UInt32 questId, UInt32 questRevision, string userGuid, string reportText)
|
|
{
|
|
UgqReportRequest request = new();
|
|
request.QuestId = questId;
|
|
request.Revision = questRevision;
|
|
request.UserGuid = userGuid;
|
|
request.Contents = reportText;
|
|
var req_param = JsonContent.Create(new { questId = questId, revision = questRevision, userGuid = userGuid, contents = reportText });
|
|
(var result, var _) = await sendUgqRequestToApiServer<object>(http_client, HttpMethod.Post, $"report", dict, JsonConvert.SerializeObject(request));
|
|
return result;
|
|
}
|
|
|
|
public async Task<(Result, GameQuestDataEntity?)> getUgqQuestData(string userGuid, UInt32 questId, UInt32 questRevision, LanguageType langType)
|
|
{
|
|
var dictionaries = UgqApiHelper.makeDictionaryForUgqQuestId(questId, questRevision);
|
|
string url_str = $"game-quest-data?";
|
|
var url_builder_str = makeGetParamString(url_str, dictionaries);
|
|
var headers = UgqApiHelper.makeDictionaryFromLanguageTypeWithMediaType(langType);
|
|
|
|
(var result, var ret) = await sendUgqRequestToApiServer<GameQuestDataEntity>(http_client, HttpMethod.Get, url_builder_str, headers, string.Empty);
|
|
|
|
return (result, ret);
|
|
}
|
|
public async Task<(Result, List<UgqQuestInTestState>?)> getTestUgqIds(string userGuid, LanguageType languageType)
|
|
{
|
|
string url_str = $"user-quests-in-test-state/{userGuid}";
|
|
var dictionaries = UgqApiHelper.makeDictionaryFromLanguageType(languageType);
|
|
|
|
(var result, var ret) = await sendUgqRequestToApiServer<List<UgqQuestInTestState>>(http_client, HttpMethod.Get, url_str, dictionaries, string.Empty);
|
|
|
|
return (result, ret);
|
|
}
|
|
|
|
public async Task<(Result, GameQuestDataEntity?)> getUgqTestQuestData(string userGuid, UInt32 questId, UInt32 questRevision, LanguageType langType)
|
|
{
|
|
var dictionaries = UgqApiHelper.makeDictionaryForUgqQuestId(questId, questRevision);
|
|
string url_str = $"test-game-quest-data/{userGuid}?";
|
|
var url_builder_str = makeGetParamString(url_str, dictionaries);
|
|
|
|
var headers = UgqApiHelper.makeDictionaryFromLanguageTypeWithMediaType(langType);
|
|
|
|
(var result, var ret) = await sendUgqRequestToApiServer<GameQuestDataEntity>(http_client, HttpMethod.Get, url_builder_str, headers, string.Empty);
|
|
|
|
return (result, ret);
|
|
}
|
|
|
|
public async Task<(Result, GameQuestDataEntity?)> getUgqLatestQuestData(UInt32 questId, LanguageType langType)
|
|
{
|
|
var dictionaries = UgqApiHelper.makeDictionaryForQuestId(questId, langType);
|
|
string url_str = $"latest-revision-game-quest-data?";
|
|
var url_builder_str = makeGetParamString(url_str, dictionaries);
|
|
var headers = UgqApiHelper.makeDictionaryFromLanguageTypeWithMediaType(langType);
|
|
|
|
(var result, var ret) = await sendUgqRequestToApiServer<GameQuestDataEntity>(http_client, HttpMethod.Get, url_builder_str, headers, string.Empty);
|
|
return (result, ret);
|
|
}
|
|
|
|
public async Task<(Result, GameQuestDataSimple?)> getUgqQuestSimpleInfo(UInt32 questId, UInt32 questRevision, QuestContentState state)
|
|
{
|
|
|
|
var dictionaries = UgqApiHelper.makeDictionaryForUgqByState(questId, questRevision, state);
|
|
string url_str = $"game-quest-data-simple?";
|
|
var url_builder_str = makeGetParamString(url_str, dictionaries);
|
|
|
|
(var result, var ret) = await sendUgqRequestToApiServer<GameQuestDataSimple>(http_client, HttpMethod.Get, url_builder_str, new(), string.Empty);
|
|
return (result, ret);
|
|
|
|
}
|
|
|
|
public async Task<(Result, GameQuestDataEntity?)> requestBeginCreatorPoint(string userGuid, Int32 cost, Int32 questId, Int32 questRevision, LanguageType languageType)
|
|
{
|
|
var result = new Result();
|
|
if (cost == 0)
|
|
{
|
|
return (result, new());
|
|
}
|
|
|
|
var dictionaries = UgqApiHelper.makeDictionaryFromLanguageTypeWithMediaType(languageType);
|
|
string url_str = $"begin-creator-point";
|
|
BeginCreatorPointRequest request = new();
|
|
request.UserGuid = userGuid;
|
|
request.Point = cost;
|
|
|
|
//여기 제네릭 나중에 영수증 response로 처리 해야된다.
|
|
(result, var ret) = await sendUgqRequestToApiServer<GameQuestDataEntity>(http_client, HttpMethod.Post, url_str, dictionaries, JsonConvert.SerializeObject(request));
|
|
|
|
return (result, ret);
|
|
}
|
|
|
|
public async Task<(Result, GameQuestDataEntity?)> requestCommitCreatorPoint(string userGuid, string receipt, LanguageType languageType)
|
|
{
|
|
var dictionaries = UgqApiHelper.makeDictionaryFromLanguageTypeWithMediaType(languageType);
|
|
string url_str = $"commit-creator-point";
|
|
CommitCreatorPointRequest request = new();
|
|
request.UserGuid = userGuid;
|
|
request.ReceiptId = receipt;
|
|
|
|
(var result, var ret) = await sendUgqRequestToApiServer<GameQuestDataEntity>(http_client, HttpMethod.Post, url_str, dictionaries, JsonConvert.SerializeObject(request));
|
|
return (result, ret);
|
|
}
|
|
|
|
public async Task<(Result, GameQuestDataEntity?)> requestCancelCreatorPoint(string userGuid, string receipt, string reason, LanguageType languageType)
|
|
{
|
|
var dictionaries = UgqApiHelper.makeDictionaryFromLanguageTypeWithMediaType(languageType);
|
|
string url_str = $"cancel-creator-point";
|
|
|
|
CancelCreatorPointRequest request = new();
|
|
request.UserGuid = userGuid;
|
|
request.ReceiptId = receipt;
|
|
request.CancelReason = reason;
|
|
|
|
(var result, GameQuestDataEntity? ret) = await sendUgqRequestToApiServer<GameQuestDataEntity>(http_client, HttpMethod.Post, url_str, dictionaries, JsonConvert.SerializeObject(request));
|
|
return (result, ret);
|
|
}
|
|
|
|
private async Task<(Result, T?)> sendUgqRequestToApiServer<T>(HttpClient httpClient, HttpMethod method, string url, Dictionary<string, string> headers, string reqBodyString)
|
|
where T : class
|
|
{
|
|
var result = new Result();
|
|
|
|
var err_msg = string.Empty;
|
|
|
|
//점검 상태면 여기서 리턴
|
|
if (api_server_check_state == inspection_state && !url.Equals(connection_test_str))
|
|
{
|
|
err_msg = $"UgqApiServer Inspection State. Exception !!!";
|
|
result.setFail(ServerErrorCode.UgqApiServerHttpRequestException, err_msg);
|
|
Log.getLogger().error(result.toBasicString());
|
|
return (result, null);
|
|
}
|
|
|
|
|
|
HttpRequestMessage requestMessage = new HttpRequestMessage(method, $"{url_prefix}/{url}");
|
|
|
|
foreach (var header in headers)
|
|
{
|
|
requestMessage.Headers.Add(header.Key, header.Value);
|
|
}
|
|
|
|
if (reqBodyString != string.Empty)
|
|
{
|
|
var stringContent = new StringContent(reqBodyString, UnicodeEncoding.UTF8, "application/json");
|
|
requestMessage.Content = stringContent;
|
|
}
|
|
|
|
|
|
var content_string = string.Empty;
|
|
try
|
|
{
|
|
var resMsg = await httpClient.SendAsync(requestMessage);
|
|
|
|
if (resMsg.IsSuccessStatusCode == false)
|
|
{
|
|
if (resMsg.StatusCode == HttpStatusCode.BadRequest)
|
|
{
|
|
content_string = await resMsg.Content.ReadAsStringAsync();
|
|
if (string.IsNullOrWhiteSpace(content_string))
|
|
{
|
|
err_msg =
|
|
$"UgqApiServerRequestFailed Failed. content_string : resMsg.StatusCode : {resMsg.StatusCode}, reason : {resMsg.ReasonPhrase} !!!, url : {url}";
|
|
result.setFail(ServerErrorCode.UgqApiServerRequestFailed, err_msg);
|
|
Log.getLogger().info(err_msg);
|
|
}
|
|
else
|
|
{
|
|
result = makeErrorResult(content_string);
|
|
}
|
|
|
|
return (result, null);
|
|
}
|
|
|
|
err_msg =
|
|
$"UgqApiServerRequestFailed Failed. resMsg.StatusCode : content_string : {content_string}, {resMsg.StatusCode}, reason : {resMsg.ReasonPhrase} !!!, url : {url}";
|
|
result.setFail(ServerErrorCode.UgqApiServerRequestFailed, err_msg);
|
|
Log.getLogger().info(err_msg);
|
|
return (result, null);
|
|
}
|
|
|
|
content_string = await resMsg.Content.ReadAsStringAsync();
|
|
if (string.IsNullOrWhiteSpace(content_string))
|
|
{
|
|
return (result, null);
|
|
}
|
|
}
|
|
catch (Exception e)
|
|
{
|
|
err_msg = $"UgqApiServerRequestFailed Failed. Exception !!!, {e.Message}";
|
|
result.setFail(ServerErrorCode.UgqApiServerHttpRequestException, err_msg);
|
|
Log.getLogger().error(result.toBasicString());
|
|
|
|
//서버죽었으므로 여기서 점검 상태로 변경
|
|
StartChangeInspectStateTask();
|
|
|
|
//await changeInspectState();
|
|
|
|
return (result, null);
|
|
}
|
|
|
|
var contect_template = JsonConvert.DeserializeObject<T>(content_string);
|
|
if (null == contect_template)
|
|
{
|
|
err_msg = $"UgqApiServerRequest Serialize Failed. content_string : {content_string} !!!, url : {url}";
|
|
result.setFail(ServerErrorCode.UgqApiServerConvertToObjectFailed, err_msg);
|
|
Log.getLogger().info(err_msg);
|
|
return (result, null);
|
|
}
|
|
|
|
return (result, contect_template);
|
|
}
|
|
|
|
|
|
private void StartChangeInspectStateTask()
|
|
{
|
|
lock (lock_object)
|
|
{
|
|
if (is_task_running)
|
|
return; // 이미 실행 중인 작업이 있으면 아무것도 하지 않음
|
|
|
|
is_task_running = true;
|
|
inspection_check_task = Task.Run(async () =>
|
|
{
|
|
try
|
|
{
|
|
await changeInspectState();
|
|
}
|
|
finally
|
|
{
|
|
is_task_running = false; // 작업이 완료된 후 상태 업데이트
|
|
}
|
|
});
|
|
}
|
|
}
|
|
|
|
|
|
private async Task changeInspectState()
|
|
{
|
|
api_server_check_state = inspection_state;
|
|
|
|
while (true)
|
|
{
|
|
// 1분 대기
|
|
await Task.Delay(TimeSpan.FromMinutes(1));
|
|
|
|
var result = new Result();
|
|
result = await checkConnection();
|
|
|
|
if (result.isFail() && result.getErrorCode() == ServerErrorCode.UgqApiServerHttpRequestException)
|
|
{
|
|
|
|
Log.getLogger().error($"ugq api server inpection recheck still error changed");
|
|
}
|
|
else
|
|
{
|
|
//그렇지 않으면 정상 이니까 상태 변경
|
|
api_server_check_state = active_state;
|
|
Log.getLogger().error($"ugq api server inpection request success !! api_server_check_state : {api_server_check_state}");
|
|
break;
|
|
}
|
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
private Result makeErrorResult(string content_string)
|
|
{
|
|
var result = new Result();
|
|
try
|
|
{
|
|
var response_result = JsonConvert.DeserializeObject<ApiErrorResponse>(content_string);
|
|
NullReferenceCheckHelper.throwIfNull(response_result, () => $"response_result is null !!!");
|
|
|
|
result.setFail((ServerErrorCode)response_result.ErrorCode, response_result.ErrorMessage);
|
|
}
|
|
catch (Exception e)
|
|
{
|
|
var err_msg = $"UgqApiServerRequest Serialize Failed. content_string : {e}, {content_string} !!!";
|
|
result.setFail(ServerErrorCode.UgqApiServerConvertToObjectFailed, err_msg);
|
|
Log.getLogger().info(err_msg);
|
|
return result;
|
|
}
|
|
return result;
|
|
}
|
|
|
|
|
|
private string makeGetParamString(string prefixUrl, Dictionary<string, string> dictionaries)
|
|
{
|
|
StringBuilder url_builder = new StringBuilder(prefixUrl);
|
|
int count = dictionaries.Count;
|
|
int index = 0;
|
|
|
|
foreach (var dict in dictionaries)
|
|
{
|
|
url_builder.Append($"{dict.Key}={dict.Value}");
|
|
if (index < count - 1)
|
|
{
|
|
url_builder.Append("&");
|
|
}
|
|
index++;
|
|
}
|
|
|
|
return url_builder.ToString();
|
|
}
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
}
|