using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; using Amazon.S3.Model; using Newtonsoft.Json; using Google.Protobuf.WellKnownTypes; using ServerCore; using ServerBase; using USER_GUID = System.String; namespace ServerCommon { public class LocationAttribute : EntityAttributeBase, ICopyEntityAttributeFromDoc, ICopyEntityAttributeFromCache, IMergeWithEntityAttribute { [JsonProperty] public ChannelServerLocation CurrentChannelServerLoaction { get; set; } = new(); [JsonProperty] public ChannelServerLocation LastestChannelServerLocation { get; set; } = new(); public IndunLocation ReJoinIndunLocation { get; set; } = new(); public List ReturnIndunLocations { get; set; } = new(); public IndunLocation EnterIndunLocation { get; set; } = new(); public IndunLocation CurrentIndunLocation { get; set; } = new(); public Timestamp MoveChannelTime { get; set; } = DateTimeHelper.MinTime.ToTimestamp(); public LocationAttribute(EntityBase owner) : base(owner) { } public override IEntityAttributeTransactor onNewEntityAttributeTransactor() { return new LocationAttributeTransactor(getOwner()); } public override void onClear() { LastestChannelServerLocation.clear(); ReJoinIndunLocation.clear(); ReturnIndunLocations.Clear(); EnterIndunLocation.clear(); CurrentIndunLocation.clear(); MoveChannelTime = DateTimeHelper.MinTime.ToTimestamp(); getAttributeState().reset(); } public override EntityAttributeBase onCloned() { var cloned = new LocationAttribute(getOwner()); cloned.deepCopyFromBase(this); cloned.LastestChannelServerLocation = LastestChannelServerLocation.clone(); cloned.ReJoinIndunLocation = ReJoinIndunLocation.clone(); cloned.ReturnIndunLocations = ReturnIndunLocations.Select(x => x.clone()).ToList(); cloned.EnterIndunLocation = EnterIndunLocation.clone(); cloned.CurrentIndunLocation = CurrentIndunLocation.clone(); cloned.MoveChannelTime = MoveChannelTime; return cloned; } public override async Task<(Result, DynamoDbDocBase?)> toDocBase(bool isForQuery = true) { var result = new Result(); var owner = getOwner(); NullReferenceCheckHelper.throwIfNull(owner, () => "owner is null !!!"); var user_attribute = owner.getRootParent().getEntityAttribute(); NullReferenceCheckHelper.throwIfNull(user_attribute, () => $"user_attribute is null !!! - {owner.toBasicString()}"); USER_GUID user_guid = user_attribute.UserGuid; //===================================================================================== // Attribute => try pending Doc //===================================================================================== var try_pending_doc = getTryPendingDocBase() as LocationDoc; if (null == try_pending_doc) { var to_copy_doc = new LocationDoc(user_guid); var origin_doc = getOriginDocBase(); if (null != origin_doc) { to_copy_doc.copyTimestampsFromOriginDocBase(origin_doc); } try_pending_doc = to_copy_doc; setTryPendingDocBase(try_pending_doc); } var to_copy_doc_attrib = try_pending_doc.getAttrib(); NullReferenceCheckHelper.throwIfNull(to_copy_doc_attrib, () => $"to_copy_doc_attrib is null !!! - {owner.toBasicString()}"); to_copy_doc_attrib.LastConnectedChannelServerLocation = LastestChannelServerLocation.clone(); to_copy_doc_attrib.ReJoinIndunLocation = ReJoinIndunLocation.clone(); if (false == isForQuery) { return (result, try_pending_doc); } //===================================================================================== // Doc QueryType 반영 //===================================================================================== (result, var to_query_doc) = await applyDoc4Query(try_pending_doc); if (result.isFail()) { return (result, null); } return (result, to_query_doc); } public bool copyEntityAttributeFromDoc(DynamoDbDocBase? docBase) { var err_msg = string.Empty; var to_cast_string = typeof(LocationDoc).Name; var location_doc_base = docBase as LocationDoc; if (null == location_doc_base) { err_msg = $"Failed to copyEntityAttributeFromDoc() !!!, location_doc_base is null :{to_cast_string}"; Log.getLogger().error(err_msg); return false; } //===================================================================================== // New Doc => Origin Doc //===================================================================================== syncOriginDocBaseWithNewDoc(location_doc_base); var doc_attrib = location_doc_base.getAttrib(); NullReferenceCheckHelper.throwIfNull(doc_attrib, () => "doc_attrib is null !!!"); LastestChannelServerLocation = doc_attrib.LastConnectedChannelServerLocation.clone(); ReJoinIndunLocation = doc_attrib.ReJoinIndunLocation.clone(); return true; } public bool copyEntityAttributeFromCache(CacheBase? cacheBase) { var err_msg = string.Empty; var to_cast_string = typeof(LocationCache).Name; var location_cache = cacheBase as LocationCache; if (null == location_cache) { err_msg = $"Failed to copyEntityAttributeFromCache() !!!, location_cache is null :{to_cast_string}"; Log.getLogger().error(err_msg); return false; } //===================================================================================== // Cache => Attribute //===================================================================================== LastestChannelServerLocation = location_cache.LastestChannelServerLocation.clone(); ReturnIndunLocations = location_cache.ReturnIndunLocations.Select(x => x.clone()).ToList(); EnterIndunLocation = location_cache.EnterIndunLocation.clone(); MoveChannelTime = location_cache.MoveChannelTime; return true; } public Result onMerge(EntityAttributeBase otherEntityAttribute) { var owner = getOwner(); NullReferenceCheckHelper.throwIfNull(owner, () => $"owner is null !!!"); var result = new Result(); var err_msg = string.Empty; if (null == otherEntityAttribute) { err_msg = $"Invalid Param !!!, otherEntityAttribute is null"; result.setFail(ServerErrorCode.FunctionParamNull, err_msg); Log.getLogger().error(result.toBasicString()); return result; } //===================================================================================== // OtherAttribute => Attribute //===================================================================================== var location_attribute = otherEntityAttribute as LocationAttribute; if (null == location_attribute) { err_msg = $"Failed to cast MinimapMarkerAttribute !!!, minimap_marker_attribute is null"; result.setFail(ServerErrorCode.ClassTypeCastIsNull, err_msg); Log.getLogger().error(result.toBasicString()); return result; } LastestChannelServerLocation = location_attribute.LastestChannelServerLocation.clone(); ReturnIndunLocations = location_attribute.ReturnIndunLocations.Select(x => x.clone()).ToList(); EnterIndunLocation = location_attribute.EnterIndunLocation.clone(); CurrentIndunLocation = location_attribute.CurrentIndunLocation.clone(); MoveChannelTime = location_attribute.MoveChannelTime; //===================================================================================== // Attribute Try Pending Doc => Origin Doc //===================================================================================== var try_pending_doc = location_attribute.getTryPendingDocBase() as LocationDoc; if (null != try_pending_doc) { location_attribute.resetTryPendingDocBase(); syncOriginDocBaseWithNewDoc(try_pending_doc); } var origin_doc_base = getOriginDocBase(); if (null == origin_doc_base) { // DB 에 저장되어 있지 않는 경우 OriginDoc은 null 이다 !!! return result; } var location_attrib = origin_doc_base.getAttrib(); NullReferenceCheckHelper.throwIfNull(location_attrib, () => $"location_attrib is null !!! - {owner.toBasicString()}"); location_attrib.LastConnectedChannelServerLocation = LastestChannelServerLocation.clone(); location_attrib.ReJoinIndunLocation = ReJoinIndunLocation.clone(); return result; } } public class LocationAttributeTransactor : EntityAttributeTransactorBase, ICopyEntityAttributeTransactorFromEntityAttribute { public LocationAttributeTransactor(EntityBase owner) : base(owner) { } public bool copyEntityAttributeTransactorFromEntityAttribute(EntityAttributeBase? entityAttributeBase) { var err_msg = string.Empty; var to_cast_string = typeof(LocationAttribute).Name; var copy_from_location_attribute = entityAttributeBase as LocationAttribute; if (null == copy_from_location_attribute) { err_msg = $"Failed to copyEntityAttributeTransactorBaseFromEntityAttribute() !!!, copy_from_location_attribute is null :{to_cast_string}"; Log.getLogger().error(err_msg); return false; } var copy_to_location_attribute = getClonedEntityAttribute() as LocationAttribute; if (null == copy_to_location_attribute) { err_msg = $"Failed to copyEntityAttributeTransactorBaseFromEntityAttribute() !!!, copy_to_location_attribute is null :{to_cast_string}"; Log.getLogger().error(err_msg); return false; } copy_to_location_attribute.LastestChannelServerLocation = copy_from_location_attribute.LastestChannelServerLocation.clone(); copy_to_location_attribute.ReJoinIndunLocation = copy_from_location_attribute.ReJoinIndunLocation.clone(); copy_to_location_attribute.ReturnIndunLocations = copy_from_location_attribute.ReturnIndunLocations.Select(x => x.clone()).ToList(); copy_to_location_attribute.EnterIndunLocation = copy_from_location_attribute.EnterIndunLocation.clone(); copy_to_location_attribute.CurrentIndunLocation = copy_from_location_attribute.CurrentIndunLocation.clone(); copy_to_location_attribute.MoveChannelTime = copy_from_location_attribute.MoveChannelTime; return true; } } }