초기커밋
This commit is contained in:
563
GameServer/Contents/AIChat/Action/AIChatAction.cs
Normal file
563
GameServer/Contents/AIChat/Action/AIChatAction.cs
Normal file
@@ -0,0 +1,563 @@
|
||||
using Newtonsoft.Json;
|
||||
|
||||
|
||||
using ServerCore; using ServerBase;
|
||||
using ServerCommon;
|
||||
using static ServerCommon.MetaHelper;
|
||||
|
||||
|
||||
using META_ID = System.UInt32;
|
||||
using Amazon.S3.Model;
|
||||
|
||||
|
||||
namespace GameServer
|
||||
{
|
||||
public class AIChatAction : EntityActionBase
|
||||
{
|
||||
private string user_jwt = string.Empty;
|
||||
|
||||
public AIChatAction(Player owner)
|
||||
: base(owner)
|
||||
{
|
||||
}
|
||||
|
||||
public override Task<Result> onInit()
|
||||
{
|
||||
var result = new Result();
|
||||
|
||||
return Task.FromResult(result);
|
||||
}
|
||||
|
||||
public override void onClear()
|
||||
{
|
||||
user_jwt = string.Empty;
|
||||
}
|
||||
|
||||
//-------------인증 JWT 관련 API-------------
|
||||
//특정 유저의 JWT를 검증합니다.
|
||||
public async Task<(Result, AIChatJwtInfo?)> jwtverify(string user_jwt)
|
||||
{
|
||||
var result = new Result();
|
||||
|
||||
var player = getOwner() as Player;
|
||||
NullReferenceCheckHelper.throwIfNull(player, () => $"player is null !!!");
|
||||
|
||||
var server_logic = GameServerApp.getServerLogic();
|
||||
if (server_logic.getServerConfig().OfflineMode == true)
|
||||
{
|
||||
result.setFail(ServerErrorCode.AiChatServerInactive);
|
||||
return (result, null);
|
||||
}
|
||||
|
||||
var url = $"/api/auth/jwt/verify";
|
||||
(result, string resMsg) = await AIChatServerConnector.sendAIChatServer("GET", url, user_jwt, null);
|
||||
if (result.isFail())
|
||||
{
|
||||
Log.getLogger().error($"Failed ai chat server action : jwtverify, msg : {resMsg}");
|
||||
return (result, null);
|
||||
}
|
||||
|
||||
var invokers = new List<ILogInvoker>();
|
||||
var log_action = new LogActionEx(LogActionType.AIChatJwtVerify);
|
||||
|
||||
var task_log_data = AIChatBusinessLogHelper.toLogInfo(url, string.Empty);
|
||||
invokers.Add(new AIChatBusinessLog(task_log_data));
|
||||
|
||||
BusinessLogger.collectLogs(log_action, player, invokers);
|
||||
|
||||
try
|
||||
{
|
||||
var aichat_jwt_info = JsonConvert.DeserializeObject<AIChatJwtInfo>(resMsg);
|
||||
return (result, aichat_jwt_info);
|
||||
}
|
||||
catch(Exception ex)
|
||||
{
|
||||
Log.getLogger().error($"Exception !!!, DeserializeObject : exception:{ex}, resMsg:{resMsg}");
|
||||
return (result, null);
|
||||
}
|
||||
}
|
||||
|
||||
//특정 유저의 JWT를 발행합니다.
|
||||
public async Task<(Result, string?)> jwtIssue(string user_guid)
|
||||
{
|
||||
var result = new Result();
|
||||
|
||||
var player = getOwner() as Player;
|
||||
NullReferenceCheckHelper.throwIfNull(player, () => $"player is null !!!");
|
||||
|
||||
var server_logic = GameServerApp.getServerLogic();
|
||||
if (server_logic.getServerConfig().OfflineMode == true)
|
||||
{
|
||||
result.setFail(ServerErrorCode.AiChatServerInactive);
|
||||
return (result, string.Empty);
|
||||
}
|
||||
|
||||
var url = $"/api/auth/jwt/issue/{user_guid}";
|
||||
var body = AIChatServerConnector.getUserJwtJson();
|
||||
|
||||
(result, string resMsg) = await AIChatServerConnector.sendAIChatServer("POST", url, null, body);
|
||||
if (result.isFail())
|
||||
{
|
||||
Log.getLogger().error($"Failed ai chat server action : jwtIssue, msg : {resMsg}");
|
||||
return (result, string.Empty);
|
||||
}
|
||||
|
||||
var invokers = new List<ILogInvoker>();
|
||||
var log_action = new LogActionEx(LogActionType.AIChatJwtIssue);
|
||||
|
||||
var task_log_data = AIChatBusinessLogHelper.toLogInfo(url, body);
|
||||
invokers.Add(new AIChatBusinessLog(task_log_data));
|
||||
|
||||
BusinessLogger.collectLogs(log_action, player, invokers);
|
||||
|
||||
try
|
||||
{
|
||||
var ai_chat_issue_jwt = JsonConvert.DeserializeObject<AIChatIssueJwt>(resMsg);
|
||||
NullReferenceCheckHelper.throwIfNull(ai_chat_issue_jwt, () => $"ai_chat_issue_jwt is null !!! - {toBasicString()}");
|
||||
|
||||
user_jwt = ai_chat_issue_jwt.jwt == null ? string.Empty : ai_chat_issue_jwt.jwt;
|
||||
|
||||
return (result, user_jwt);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Log.getLogger().error($"Exception !!!, DeserializeObject : exception:{ex}, resMsg:{resMsg}");
|
||||
return (result, null);
|
||||
}
|
||||
}
|
||||
|
||||
//포인트 충전
|
||||
public async Task<Result> pointCharge(AIChatPointCharge aIChatPointCharge)
|
||||
{
|
||||
var player = getOwner() as Player;
|
||||
NullReferenceCheckHelper.throwIfNull(player, () => $"player is null !!!");
|
||||
|
||||
var url = $"/api/point/charge";
|
||||
var body = JsonConvert.SerializeObject(aIChatPointCharge);
|
||||
|
||||
(var result, string resMsg) = await AIChatServerConnector.sendAIChatServerWithServerJwt("PUT", url, body);
|
||||
if (result.isFail())
|
||||
{
|
||||
if (result.ErrorCode == ServerErrorCode.AiChatServerInactive)
|
||||
return result;
|
||||
|
||||
result.setFail(ServerErrorCode.AiChatServerRetryChargePoint);
|
||||
Log.getLogger().error($"Failed ai chat server action : pointCharge, msg : {resMsg}");
|
||||
return result;
|
||||
}
|
||||
|
||||
var invokers = new List<ILogInvoker>();
|
||||
var log_action = new LogActionEx(LogActionType.AIChatPointCharge);
|
||||
|
||||
var task_log_data = AIChatBusinessLogHelper.toLogInfo(url, body);
|
||||
invokers.Add(new AIChatBusinessLog(task_log_data));
|
||||
|
||||
BusinessLogger.collectLogs(log_action, player, invokers);
|
||||
|
||||
return result;
|
||||
}
|
||||
//포인트 충전 확인
|
||||
public async Task<Result> pointChargeCheckByOrderGuid(string order_guid)
|
||||
{
|
||||
var player = getOwner() as Player;
|
||||
NullReferenceCheckHelper.throwIfNull(player, () => $"player is null !!!");
|
||||
|
||||
var aIPointVerify = new AIChatPointVerify() { orderGuid = order_guid };
|
||||
|
||||
var url = $"/api/point/charge";
|
||||
var body = JsonConvert.SerializeObject(aIPointVerify);
|
||||
|
||||
(var result, string resMsg) = await AIChatServerConnector.sendAIChatServerWithServerJwt("GET", url, body);
|
||||
if (result.isFail()) return result;
|
||||
|
||||
var invokers = new List<ILogInvoker>();
|
||||
var log_action = new LogActionEx(LogActionType.AIChatPointChargeVerify);
|
||||
|
||||
var task_log_data = AIChatBusinessLogHelper.toLogInfo(url, body);
|
||||
invokers.Add(new AIChatBusinessLog(task_log_data));
|
||||
|
||||
BusinessLogger.collectLogs(log_action, player, invokers);
|
||||
|
||||
return result;
|
||||
}
|
||||
//어제까지의 벌어들인 미청구 포인트 조회
|
||||
public async Task<(Result, AIChatPointClaimables?)> pointClaimables(int page, int num_per_page, string user_guid)
|
||||
{
|
||||
var player = getOwner() as Player;
|
||||
NullReferenceCheckHelper.throwIfNull(player, () => $"player is null !!!");
|
||||
|
||||
var url = $"/api/point/claimables/{user_guid}?page={page}&numPerPage={num_per_page}";
|
||||
|
||||
(var result, string resMsg) = await AIChatServerConnector.sendAIChatServerWithServerJwt("GET", url, null);
|
||||
if (result.isFail())
|
||||
{
|
||||
if (result.ErrorCode == ServerErrorCode.AiChatServerUserNotFound)
|
||||
{
|
||||
result = await registerUser(player.getUserGuid(), player.getUserNickname());
|
||||
if (result.isFail())
|
||||
{
|
||||
return (result, null);
|
||||
}
|
||||
|
||||
(result, resMsg) = await AIChatServerConnector.sendAIChatServerWithServerJwt("GET", url, null);
|
||||
if (result.isFail())
|
||||
{
|
||||
return (result, null);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
var invokers = new List<ILogInvoker>();
|
||||
var log_action = new LogActionEx(LogActionType.AIChatIncentiveSearch);
|
||||
|
||||
var task_log_data = AIChatBusinessLogHelper.toLogInfo(url, string.Empty);
|
||||
invokers.Add(new AIChatBusinessLog(task_log_data));
|
||||
|
||||
BusinessLogger.collectLogs(log_action, player, invokers);
|
||||
|
||||
try
|
||||
{
|
||||
var aichat_point_claim_ables = JsonConvert.DeserializeObject<AIChatPointClaimables>(resMsg);
|
||||
return (result, aichat_point_claim_ables);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Log.getLogger().error($"Exception !!!, DeserializeObject : exception:{ex}, resMsg:{resMsg}");
|
||||
return (result, null);
|
||||
}
|
||||
}
|
||||
//인센티브 수령 완료 표시
|
||||
public async Task<Result> pointMarkClaimed(string user_guid, int marking_day)
|
||||
{
|
||||
var player = getOwner() as Player;
|
||||
NullReferenceCheckHelper.throwIfNull(player, () => $"server_logic is null !!!");
|
||||
|
||||
var url = $"/api/point/mark-as-claimed/{user_guid}?aggregationEndTime={marking_day}";
|
||||
|
||||
(var result, string resMsg) = await AIChatServerConnector.sendAIChatServerWithServerJwt("POST", url, null);
|
||||
if (result.isFail())
|
||||
{
|
||||
Log.getLogger().error($"Failed ai chat server action : pointMarkClaimed, msg : {resMsg}");
|
||||
return result;
|
||||
}
|
||||
|
||||
var invokers = new List<ILogInvoker>();
|
||||
var log_action = new LogActionEx(LogActionType.AIChatIncentiveMarking);
|
||||
|
||||
var task_log_data = AIChatBusinessLogHelper.toLogInfo(url, string.Empty);
|
||||
invokers.Add(new AIChatBusinessLog(task_log_data));
|
||||
|
||||
BusinessLogger.collectLogs(log_action, player, invokers);
|
||||
|
||||
return result;
|
||||
}
|
||||
//신규 유저 등록
|
||||
public async Task<Result> registerUser(string user_guid, string name)
|
||||
{
|
||||
var player = getOwner() as Player;
|
||||
NullReferenceCheckHelper.throwIfNull(player, () => $"player is null !!!");
|
||||
|
||||
var url = $"/api/user/{user_guid}";
|
||||
|
||||
var aIRegisterUser = new AIChatRegisterUser() { nick = name };
|
||||
var body = JsonConvert.SerializeObject(aIRegisterUser);
|
||||
|
||||
(var result, string resMsg) = await AIChatServerConnector.sendAIChatServerWithServerJwt("POST", url, body);
|
||||
if (result.isFail())
|
||||
{
|
||||
Log.getLogger().error($"Failed ai chat server action : registerUser, user_guid : {user_guid}, name : {name}, msg : {resMsg}");
|
||||
return result;
|
||||
}
|
||||
|
||||
var invokers = new List<ILogInvoker>();
|
||||
var log_action = new LogActionEx(LogActionType.AIChatRegisterUser);
|
||||
|
||||
var task_log_data = AIChatBusinessLogHelper.toLogInfo(url, body);
|
||||
invokers.Add(new AIChatBusinessLog(task_log_data));
|
||||
|
||||
BusinessLogger.collectLogs(log_action, player, invokers);
|
||||
|
||||
return result;
|
||||
}
|
||||
//유저 등록 제거
|
||||
public async Task<Result> deleteUser(string user_guid)
|
||||
{
|
||||
var player = getOwner() as Player;
|
||||
NullReferenceCheckHelper.throwIfNull(player, () => $"player is null !!!");
|
||||
|
||||
var url = $"/api/user/{user_guid}";
|
||||
|
||||
(var result, string resMsg) = await AIChatServerConnector.sendAIChatServerWithServerJwt("DELETE", url, null);
|
||||
if (result.isFail()) return result;
|
||||
|
||||
var invokers = new List<ILogInvoker>();
|
||||
var log_action = new LogActionEx(LogActionType.AIChatDeleteUser);
|
||||
|
||||
var task_log_data = AIChatBusinessLogHelper.toLogInfo(url, string.Empty);
|
||||
invokers.Add(new AIChatBusinessLog(task_log_data));
|
||||
|
||||
BusinessLogger.collectLogs(log_action, player, invokers);
|
||||
|
||||
return result;
|
||||
}
|
||||
//특정 캐릭터 조회
|
||||
public async Task<(Result, AIChatCharacter?)> getCharacterByTargetGuid(string target_guid)
|
||||
{
|
||||
var player = getOwner() as Player;
|
||||
NullReferenceCheckHelper.throwIfNull(player, () => $"player is null !!!");
|
||||
|
||||
var url = $"/api/character/{target_guid}";
|
||||
|
||||
(var result, string resMsg) = await AIChatServerConnector.sendAIChatServerWithServerJwt("GET", url, null);
|
||||
if (result.isFail()) return (result, null);
|
||||
|
||||
var invokers = new List<ILogInvoker>();
|
||||
var log_action = new LogActionEx(LogActionType.AIChatGetCharacter);
|
||||
|
||||
var task_log_data = AIChatBusinessLogHelper.toLogInfo(url, string.Empty);
|
||||
invokers.Add(new AIChatBusinessLog(task_log_data));
|
||||
|
||||
BusinessLogger.collectLogs(log_action, player, invokers);
|
||||
try
|
||||
{
|
||||
var aichat_character = JsonConvert.DeserializeObject<AIChatCharacter>(resMsg);
|
||||
return (result, aichat_character);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Log.getLogger().error($"Exception !!!, DeserializeObject : exception:{ex}, resMsg:{resMsg}");
|
||||
return (result, null);
|
||||
}
|
||||
}
|
||||
|
||||
//-------------유저 권한 API-------------
|
||||
//신규 캐릭터 등록
|
||||
public async Task<Result> registerCharacter(AIChatRegisterCharacter aIChatRegisterCharacter)
|
||||
{
|
||||
var player = getOwner() as Player;
|
||||
NullReferenceCheckHelper.throwIfNull(player, () => $"player is null !!!");
|
||||
|
||||
var url = $"/api/character";
|
||||
var body = JsonConvert.SerializeObject(aIChatRegisterCharacter);
|
||||
|
||||
(var result, string resMsg) = await AIChatServerConnector.sendAIChatServerWithServerJwt("POST", url, body);
|
||||
if (result.isFail())
|
||||
{
|
||||
Log.getLogger().error($"Failed ai chat server action : registerCharacter, msg : {resMsg}");
|
||||
return result;
|
||||
}
|
||||
|
||||
var invokers = new List<ILogInvoker>();
|
||||
var log_action = new LogActionEx(LogActionType.AIChatRegisterCharacter);
|
||||
|
||||
var task_log_data = AIChatBusinessLogHelper.toLogInfo(url, body);
|
||||
invokers.Add(new AIChatBusinessLog(task_log_data));
|
||||
|
||||
BusinessLogger.collectLogs(log_action, player, invokers);
|
||||
|
||||
return result;
|
||||
}
|
||||
//캐릭터 수정
|
||||
public async Task<Result> updateCharacter(AIChatRegisterCharacter aIChatRegisterCharacter)
|
||||
{
|
||||
var player = getOwner() as Player;
|
||||
NullReferenceCheckHelper.throwIfNull(player, () => $"player is null !!!");
|
||||
|
||||
var url = $"/api/character/locale/{aIChatRegisterCharacter.guid}";
|
||||
var body = JsonConvert.SerializeObject(aIChatRegisterCharacter);
|
||||
|
||||
(var result, string resMsg) = await AIChatServerConnector.sendAIChatServerWithServerJwt("PUT", url, body);
|
||||
if (result.isFail()) return result;
|
||||
|
||||
var invokers = new List<ILogInvoker>();
|
||||
var log_action = new LogActionEx(LogActionType.AIChatUpdateCharacter);
|
||||
|
||||
var task_log_data = AIChatBusinessLogHelper.toLogInfo(url, body);
|
||||
invokers.Add(new AIChatBusinessLog(task_log_data));
|
||||
|
||||
BusinessLogger.collectLogs(log_action, player, invokers);
|
||||
|
||||
return result;
|
||||
}
|
||||
//캐릭터 등록 제거
|
||||
public async Task<Result> deleteCharacter(string character_guid)
|
||||
{
|
||||
var player = getOwner() as Player;
|
||||
NullReferenceCheckHelper.throwIfNull(player, () => $"player is null !!!");
|
||||
|
||||
var url = $"/api/character/{character_guid}";
|
||||
|
||||
(var result, string resMsg) = await AIChatServerConnector.sendAIChatServerWithServerJwt("DELETE", url, null);
|
||||
if (result.isFail()) return result;
|
||||
|
||||
var invokers = new List<ILogInvoker>();
|
||||
var log_action = new LogActionEx(LogActionType.AIChatDeleteCharacter);
|
||||
|
||||
var task_log_data = AIChatBusinessLogHelper.toLogInfo(url, string.Empty);
|
||||
invokers.Add(new AIChatBusinessLog(task_log_data));
|
||||
|
||||
BusinessLogger.collectLogs(log_action, player, invokers);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 데이터 수집 기간 : 월요일 00:00:00 ~ 일요일 23:59:59(KST 기준 - UTC+9)
|
||||
/// 인센티브 보상 지급 날짜 및 시각 : 매주 월요일 05:00 (KST 기준 - UTC+9)
|
||||
/// </summary>
|
||||
|
||||
public async Task<Result> updateTickOfIncentivePoint()
|
||||
{
|
||||
var result = new Result();
|
||||
var err_msg = string.Empty;
|
||||
|
||||
var player = getOwner() as Player;
|
||||
NullReferenceCheckHelper.throwIfNull(player, () => $"player is null !!!");
|
||||
|
||||
var current_time = DateTimeHelper.Current;
|
||||
var incentive_collect_time = current_time.AddDays(Convert.ToInt32(DayOfWeek.Monday) - Convert.ToInt32(current_time.DayOfWeek)).Date;
|
||||
var incentive_provide_time = incentive_collect_time.AddHours(5);
|
||||
|
||||
var ai_chat_attribute = player.getEntityAttribute<AiChatAttribute>();
|
||||
NullReferenceCheckHelper.throwIfNull(ai_chat_attribute, () => $"ai_chat_attribute is null !!! - {player.toBasicString()}");
|
||||
var last_incentive_provide_time = ai_chat_attribute.LastIncentiveProvideTime;
|
||||
|
||||
if (last_incentive_provide_time != default ||
|
||||
last_incentive_provide_time == incentive_provide_time ||
|
||||
incentive_provide_time > current_time)
|
||||
{
|
||||
return result;
|
||||
}
|
||||
|
||||
result = await TakeIncentivePoint(incentive_provide_time);
|
||||
if(result.isFail()) return result;
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
public async Task<Result> TakeIncentivePoint(DateTime new_incentive_provide_time)
|
||||
{
|
||||
var result = new Result();
|
||||
var err_msg = string.Empty;
|
||||
|
||||
var player = getOwner() as Player;
|
||||
NullReferenceCheckHelper.throwIfNull(player, () => $"player is null !!!");
|
||||
|
||||
var server_logic = GameServerApp.getServerLogic();
|
||||
var dynamo_db_client = server_logic.getDynamoDbClient();
|
||||
|
||||
var mail_action = player.getEntityAction<MailAction>();
|
||||
NullReferenceCheckHelper.throwIfNull(mail_action, () => $"mail_action is null !!!");
|
||||
|
||||
var ai_chat_attribute = player.getEntityAttribute<AiChatAttribute>();
|
||||
NullReferenceCheckHelper.throwIfNull(ai_chat_attribute, () => $"ai_chat_attribute is null !!! - {player.toBasicString()}");
|
||||
|
||||
if (MetaData.Instance._CurrencyMetaTableByCurrencyType.TryGetValue(CurrencyType.Beam, out var currencyMetaData) == false)
|
||||
{
|
||||
result.setFail(ServerErrorCode.CurrencyNotFoundData, err_msg);
|
||||
return result;
|
||||
}
|
||||
|
||||
(result, var pointClaim) = await pointClaimables(0, 100, player.getUserGuid());
|
||||
if (result.isFail())
|
||||
{
|
||||
return result;
|
||||
}
|
||||
|
||||
NullReferenceCheckHelper.throwIfNull(pointClaim, () => $"pointClaim is null !!! - {toBasicString()}");
|
||||
if (pointClaim.items.Count == 0)
|
||||
{
|
||||
ai_chat_attribute.LastIncentiveProvideTime = new_incentive_provide_time;
|
||||
ai_chat_attribute.modifiedEntityAttribute();
|
||||
|
||||
(result, var ai_chat_doc) = await ai_chat_attribute.toDocBase();
|
||||
if (result.isFail()) return result;
|
||||
NullReferenceCheckHelper.throwIfNull(ai_chat_doc, () => $"ai_chat_doc is null !!! - {player.toBasicString()}");
|
||||
|
||||
result = await dynamo_db_client.simpleUpdateDocumentWithDocType(ai_chat_doc);
|
||||
if (result.isFail())
|
||||
{
|
||||
err_msg = $"Failed to simpleUpdateDocumentWithDocType ai_chat_doc !!! - {player.toBasicString()}";
|
||||
Log.getLogger().error(err_msg);
|
||||
return result;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
var IncentivePointList = new List<int>();
|
||||
int maxPoint = GameConfigMeta.AiChatInsentiveMax;
|
||||
int last_incentive_period = 0;
|
||||
|
||||
foreach (var pointInfo in pointClaim.items)
|
||||
{
|
||||
int amount = pointInfo.amount;
|
||||
if(maxPoint < amount)
|
||||
{
|
||||
amount = maxPoint;
|
||||
}
|
||||
|
||||
IncentivePointList.Add(amount);
|
||||
if(last_incentive_period < pointInfo.end_time)
|
||||
{
|
||||
last_incentive_period = pointInfo.end_time;
|
||||
}
|
||||
}
|
||||
|
||||
var fn_send_system_mail = async delegate ()
|
||||
{
|
||||
var result = new Result();
|
||||
var err_msg = string.Empty;
|
||||
|
||||
var receivedMailDocs = new List<DynamoDbDocBase>();
|
||||
foreach (var amount in IncentivePointList)
|
||||
{
|
||||
var mail_items = new List<ServerCommon.MailItem>() { new ServerCommon.MailItem() { ItemId = (META_ID)currencyMetaData.ItemId, Count = amount } };
|
||||
(result, var receivedMailDoc) = await mail_action.tryMakeNewSystemMail(mail_items, ServerCommon.Constant.NPC_INSENTIVE_META_KEY, GameConfigMeta.AiChatInsentivePeriod, string.Empty);
|
||||
if (result.isFail())
|
||||
{
|
||||
return result;
|
||||
}
|
||||
NullReferenceCheckHelper.throwIfNull(receivedMailDoc, () => $"receivedMailDoc is null !!! - {toBasicString()}");
|
||||
receivedMailDocs.Add(receivedMailDoc);
|
||||
}
|
||||
|
||||
ai_chat_attribute.LastIncentiveProvideTime = new_incentive_provide_time;
|
||||
|
||||
var batch = new QueryBatchEx<QueryRunnerWithDocument>(player, LogActionType.MailAiChatIncentivePoint
|
||||
, dynamo_db_client);
|
||||
{
|
||||
batch.addQuery(new DBQEntityWrite(receivedMailDocs));
|
||||
batch.addQuery(new DBQWriteToAttributeAllWithTransactionRunner());
|
||||
}
|
||||
|
||||
result = await QueryHelper.sendQueryAndBusinessLog(batch);
|
||||
if (result.isFail())
|
||||
{
|
||||
return result;
|
||||
}
|
||||
|
||||
result = await pointMarkClaimed(player.getUserGuid(), last_incentive_period);
|
||||
if (result.isFail())
|
||||
{
|
||||
return result;
|
||||
}
|
||||
|
||||
mail_action.NewReceivedMail();
|
||||
|
||||
return result;
|
||||
};
|
||||
|
||||
var transaction_name = "provideIncentivePoint";
|
||||
result = await player.runTransactionRunnerSafelyWithTransGuid(player.getUserGuid()
|
||||
, TransactionIdType.PrivateContents, transaction_name
|
||||
, fn_send_system_mail);
|
||||
if (result.isFail())
|
||||
{
|
||||
err_msg = $"Failed to runTransactionRunnerSafelyWithTransGuid() !!! : {result.toBasicString()} - transactionName:{transaction_name}, {player.toBasicString()}";
|
||||
Log.getLogger().error(err_msg);
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
}
|
||||
}
|
||||
216
GameServer/Contents/AIChat/Action/AIChatSchema.cs
Normal file
216
GameServer/Contents/AIChat/Action/AIChatSchema.cs
Normal file
@@ -0,0 +1,216 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
|
||||
using ServerCommon;
|
||||
|
||||
|
||||
using META_ID = System.UInt32;
|
||||
|
||||
|
||||
|
||||
namespace GameServer;
|
||||
|
||||
public class AIChatJwt
|
||||
{
|
||||
public string messageBase64 { get; set; } = string.Empty;
|
||||
public string signatureBase64 { get; set; } = string.Empty;
|
||||
}
|
||||
|
||||
public class AIChatPointVerify
|
||||
{
|
||||
public string orderGuid { get; set; } = string.Empty;
|
||||
}
|
||||
|
||||
public class AIChatError
|
||||
{
|
||||
public int code { get; set; } = 0;
|
||||
public string name { get; set; } = string.Empty;
|
||||
public string message { get; set; } = string.Empty;
|
||||
}
|
||||
|
||||
public class AIChatJwtInfo
|
||||
{
|
||||
public string guid { get; set; } = string.Empty;
|
||||
public string role { get; set; } = string.Empty;
|
||||
public int iat { get; set; } = 0;
|
||||
public int exp { get; set; } = 0;
|
||||
}
|
||||
|
||||
public class AIChatRegisterCharacter
|
||||
{
|
||||
public string guid { get; set; } = string.Empty;
|
||||
public string ownerUserGuid { get; set; } = string.Empty;
|
||||
public string lang { get; set; } = string.Empty;
|
||||
public string name { get; set; } = string.Empty;
|
||||
public string persona { get; set; } = string.Empty;
|
||||
public string firstMes { get; set; } = string.Empty;
|
||||
public string secrets { get; set; } = string.Empty; // Not Used
|
||||
public string shortDesc { get; set; } = string.Empty;
|
||||
|
||||
public List<META_ID> tags { get; set; } = new();
|
||||
public bool isOfficial { get; set; } = false;
|
||||
|
||||
public List<AIChatSocialActionConfig> socialActionConfig = new();
|
||||
|
||||
public AIChatCharacterAttribute attributes { get; set; } = new();
|
||||
}
|
||||
|
||||
public class AIChatCharacterAttribute
|
||||
{
|
||||
public int gender { get; set; } = 0;
|
||||
}
|
||||
|
||||
public class AIChatIssueJwt
|
||||
{
|
||||
public string jwt { get; set; } = string.Empty;
|
||||
}
|
||||
|
||||
public class AIChatSocialActionConfig
|
||||
{
|
||||
public int id { get; set; } = 0;
|
||||
public float weight { get; set; } = 0;
|
||||
}
|
||||
|
||||
public class AIChatPointClaimables
|
||||
{
|
||||
public int page { get; set; } = 0;
|
||||
public int numPerPage { get; set; } = 0;
|
||||
public int total { get; set; } = 0;
|
||||
public List<AIChatPointClaimablesItems> items { get; set; } = new();
|
||||
}
|
||||
|
||||
public class AIChatPointClaimablesItems
|
||||
{
|
||||
public int start_time { get; set; } = 0;
|
||||
public int end_time { get; set; } = 0;
|
||||
public int amount { get; set; } = 0;
|
||||
public int log_count { get; set; } = 0;
|
||||
}
|
||||
|
||||
public class AIChatPointHistory
|
||||
{
|
||||
public int page { get; set; } = 0;
|
||||
public int numPerPage { get; set; } = 0;
|
||||
public int total { get; set; } = 0;
|
||||
public List<AIChatPointHistoryItems> items { get; set; } = new();
|
||||
}
|
||||
|
||||
public class AIChatPointHistoryItems
|
||||
{
|
||||
public string created_date { get; set; } = string.Empty;
|
||||
public int sum_of_spend_free { get; set; } = 0;
|
||||
public int sum_of_earn_free { get; set; } = 0;
|
||||
public int sum_of_charge_free { get; set; } = 0;
|
||||
public int sum_of_spend_nonfree { get; set; } = 0;
|
||||
public int sum_of_earn_nonfree { get; set; } = 0;
|
||||
public int sum_of_charge_nonfree { get; set; } = 0;
|
||||
public int free_points_balance { get; set; } = 0;
|
||||
public int nonfree_points_balance { get; set; } = 0;
|
||||
}
|
||||
|
||||
public class AIChatPointCharge
|
||||
{
|
||||
public double points { get; set; } = 0;
|
||||
public string pointType { get; set; } = string.Empty;
|
||||
public string userGuid { get; set; } = string.Empty;
|
||||
public string orderGuid { get; set; } = string.Empty;
|
||||
public string description { get; set; } = string.Empty;
|
||||
}
|
||||
|
||||
public class AIChatSetting
|
||||
{
|
||||
public string id { get; set; } = string.Empty;
|
||||
public string model { get; set; } = string.Empty;
|
||||
public AIChatPoint point { get; set; } = new AIChatPoint();
|
||||
public bool enabled { get; set; } = false;
|
||||
public int token_limit { get; set; } = 0;
|
||||
public AIChatOptions options { get; set; } = new AIChatOptions();
|
||||
}
|
||||
|
||||
public class AIChatPoint
|
||||
{
|
||||
public int cost { get; set; } = 0;
|
||||
public int share { get; set; } = 0;
|
||||
}
|
||||
|
||||
public class AIChatOptions
|
||||
{
|
||||
public float temperature { get; set; } = 0;
|
||||
public float top_p { get; set; } = 0;
|
||||
}
|
||||
|
||||
public class AIChatRegisterUser
|
||||
{
|
||||
public string nick { get; set; } = string.Empty;
|
||||
public AIChatRegisterUserSetting settings { get; set; } = new();
|
||||
}
|
||||
|
||||
public class AIChatRegisterUserSetting
|
||||
{
|
||||
public string defaultModel { get; set; } = ServerCommon.Constant.AI_CHAT_DEFAULT_MODEL;
|
||||
}
|
||||
|
||||
public class AIChatRanking
|
||||
{
|
||||
public List<AIChatRankingData> items { get; set; } = new();
|
||||
public int page { get; set; } = 0;
|
||||
public int numPerPage { get; set; } = 0;
|
||||
public int total { get; set; } = 0;
|
||||
public int start_at { get; set; } = 0;
|
||||
public int end_at { get; set; } = 0;
|
||||
}
|
||||
public class AIChatRankingData
|
||||
{
|
||||
public string char_guid { get; set; } = string.Empty;
|
||||
public string owner_guid { get; set; } = string.Empty;
|
||||
public string owner_nick { get; set; } = string.Empty;
|
||||
public string char_name { get; set; } = string.Empty;
|
||||
public int total_chat_count { get; set; } = 0;
|
||||
}
|
||||
|
||||
public class AIChatCharacter
|
||||
{
|
||||
public string itemId { get; set; } = string.Empty;
|
||||
public AIChatCharacterInfo data { get; set; } = new();
|
||||
}
|
||||
|
||||
public class AIChatCharacterInfo
|
||||
{
|
||||
public string guid { get; set; } = string.Empty;
|
||||
public string owner_guid { get; set; } = string.Empty;
|
||||
public Int64 chat_count { get; set; } = 0;
|
||||
|
||||
public List<AIChatSocialActionConfig> socialActionConfig = new();
|
||||
|
||||
public string created_at { get; set; } = string.Empty;
|
||||
public string updated_at { get; set; } = string.Empty;
|
||||
public bool is_official { get; set; } = false;
|
||||
|
||||
public AiChatCharacterLocales locale { get; set; } = new();
|
||||
|
||||
public List<META_ID> tags { get; set; } = new();
|
||||
}
|
||||
|
||||
public class AiChatCharacterLocales
|
||||
{
|
||||
AiChatCharacterLocale en = new();
|
||||
AiChatCharacterLocale ko = new();
|
||||
AiChatCharacterLocale ja = new();
|
||||
}
|
||||
|
||||
public class AiChatCharacterLocale
|
||||
{
|
||||
public string id { get; set; } = string.Empty;
|
||||
public string lang { get; set; } = string.Empty;
|
||||
public string name { get; set; } = string.Empty;
|
||||
public string persona { get; set; } = string.Empty;
|
||||
public string first_mes { get; set; } = string.Empty;
|
||||
public string secrets { get; set; } = string.Empty;
|
||||
public string short_desc { get; set; } = string.Empty;
|
||||
public string created_at { get; set; } = string.Empty;
|
||||
public string updated_at { get; set; } = string.Empty;
|
||||
}
|
||||
32
GameServer/Contents/AIChat/Log/AIChatBusinessLog.cs
Normal file
32
GameServer/Contents/AIChat/Log/AIChatBusinessLog.cs
Normal file
@@ -0,0 +1,32 @@
|
||||
using Google.Protobuf;
|
||||
using Google.Protobuf.WellKnownTypes;
|
||||
|
||||
|
||||
using ServerCore;
|
||||
using ServerBase;
|
||||
using ServerCommon;
|
||||
using ServerCommon.BusinessLogDomain;
|
||||
using MetaAssets;
|
||||
|
||||
|
||||
namespace GameServer;
|
||||
|
||||
public class AIChatBusinessLog : ILogInvokerEx
|
||||
{
|
||||
private AIChatLogData m_data_to_log;
|
||||
public AIChatBusinessLog(AIChatLogData log_data_param)
|
||||
: base(LogDomainType.AIChat)
|
||||
{
|
||||
m_data_to_log = log_data_param;
|
||||
}
|
||||
|
||||
public override bool hasLog()
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
protected override void fillup(ref BusinessLog.LogBody body)
|
||||
{
|
||||
body.append(new AIChatLogData(this, m_data_to_log));
|
||||
}
|
||||
}
|
||||
25
GameServer/Contents/AIChat/Log/AIChatBusinessLogHelper.cs
Normal file
25
GameServer/Contents/AIChat/Log/AIChatBusinessLogHelper.cs
Normal file
@@ -0,0 +1,25 @@
|
||||
using ServerCommon;
|
||||
using ServerCommon.BusinessLogDomain;
|
||||
|
||||
|
||||
using META_ID = System.UInt32;
|
||||
|
||||
|
||||
namespace GameServer
|
||||
{
|
||||
static public class AIChatBusinessLogHelper
|
||||
{
|
||||
static public AIChatLogData toLogInfo(string URL, string bodyParamJson)
|
||||
{
|
||||
var logData = new AIChatLogData();
|
||||
logData.setInfo(URL, bodyParamJson);
|
||||
return logData;
|
||||
}
|
||||
|
||||
static public void setInfo(this AIChatLogData logData, string URL, string bodyParamJson)
|
||||
{
|
||||
logData.AIChatURL = URL;
|
||||
logData.AIChatBodyParamJson = bodyParamJson;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,97 @@
|
||||
using Google.Protobuf;
|
||||
|
||||
|
||||
using ServerCore;
|
||||
using ServerBase;
|
||||
using ServerCommon;
|
||||
|
||||
|
||||
using static ClientToGameRes.Types;
|
||||
|
||||
|
||||
namespace GameServer.PacketHandler
|
||||
{
|
||||
[PacketHandler(typeof(ClientToGameReq), typeof(ClientToGameReq.Types.C2GS_REQ_AICHAT_AUTH), typeof(AIChatAuthPacketHandler), typeof(GameLoginListener))]
|
||||
public class AIChatAuthPacketHandler : PacketRecvHandler
|
||||
{
|
||||
public static bool send_S2C_ACK_AICHAT_AUTH(Player player, Result result, string? jwt = null, int leftTime = 0)
|
||||
{
|
||||
var err_msg = string.Empty;
|
||||
|
||||
var ack_packet = new ClientToGame();
|
||||
ack_packet.Response = new ClientToGameRes();
|
||||
|
||||
ack_packet.Response.ErrorCode = result.ErrorCode;
|
||||
ack_packet.Response.AckAIChatAuth = new GS2C_ACK_AICHAT_AUTH();
|
||||
ack_packet.Response.AckAIChatAuth.Jwt = jwt ?? string.Empty;
|
||||
ack_packet.Response.AckAIChatAuth.LeftTime = leftTime;
|
||||
|
||||
if (false == GameServerApp.getServerLogic().onSendPacket(player, ack_packet))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
public override async Task<Result> onProcessPacket(ISession entityWithSession, IMessage recvMessage)
|
||||
{
|
||||
var result = new Result();
|
||||
var err_msg = string.Empty;
|
||||
|
||||
var player = entityWithSession as Player;
|
||||
NullReferenceCheckHelper.throwIfNull(player, () => $"player is null !!!");
|
||||
|
||||
var player_action = player.getEntityAction<PlayerAction>();
|
||||
NullReferenceCheckHelper.throwIfNull(player_action, () => $"player_action is null !!! - {player.toBasicString()}");
|
||||
|
||||
var ai_chat_action = player.getEntityAction<AIChatAction>();
|
||||
NullReferenceCheckHelper.throwIfNull(ai_chat_action, () => $"ai_chat_action is null !!! - {player.toBasicString()}");
|
||||
|
||||
(result, var jwt) = await ai_chat_action.jwtIssue(player.getUserGuid());
|
||||
if(result.ErrorCode == ServerErrorCode.AiChatServerUserNotFound)
|
||||
{
|
||||
result = await ai_chat_action.registerUser(player.getUserGuid(), player.getUserNickname());
|
||||
if (result.isFail())
|
||||
{
|
||||
err_msg = $"Failed Register User : {player.getUserGuid()}";
|
||||
Log.getLogger().error(err_msg);
|
||||
send_S2C_ACK_AICHAT_AUTH(player, result);
|
||||
return result;
|
||||
}
|
||||
|
||||
(result, jwt) = await ai_chat_action.jwtIssue(player.getUserGuid());
|
||||
}
|
||||
|
||||
if(result.isFail() || string.IsNullOrEmpty(jwt))
|
||||
{
|
||||
send_S2C_ACK_AICHAT_AUTH(player, result);
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
(result, var jwtInfo) = await ai_chat_action.jwtverify(jwt);
|
||||
if (result.isFail() || jwt == null)
|
||||
{
|
||||
send_S2C_ACK_AICHAT_AUTH(player, result);
|
||||
return result;
|
||||
}
|
||||
NullReferenceCheckHelper.throwIfNull(jwtInfo, () => $"jwtInfo is null !!");
|
||||
|
||||
send_S2C_ACK_AICHAT_AUTH(player, result, jwt, jwtInfo.exp - jwtInfo.iat);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
public override async Task onProcessPacketException(ISession entityWithSession, IMessage recvMessage
|
||||
, Result errorResult)
|
||||
{
|
||||
await Task.CompletedTask;
|
||||
|
||||
var player = entityWithSession as Player;
|
||||
NullReferenceCheckHelper.throwIfNull(player, () => $"player is null !!! - {entityWithSession.toBasicString()}");
|
||||
|
||||
send_S2C_ACK_AICHAT_AUTH(player, errorResult);
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user