초기커밋

This commit is contained in:
2025-05-01 07:20:41 +09:00
commit 98bb2e3c5c
2747 changed files with 646947 additions and 0 deletions

View File

@@ -0,0 +1,11 @@
using ServerCommon;
using UGQDatabase.Models;
namespace GameServer;
public interface IQuestMeta
{
Task<(Result, QuestMetaAllBaseInfo)> getQuestMetaInfo(Player? player, UInt32 questId, UInt32 questRevision);
}

View File

@@ -0,0 +1,69 @@
using ServerCommon;
using ServerCore; using ServerBase;
using UGQDatabase.Models;
namespace GameServer;
public abstract class QuestMetaBase : IQuestMeta
{
protected readonly UgqStateType m_ugq_state = UgqStateType.Live;
protected readonly QuestContentState m_quest_content_state = QuestContentState.Live;
public QuestMetaBase()
{
m_ugq_state = UgqStateType.None;
m_quest_content_state = QuestContentState.None;
}
public QuestMetaBase(UgqStateType ugqState, QuestContentState questContentState)
{
m_ugq_state = ugqState;
m_quest_content_state = questContentState;
}
public abstract Task<(Result, QuestMetaAllBaseInfo)> getQuestMetaInfo(Player? player, UInt32 questId, UInt32 questRevision);
}
public class QuestMetaAllBaseInfo
{
private readonly UgqStateType m_ugq_state = UgqStateType.None;
private readonly QuestContentState m_quest_content_state = QuestContentState.None;
public QuestBaseInfo? m_quest_base_info { get; set; } = null;
public GameQuestDataEntity? m_quest_data_entity { get; set; } = null;
public QuestMetaAllBaseInfo(UgqStateType ugqState, QuestContentState questContentState)
{
m_ugq_state = ugqState;
m_quest_content_state = questContentState;
}
public QuestMetaAllBaseInfo(QuestBaseInfo questBaseInfo)
{
m_ugq_state = UgqStateType.None;
m_quest_content_state = QuestContentState.None;
m_quest_base_info = questBaseInfo;
m_quest_data_entity = null!;
}
public QuestMetaAllBaseInfo(UgqStateType ugqState, QuestContentState questContentState, QuestBaseInfo questBaseInfo, GameQuestDataEntity gameQuestData)
{
m_ugq_state = ugqState;
m_quest_content_state = questContentState;
m_quest_base_info = questBaseInfo;
m_quest_data_entity = gameQuestData;
}
/*
public QuestMetaAllBaseInfo(QuestBaseInfo questBaseInfo, GameQuestDataEntity gameQuestData)
{
m_ugq_state = UgqStateType.None;
m_quest_content_state = QuestContentState.None;
m_quest_base_info = questBaseInfo;
m_quest_data_entity = gameQuestData;
}
*/
}

View File

@@ -0,0 +1,126 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using ServerCore; using ServerBase;
using ServerCommon;
using UGQDatabase.Models;
namespace GameServer;
public class QuestMetaManager : Singleton<QuestMetaManager>
{
IQuestMeta m_system_quest_meta;
IQuestMeta m_ugq_live_quest_meta;
IQuestMeta m_ugq_test_quest_meta;
public QuestMetaManager()
{
m_system_quest_meta = new QuestSystemMeta();
m_ugq_live_quest_meta = new QuestUgqLiveMeta();
m_ugq_test_quest_meta = new QuestUgqTestMeta();
}
//system quest일때 사용
public async Task<(Result, QuestMetaAllBaseInfo)> getQuestMeta(UInt32 questId)
{
return await m_system_quest_meta.getQuestMetaInfo(null, questId, 0);
}
//시스템 퀘스트 인지 아닌지 잘 모를때 사용
public async Task<(Result, QuestMetaAllBaseInfo)> getQuestMeta(Player player, UInt32 questId, UInt32 questRevision)
{
(var result, IQuestMeta i_quest_meta) = await getIUgqMeta(questId, questRevision);
return await i_quest_meta.getQuestMetaInfo(player, questId, questRevision);
}
//Ugq 퀘스트를 명시적으로 호출할때 사용
public async Task<(Result, QuestMetaAllBaseInfo)> getQuestMeta(Player player, UInt32 questId, UInt32 questRevision, QuestContentState contentState)
{
(var result, IQuestMeta i_quest_meta) = getIUgqMeta(questRevision, contentState);
return await i_quest_meta.getQuestMetaInfo(player, questId, questRevision);
}
//Ugq 퀘스트를 명시적으로 호출할때 사용
public async Task<(Result, QuestMetaAllBaseInfo)> getQuestMeta(Player player, UInt32 questId, UInt32 questRevision, UgqStateType UgqStateState)
{
(var result, IQuestMeta i_quest_meta) = getIUgqMeta(questRevision, UgqStateState);
return await i_quest_meta.getQuestMetaInfo(player, questId, questRevision);
}
private (Result, IQuestMeta) getIUgqMeta(UInt32 questRevision, QuestContentState contentState)
{
var result = new Result();
if (questRevision == 0)
{
return (result, m_system_quest_meta);
}
switch (contentState)
{
case QuestContentState.Live:
return (result, m_ugq_live_quest_meta);
case QuestContentState.Test:
return (result, m_ugq_test_quest_meta);
default:
var err_msg = $"Not Support QuestContentState : {contentState}";
result.setFail(ServerErrorCode.MetaInfoException, err_msg);
return (result, null!);
}
}
private (Result, IQuestMeta) getIUgqMeta(UInt32 questRevision, UgqStateType ugqQuestType)
{
var result = new Result();
if (questRevision == 0)
{
return (result, m_system_quest_meta);
}
switch (ugqQuestType)
{
case UgqStateType.Live:
return (result, m_ugq_live_quest_meta);
case UgqStateType.Test:
return (result, m_ugq_test_quest_meta);
default:
var err_msg = $"Not Support ugqQuestType : {ugqQuestType}";
result.setFail(ServerErrorCode.MetaInfoException, err_msg);
return (result, null!);
}
}
private async Task<(Result, IQuestMeta)> getIUgqMeta(UInt32 questId, UInt32 questRevision)
{
var result = new Result();
if(questRevision == 0)
{
return (result, m_system_quest_meta);
}
else
{
//Live 상태가 많을 것으로 생각해서 많은것 먼저조회 해서 가져 오도록 하자.
var server_logic = GameServerApp.getServerLogic();
var ugq_api_manager = server_logic.GetUqgApiManager();
(result, var simple_game_quest_data) = await ugq_api_manager.getUgqQuestSimpleInfo(questId, questRevision, QuestContentState.Live);
if (result.isSuccess() && simple_game_quest_data is not null)
return (result, m_ugq_live_quest_meta);
(result, simple_game_quest_data) = await ugq_api_manager.getUgqQuestSimpleInfo(questId, questRevision, QuestContentState.Test);
if (result.isSuccess() && simple_game_quest_data is not null)
return (result, m_ugq_test_quest_meta);
//여기까지 오면 에러...
var err_msg = $"Not Exist QuestUgqMetaInfo QuestID : {questId} - QuestRevision : {questRevision}";
result.setFail(ServerErrorCode.MetaInfoException, err_msg);
Log.getLogger().error(result.toBasicString());
return (result, null!);
}
}
}

View File

@@ -0,0 +1,33 @@
using Amazon.CloudWatchLogs.Model;
using ServerCommon;
using ServerCore; using ServerBase;
using UGQDatabase.Models;
namespace GameServer;
public class QuestSystemMeta : QuestMetaBase
{
public QuestSystemMeta() : base()
{
}
public override async Task<(Result, QuestMetaAllBaseInfo)> getQuestMetaInfo(Player? player, UInt32 questId, UInt32 questRevision)
{
await Task.CompletedTask;
var result = new Result();
if (false == MetaData.Instance._QuestBaseinfoTable.TryGetValue(questId, out var quest_base_info))
{
string err_msg = $"NotExist Quest Assign Data QuestID : {questId}";
result.setFail(ServerErrorCode.QuestAssingDataNotExist, err_msg);
Log.getLogger().error(result.toBasicString());
return (result, null!);
}
QuestMetaAllBaseInfo info = new QuestMetaAllBaseInfo(quest_base_info);
return (result, info);
}
}

View File

@@ -0,0 +1,158 @@
using Amazon.DynamoDBv2.Model;
using ServerCommon;
using ServerCore; using ServerBase;
using System;
using System.Collections.Concurrent;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using UGQDatabase.Models;
using Newtonsoft.Json;
using static System.Runtime.InteropServices.JavaScript.JSType;
using ServerCommon.UGQ.Models;
namespace GameServer
{
public class QuestUgqLiveMeta : QuestMetaBase
{
private Lazy<ConcurrentDictionary<(UInt32, UInt32), QuestMetaAllBaseInfo>> m_ugq_quest_data = new Lazy<ConcurrentDictionary<(UInt32, UInt32), QuestMetaAllBaseInfo>>();
private ConcurrentDictionary<(UInt32, UInt32), QuestMetaAllBaseInfo> UgqQuestData => m_ugq_quest_data.Value;
public QuestUgqLiveMeta()
: base(UgqStateType.Live, QuestContentState.Live)
{
}
public override async Task<(Result, QuestMetaAllBaseInfo)> getQuestMetaInfo(Player? player, UInt32 questId, UInt32 questRevision)
{
ArgumentNullReferenceCheckHelper.throwIfNull(player, () => $"player is null !!!");
var result = new Result();
if (false == UgqQuestData.TryGetValue((questId, questRevision), out var ugq_quest_meta_collected_info))
{
Log.getLogger().debug($"getQuestMetaInfo not exist memory questId : {questId}, questRevision : {questRevision}");
//서버에 캐싱이 없는 경우
ugq_quest_meta_collected_info = new(m_ugq_state, m_quest_content_state);
//api서버에서 호출
(result, var game_quest_data) = await UgqMetaHelper.loadLiveGameQuestGameDataEntity(player, questId, questRevision);
if (result.isFail() || game_quest_data is null)
{
Log.getLogger().error(result.toBasicString());
//호출 해서 데이터가 없는 경우 에러 처리(무조건 있어야 된다.)
return (result, null!);
}
result = await gameQuestDataStateCheck(player, game_quest_data); //여기 result는 그냥 shutdown으로 보내는 거라서 무시
ugq_quest_meta_collected_info.m_quest_data_entity = game_quest_data;
(result, var generated_quest_base_info) = UgqMetaHelper.generateUgqQuestBaseInfo(game_quest_data);
if (result.isFail())
{
return (result, null!);
}
ugq_quest_meta_collected_info.m_quest_base_info = generated_quest_base_info;
UgqQuestData.TryAdd((questId, questRevision), ugq_quest_meta_collected_info);
Log.getLogger().debug($"UgqQuestData.TryAdd questId : {questId}, questRevision : {questRevision}");
}
else
{
//캐싱이 오래 됐을 수도 있으니 game -quest - data - simple 로 한번더 확인 필요.
//Log.getLogger().debug($"getQuestMetaInfo exist memory questId : {questId}, questRevision : {questRevision}, player : {player.toBasicString()}");
var server_logic = GameServerApp.getServerLogic();
var ugq_api_manager = server_logic.GetUqgApiManager();
var lang_type = player.getLanguageType();
(result, var simple_game_quest_data) = await ugq_api_manager.getUgqQuestSimpleInfo(questId, questRevision, m_quest_content_state);
if (result.isFail())
{
Log.getLogger().error(result.toBasicString());
return (result, null!);
}
NullReferenceCheckHelper.throwIfNull(simple_game_quest_data, () => $"simple_game_quest_data is null !!!");
NullReferenceCheckHelper.throwIfNull(ugq_quest_meta_collected_info.m_quest_data_entity, () => $"ugq_quest_meta_collected_info.m_quest_data_entity is null !!!");
ugq_quest_meta_collected_info.m_quest_data_entity.Shutdown = simple_game_quest_data.Shutdown;
ugq_quest_meta_collected_info.m_quest_data_entity.State = simple_game_quest_data.State;
result = await gameQuestDataStateCheck(player, ugq_quest_meta_collected_info.m_quest_data_entity);
if (result.isFail())
{
Log.getLogger().error(result.toBasicString());
return (result, null!);
}
}
UgqQuestData.TryGetValue((questId, questRevision), out ugq_quest_meta_collected_info);
return (result, ugq_quest_meta_collected_info!);
}
private async Task<Result> gameQuestDataStateCheck(Player player, GameQuestDataEntity gameQuestData)
{
//api에서 로드해서 상태 값 확인 했는데 shutdown 인 경우
var result = new Result();
if (gameQuestData.Shutdown == true)
{
var server_logic = GameServerApp.getServerLogic();
var ugq_api_manager = server_logic.GetUqgApiManager();
var lang_type = player.getLanguageType();
//해당 퀘스트가 Shutdown 인경우 갱신 해줘야 된다.
(result, var latest_queat_game_data) = await ugq_api_manager.getUgqLatestQuestData((UInt32)gameQuestData.QuestId, lang_type);
if (result.isFail())
{
var err_msg = $"Failed to getUgqLatestQuestData()!!! questId : {gameQuestData.QuestId} - {player.toBasicString()}";
Log.getLogger().error(err_msg);
return result;
}
NullReferenceCheckHelper.throwIfNull(latest_queat_game_data, () => $"latest_queat_game_data is null !!! - {player.toBasicString()}");
//기존 로드된 데이터의 리비전과, 최신 리비전이 다르면 리비전이 변경이 발생한것
if (gameQuestData.Revision != latest_queat_game_data.Revision)
{
Log.getLogger().info($"Revision diff gameQuestData.Revision : {gameQuestData.Revision} <-> latest_queat_game_data.Revision : {latest_queat_game_data.Revision}");
gameQuestData.UgqGameQuestDataForClient.UgqStateType = UgqStateType.RevisionChanged;
gameQuestData.UgqGameQuestDataForClient.UgqGradeType = gameQuestData.GradeType;
//최신 버전이 아닌경우
result = updateUgqState(gameQuestData.UgqGameQuestDataForClient, UgqStateType.RevisionChanged);
if (result.isFail())
{
return result;
}
}
}
return result;
}
private Result updateUgqState(UgqGameQuestDataForClient ugqGameQuestDataForClient, UgqStateType state)
{
var result = new Result();
if (ugqGameQuestDataForClient is null)
{
var err_msg = $"GameQuestDataEntity NotExist ugqGameQuestDataForClientString";
result.setFail(ServerErrorCode.UgqQuestMetaNotExist, err_msg);
Log.getLogger().error(err_msg);
return result;
}
ugqGameQuestDataForClient.UgqStateType = state;
Log.getLogger().info($"ugq_game_quest_data_for_client ugqState: {state}");
return result;
}
}
}

View File

@@ -0,0 +1,21 @@
using ServerCommon;
using ServerCore; using ServerBase;
using UGQDatabase.Models;
namespace GameServer;
public class QuestUgqTestMeta : QuestMetaBase
{
public QuestUgqTestMeta()
: base(UgqStateType.Test, QuestContentState.Test)
{
}
public override async Task<(Result, QuestMetaAllBaseInfo)> getQuestMetaInfo(Player? player, UInt32 questId, UInt32 questRevision)
{
ArgumentNullReferenceCheckHelper.throwIfNull(player, () => $"player is null !!!");
var ugq_test_action = player.getEntityAction<UgqTestAction>();
return await ugq_test_action.getUgqGameQuestTestData(questId, questRevision);
}
}