using Amazon.S3.Model; using Google.Protobuf.WellKnownTypes; using RabbitMQ.Client; using ServerCommon; using ServerCore; using ServerBase; using System; using System.Collections.Concurrent; using System.Collections.Generic; using System.Diagnostics.CodeAnalysis; using System.Linq; using System.Security.Claims; using System.Text; using System.Threading.Tasks; namespace GameServer { public class ClaimAction : EntityActionBase { private ConcurrentDictionary m_normal_claim { get; set; } = new(); private ConcurrentDictionary m_membership_claim { get; set; } = new(); private bool m_data_load = false; public ClaimAction(EntityBase owner) : base(owner) { } public override Task onInit() { var result = new Result(); return Task.FromResult(result); } public void setDataLoad(bool isLoad) { m_data_load = isLoad; } public bool getDataLoad() { return m_data_load; } public Result setClaimFromDoc(ClaimDoc doc) { var result = new Result(); var owner = getOwner(); NullReferenceCheckHelper.throwIfNull(owner, () => $"owner is null !!!"); EntityBase claim; var claim_attrib = doc.getAttrib(); NullReferenceCheckHelper.throwIfNull(claim_attrib, () => $"claim_attrib is null !!!"); claim = new ServerCommon.Claim(owner, claim_attrib.ClaimType); var claim_attribute = claim.getEntityAttribute(); NullReferenceCheckHelper.throwIfNull(claim_attribute, () => $"claim_attribute is null !!!"); if (false == doc.getAttribWrappers().TryGetValue(typeof(ClaimAttrib), out var to_copy_doc_attrib)) { var err_msg = $"Fail to get ClaimAttrib"; result.setFail(ServerErrorCode.EntityAttributeNotFound, err_msg); return result; } var attrib_base = to_copy_doc_attrib.getAttribBase(); var doc_attrib = attrib_base as ClaimAttrib; if (doc_attrib is null) { var err_msg = $"Fail to get ClaimAttrib"; result.setFail(ServerErrorCode.EntityAttributeNotFound, err_msg); return result; } claim_attribute.ClaimType = doc_attrib.ClaimType; claim_attribute.ActiveRewardIdx = doc_attrib.ActiveRewardIdx; claim_attribute.ActiveTime = doc_attrib.ActiveTime; claim_attribute.CreateTime = doc_attrib.CreateTime; claim_attribute.CompleteTime = doc_attrib.CompleteTime; claim_attribute.IsComplete = doc_attrib.IsComplete; claim_attribute.syncOriginDocBaseWithNewDoc(doc); Int32 claim_id = claim_attribute.ClaimId = doc_attrib.ClaimId; var casted_claim = claim as ServerCommon.Claim; NullReferenceCheckHelper.throwIfNull(casted_claim, () => $"casted_claim is null !!!"); if (claim_attrib.ClaimType == MetaAssets.ClaimType.Normal) { m_normal_claim.TryAdd(claim_id, casted_claim); } else { m_membership_claim.TryAdd(claim_id, casted_claim); } return result; } public async Task<(Result, List, List)> update() { var result = new Result(); var owner = getOwner() as Player; NullReferenceCheckHelper.throwIfNull(owner, () => $"owner is null !!!"); (var acceptable_claims, var old_claims) = getUpdatableClaims(); if (acceptable_claims.Count == 0 && old_claims.Count == 0) return (result, new(), new()); result = await owner.runTransactionRunnerSafelyWithTransGuid( owner.getUserGuid() , TransactionIdType.PrivateContents, "ClaimUpdate", delegateUpdateClaim); if (result.isFail()) { string err_msg = $"Failed to runTransactionRunnerSafelyWithTransGuid() !!! : {result.toBasicString()} - {owner.toBasicString()}"; Log.getLogger().error(err_msg); return (result, new(), new()); } return (result, acceptable_claims, old_claims); async Task delegateUpdateClaim() => await updateClaim(owner, acceptable_claims, old_claims); } public (List, List) getUpdatableClaims() { var acceptable_claims = getAcceptableClaims(); var old_claims = getOldClaim(); return (acceptable_claims, old_claims); } public static List getOldClaims() { List rets = new(); DateTime nowDt = DateTimeHelper.Current; foreach (ClaimMetaData metaData in MetaData.Instance._ClaimMetaTable.Values) { if (metaData.EndTime < nowDt) { rets.Add(metaData); } } return rets; } private async Task updateClaim(Player owner, List acceptableClaim, List oldClaim) { (var result, var new_claims) = updateClaims(acceptableClaim, oldClaim); if (result.isFail()) return result; var server_logic = GameServerApp.getServerLogic(); var batch = new QueryBatchEx(owner, LogActionType.None, server_logic.getDynamoDbClient()); { batch.addQuery(new DBQWriteToAttributeAllWithTransactionRunner()); } result = await QueryHelper.sendQueryAndBusinessLog(batch); if (result.isFail()) { return result; } foreach (var new_claim in new_claims) { var claim_attribute = new_claim.getEntityAttribute(); NullReferenceCheckHelper.throwIfNull(claim_attribute, () => $"claim_attribute is null !!!"); if (claim_attribute.ClaimType == MetaAssets.ClaimType.Normal) { m_normal_claim.TryAdd(claim_attribute.ClaimId, new_claim as ServerCommon.Claim); } else { m_membership_claim.TryAdd(claim_attribute.ClaimId, new_claim as ServerCommon.Claim); } } foreach (var old_claim in oldClaim) { m_normal_claim.TryRemove(old_claim, out _); m_membership_claim.TryRemove(old_claim, out _); } return result; } private (Result, List) updateClaims(List acceptable_claims, List oldClaims) { var result = new Result(); DateTime now = DateTimeHelper.Current; List claims = new(); foreach (var meta in acceptable_claims) { var claim_id = meta.ClaimId; var claim_type = meta.ClaimType; if (claim_type == MetaAssets.ClaimType.Normal) { if (m_normal_claim.ContainsKey(claim_id)) continue; } else { if (m_membership_claim.ContainsKey(claim_id)) continue; } var new_claim = makeNewClaim(now, meta); claims.Add(new_claim); //m_normal_claim.TryAdd(claim_id, normal_claim); } foreach (var old_claim in oldClaims) { if (false == m_normal_claim.TryGetValue(old_claim, out var normal_claim)) continue; NullReferenceCheckHelper.throwIfNull(normal_claim, () => $"normal_claim is null !!!"); var normal_claim_attribute = normal_claim.getEntityAttribute(); NullReferenceCheckHelper.throwIfNull(normal_claim_attribute, () => $"normal_claim_attribute is null !!!"); normal_claim_attribute.deleteEntityAttribute(); } foreach (var old_claim in oldClaims) { if (false == m_membership_claim.TryGetValue(old_claim, out var membership_claim)) continue; NullReferenceCheckHelper.throwIfNull(membership_claim, () => $"membership_claim is null !!!"); var membership_claim_attribute = membership_claim.getEntityAttribute(); NullReferenceCheckHelper.throwIfNull(membership_claim_attribute, () => $"membership_claim_attribute is null !!!"); membership_claim_attribute.deleteEntityAttribute(); } return (result, claims); } private ServerCommon.Claim resetClaim(ServerCommon.Claim claim, ClaimMetaData metaData) { var owner = getOwner() as Player; DateTime now = DateTimeHelper.Current; var claim_attribute = claim.getEntityAttribute(); NullReferenceCheckHelper.throwIfNull(claim_attribute, () => $"claim_attribute is null !!!"); claim_attribute.ActiveRewardIdx = metaData.DetailInfo.First().Value.Idx; claim_attribute.ActiveTime = now; claim_attribute.CreateTime = now; claim_attribute.CompleteTime = now; claim_attribute.IsComplete = 0; claim_attribute.modifiedEntityAttribute(); return claim; } private ServerCommon.Claim updateClaimRewardable(ServerCommon.Claim claim, ClaimMetaData metaData) { var owner = getOwner() as Player; DateTime now = DateTimeHelper.Current; var claim_attribute = claim.getEntityAttribute(); NullReferenceCheckHelper.throwIfNull(claim_attribute, () => $"claim_attribute is null !!!"); claim_attribute.ActiveTime = now.AddSeconds(-86400); claim_attribute.modifiedEntityAttribute(); return claim; } private ServerCommon.Claim makeNewClaim(DateTime now, ClaimMetaData metaData) { var owner = getOwner() as Player; NullReferenceCheckHelper.throwIfNull(owner, () => $"owner is null !!!"); var claim = new ServerCommon.Claim(getOwner(), metaData.ClaimType); var claim_attribute = claim.getEntityAttribute(); NullReferenceCheckHelper.throwIfNull(claim_attribute, () => $"claim_attribute is null !!!"); claim_attribute.ClaimId = metaData.ClaimId; claim_attribute.ClaimType = metaData.ClaimType; claim_attribute.ActiveRewardIdx = metaData.DetailInfo.First().Value.Idx; claim_attribute.ActiveTime = now; claim_attribute.CreateTime = now; claim_attribute.CompleteTime = now; claim_attribute.IsComplete = 0; var new_claim_doc = new ClaimDoc(owner.getUserGuid(), metaData.ClaimType, metaData.ClaimId); claim_attribute.syncOriginDocBaseWithNewDoc(new_claim_doc); var claim_attrib = new_claim_doc.getAttrib(); NullReferenceCheckHelper.throwIfNull(claim_attrib, () => $"claim_attrib is null !!!"); claim_attrib.ClaimId = metaData.ClaimId; claim_attrib.ClaimType = metaData.ClaimType; claim_attrib.ActiveRewardIdx = metaData.DetailInfo.First().Value.Idx; claim_attrib.ActiveTime = now; claim_attrib.CreateTime = now; claim_attrib.CompleteTime = now; claim_attrib.IsComplete = 0; claim_attribute.newEntityAttribute(); return claim; } private List getAcceptableClaims() { var owner = getOwner() as Player; NullReferenceCheckHelper.throwIfNull(owner, () => $"owner is null !!!"); List rets = new(); var current_metas = ClaimRewardHelper.getCurrentClaims(); foreach (var metaData in current_metas) { var claim_id = metaData.GetMetaId(); if (m_normal_claim.ContainsKey(claim_id)) continue; rets.Add(metaData); } return rets; } public List getOldClaim() { List old_metas = getOldClaims(); List old_claims = new(); foreach (var meta in old_metas) { var claim_id = meta.ClaimId; if (m_normal_claim.ContainsKey(claim_id)) { old_claims.Add(claim_id); } } return old_claims; } public async Task cheatClaimReset() { var player = getOwner() as Player; NullReferenceCheckHelper.throwIfNull(player, () => $"player is null !!!"); var server_logic = GameServerApp.getServerLogic(); var result = new Result(); var fn_reset_claim = async delegate () { var result = new Result(); var err_msg = string.Empty; List log_invokers = new(); foreach (var normal_claim in m_normal_claim.Values) { var normal_claim_attribute = normal_claim.getEntityAttribute(); NullReferenceCheckHelper.throwIfNull(normal_claim_attribute, () => $"normal_claim_attribute is null !!!"); var claim_id = normal_claim_attribute.ClaimId; (result, var claim_meta) = ClaimRewardHelper.getClaimMeta(claim_id, MetaAssets.ClaimType.Normal); if (result.isFail())continue; NullReferenceCheckHelper.throwIfNull(claim_meta, () => $"claim_meta is null !!!"); resetClaim(normal_claim, claim_meta); var log_invoker = new CheatClaimResetBusinessLog(MetaAssets.ClaimType.Normal, claim_id, normal_claim_attribute.ActiveRewardIdx); log_invokers.Add(log_invoker); } foreach (var membership_claim in m_membership_claim.Values) { var membership_claim_attribute = membership_claim.getEntityAttribute(); NullReferenceCheckHelper.throwIfNull(membership_claim_attribute, () => $"normal_claim_attribute is null !!!"); var claim_id = membership_claim_attribute.ClaimId; (result, var claim_meta) = ClaimRewardHelper.getClaimMeta(claim_id, MetaAssets.ClaimType.Membership); if (result.isFail()) continue; NullReferenceCheckHelper.throwIfNull(claim_meta, () => $"claim_meta is null !!!"); resetClaim(membership_claim, claim_meta); var log_invoker = new CheatClaimResetBusinessLog(MetaAssets.ClaimType.Membership, claim_id, membership_claim_attribute.ActiveRewardIdx); log_invokers.Add(log_invoker); } var batch = new QueryBatchEx(player, LogActionType.CheatCommandClaimReset, server_logic.getDynamoDbClient()); { batch.addQuery(new DBQWriteToAttributeAllWithTransactionRunner()); } result = await QueryHelper.sendQueryAndBusinessLog(batch); if (result.isFail()) { return result; } foreach (var normal_claim in m_normal_claim.Values) { var normal_claim_attribute = normal_claim.getEntityAttribute(); if (normal_claim_attribute is null) continue; var claim_id = normal_claim_attribute.ClaimId; } send_GS2C_NTF_CLAIM_UPDATE(); return result; }; result = await player.runTransactionRunnerSafely(TransactionIdType.PrivateContents, "CheatResetClaim", fn_reset_claim); if (result.isFail()) { var err_msg = $"Failed to runTransactionRunnerSafely() !!! : {result.toBasicString()} - {player.toBasicString()}"; Log.getLogger().error(err_msg); return; } } public async Task cheatClaimUpdateRewardable() { var player = getOwner() as Player; NullReferenceCheckHelper.throwIfNull(player, () => $"server_logic is null !!!"); var server_logic = GameServerApp.getServerLogic(); var result = new Result(); var fn_claim_update_rewardable = async delegate () { var result = new Result(); var err_msg = string.Empty; List log_invokers = new(); foreach (var normal_claim in m_normal_claim.Values) { var normal_claim_attribute = normal_claim.getEntityAttribute(); if (normal_claim_attribute is null) continue; var claim_id = normal_claim_attribute.ClaimId; (result, var claim_meta) = ClaimRewardHelper.getClaimMeta(claim_id, MetaAssets.ClaimType.Normal); if (result.isFail()) continue; NullReferenceCheckHelper.throwIfNull(claim_meta, () => $"claim_meta is null !!!"); updateClaimRewardable(normal_claim, claim_meta); var log_invoker = new CheatClaimRewardableBusinessLog(MetaAssets.ClaimType.Normal, claim_id, normal_claim_attribute.ActiveRewardIdx); log_invokers.Add(log_invoker); } foreach (var membership_claim in m_membership_claim.Values) { var membership_claim_attribute = membership_claim.getEntityAttribute(); if (membership_claim_attribute is null) continue; var claim_id = membership_claim_attribute.ClaimId; (result, var claim_meta) = ClaimRewardHelper.getClaimMeta(claim_id, MetaAssets.ClaimType.Membership); if (result.isFail()) continue; NullReferenceCheckHelper.throwIfNull(claim_meta, () => $"claim_meta is null !!!"); updateClaimRewardable(membership_claim, claim_meta); var log_invoker = new CheatClaimRewardableBusinessLog(MetaAssets.ClaimType.Membership, claim_id, membership_claim_attribute.ActiveRewardIdx); log_invokers.Add(log_invoker); } var batch = new QueryBatchEx(player, LogActionType.CheatCommandClaimUpdate, server_logic.getDynamoDbClient()); { batch.addQuery(new DBQWriteToAttributeAllWithTransactionRunner()); } batch.appendBusinessLogs(log_invokers); result = await QueryHelper.sendQueryAndBusinessLog(batch); if (result.isFail()) { return result; } foreach (var normal_claim in m_normal_claim.Values) { var normal_claim_attribute = normal_claim.getEntityAttribute(); if(normal_claim_attribute is null) continue; var claim_id = normal_claim_attribute.ClaimId; } send_GS2C_NTF_CLAIM_UPDATE(); return result; }; result = await player.runTransactionRunnerSafely(TransactionIdType.PrivateContents, "CheatClaimUpdateRewardable", fn_claim_update_rewardable); if (result.isFail()) { var err_msg = $"Failed to runTransactionRunnerSafely() !!! : {result.toBasicString()} - {player.toBasicString()}"; Log.getLogger().error(err_msg); return; } } public ConcurrentDictionary getClaims(MetaAssets.ClaimType type) { if (type == MetaAssets.ClaimType.Normal) { return m_normal_claim; } else { return m_membership_claim; } } public Result getClaim(Int32 claimId, MetaAssets.ClaimType type, [MaybeNullWhen(false)] out ServerCommon.Claim? claim) { var result = new Result(); if (type == MetaAssets.ClaimType.Normal) { result = getNormalClaim(claimId, out claim); } else { result = getMembershipClaim(claimId, out claim); } return result; } public ConcurrentDictionary getNormalClaims() { return m_normal_claim; } public Result getNormalClaim(Int32 claimId, [MaybeNullWhen(false)] out ServerCommon.Claim? claim) { var result = new Result(); if (false == m_normal_claim.TryGetValue(claimId, out claim)) { var err_msg = $"m_normal_claim claimId : {claimId} not exist, {getOwner().toBasicString()}"; result.setFail(ServerErrorCode.ClaimInfoNotExist, err_msg); Log.getLogger().error(result.toBasicString()); return result; } NullReferenceCheckHelper.throwIfNull(claim, () => $"claim is null !!!"); return result; } public ConcurrentDictionary getMembershipClaims() { return m_membership_claim; } public Result getMembershipClaim(Int32 claimId, [MaybeNullWhen(false)] out ServerCommon.Claim? claim) { var result = new Result(); if (false == m_membership_claim.TryGetValue(claimId, out claim)) { var err_msg = $"m_membership_claim claimId : {claimId} not exist, {getOwner().toBasicString()}"; result.setFail(ServerErrorCode.ClaimInfoNotExist, err_msg); Log.getLogger().error(result.toBasicString()); return result; } NullReferenceCheckHelper.throwIfNull(claim, () => $"claim is null !!!"); return result; } public override void onClear() { return; } public void send_GS2C_NTF_CLAIM_UPDATE() { var player = getOwner() as Player; NullReferenceCheckHelper.throwIfNull(player, () => $"player is null !!!"); var server_logic = GameServerApp.getServerLogic(); NullReferenceCheckHelper.throwIfNull(server_logic, () => $"server_logic is null !!!"); var normal_claim_infos = ClaimRewardHelper.MakeClaimSendInfo(player, MetaAssets.ClaimType.Normal); var membership_claim_infos = ClaimRewardHelper.MakeClaimSendInfo(player, MetaAssets.ClaimType.Membership); foreach (var info in normal_claim_infos) { ClientToGame ntf_packet = new(); ntf_packet.Message = new(); ntf_packet.Message.ClaimUpdateNoti = new(); ntf_packet.Message.ClaimUpdateNoti.ClaimId = info.Key; ntf_packet.Message.ClaimUpdateNoti.NormalInfo = info.Value; ntf_packet.Message.ClaimUpdateNoti.MembershipInfo = membership_claim_infos.TryGetValue(info.Key, out var membership_info) ? membership_info : new(); if (false == server_logic.onSendPacket(player, ntf_packet)) { Log.getLogger().error($"SendPacket Fail"); continue; } } } } }