using System; using System.IO; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; using System.Runtime.Serialization; using System.Runtime.Serialization.Formatters.Binary; using Newtonsoft.Json; using ServerCore; using ServerBase; using SESSION_ID = System.Int32; using WORLD_ID = System.UInt32; using META_ID = System.UInt32; using ENTITY_GUID = System.String; using ACCOUNT_ID = System.String; using OWNER_GUID = System.String; using USER_GUID = System.String; using CHARACTER_GUID = System.String; using ITEM_GUID = System.String; using ServerControlCenter; namespace ServerCommon { public class CharacterAttribute : EntityAttributeBase, ICopyEntityAttributeFromMeta, ICopyEntityAttributeFromDoc, IMergeWithEntityAttribute { public class AppearanceProfile { public UInt32 BasicStyle { get; set; } = 0; public UInt32 BodyShape { get; set; } = 0; public UInt32 HairStyle { get; set; } = 0; public List CustomValues { get; set; } = new(); // 캐릭터 외형 커스터마이징 절차 완료 여부를 설정 한다. 서버 주도로 관리되어야 하는 정보 !!! public bool IsCustomCompleted { get; set; } = false; public void reset() { BasicStyle = 0; BodyShape = 0; HairStyle = 0; CustomValues.Clear(); IsCustomCompleted = false; } public object Clone() { var clone = new AppearanceProfile(); clone.BasicStyle = BasicStyle; clone.BodyShape = BodyShape; clone.HairStyle = HairStyle; clone.CustomValues = CustomValues.Select(x => x).ToList(); clone.IsCustomCompleted = IsCustomCompleted; return clone; } public void copyFromAppearanceProfile(CharacterBaseAttrib.AppearanceProfile docAttrib) { BasicStyle = docAttrib.BasicStyle; BodyShape = docAttrib.BodyShape; HairStyle = docAttrib.HairStyle; CustomValues = docAttrib.CustomValues.Select(x => x).ToList(); IsCustomCompleted = docAttrib.IsCustomCompleted; } } [JsonProperty] public CHARACTER_GUID CharacterGuid { get; set; } = string.Empty; public EntityStateInfo StateInfo { get; set; } = new(); public AppearanceProfile AppearanceProfileValue { get; set; } = new(); public CharacterAttribute(EntityBase owner, EntityBase entityOfOwnerEntityType) : base(owner, entityOfOwnerEntityType) { } public override void newEntityAttribute() { CharacterGuid = System.Guid.NewGuid().ToString("N"); base.newEntityAttribute(); } public override void onClear() { CharacterGuid = string.Empty; AppearanceProfileValue.reset(); getAttributeState().reset(); } public override EntityAttributeBase onCloned() { var owner = getOwner(); NullReferenceCheckHelper.throwIfNull(owner, () => $"owner is null !!!"); var parent = owner.getRootParent(); NullReferenceCheckHelper.throwIfNull(parent, () => $"parent is null !!! - {owner.toBasicString()}"); var entity_of_owner_entity_type = getEntityOfOwnerEntityType(); NullReferenceCheckHelper.throwIfNull(entity_of_owner_entity_type, () => $"entity_of_owner_entity_type is null !!!"); var cloned = new CharacterAttribute(owner, entity_of_owner_entity_type); cloned.CharacterGuid = CharacterGuid; var cloned_appearance_profile = (AppearanceProfile)AppearanceProfileValue.Clone(); NullReferenceCheckHelper.throwIfNull(cloned_appearance_profile, () => $"parent cloned_appearance_profile null !!! - {owner.toBasicString()}"); cloned.AppearanceProfileValue = cloned_appearance_profile; return cloned; } public override IEntityAttributeTransactor onNewEntityAttributeTransactor() { return new CharacterAttributeTransactor(getOwner()); } public override async Task<(Result, DynamoDbDocBase?)> toDocBase(bool isForQuery = true) { var result = new Result(); var owner = getOwner(); NullReferenceCheckHelper.throwIfNull(owner, () => $"owner is null !!!"); var parent = owner.getRootParent(); NullReferenceCheckHelper.throwIfNull(parent, () => $"parent is null !!! - {owner.toBasicString()}"); //===================================================================================== // Attribute => try pending Doc //===================================================================================== var user_attribute = parent.getEntityAttribute(); NullReferenceCheckHelper.throwIfNull(user_attribute, () => $"user_attribute is null !!! - {owner.toBasicString()}"); var user_guid = user_attribute.UserGuid; var try_pending_doc = getTryPendingDocBase() as CharacterBaseDoc; if (null == try_pending_doc) { var to_copy_doc = new CharacterBaseDoc(user_guid, CharacterGuid); var origin_doc = getOriginDocBase(); if (null != origin_doc) { to_copy_doc.copyTimestampsFromOriginDocBase(origin_doc); } try_pending_doc = to_copy_doc; setTryPendingDocBase(try_pending_doc); } //===================================================================================== // Attribute => Doc //===================================================================================== var to_copy_doc_character_base_attrib = try_pending_doc.getAttrib(); NullReferenceCheckHelper.throwIfNull(to_copy_doc_character_base_attrib, () => $"to_copy_doc_character_base_attrib is null !!! - {owner.toBasicString()}"); to_copy_doc_character_base_attrib.CharacterGuid = CharacterGuid; to_copy_doc_character_base_attrib.UserGuid = user_guid; to_copy_doc_character_base_attrib.StateInfo = StateInfo; to_copy_doc_character_base_attrib.ApperanceProfileValue.copyFromAppearanceProfile(AppearanceProfileValue); 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 Result onMerge(EntityAttributeBase otherEntityAttribute) { var result = new Result(); var err_msg = string.Empty; var owner = getOwner(); NullReferenceCheckHelper.throwIfNull(owner, () => $"owner is null !!!"); var parent = owner.getRootParent(); NullReferenceCheckHelper.throwIfNull(parent, () => $"parent is null !!! - {owner.toBasicString()}"); if (null == otherEntityAttribute) { err_msg = $"Invalid Param !!!, otherEntityAttribute is null - {owner.toBasicString()}"; result.setFail(ServerErrorCode.FunctionParamNull, err_msg); Log.getLogger().error(result.toBasicString()); return result; } var user_attribute = parent.getEntityAttribute(); NullReferenceCheckHelper.throwIfNull(user_attribute, () => $"user_attribute is null !!! - {owner.toBasicString()}"); var user_guid = user_attribute.UserGuid; //===================================================================================== // OtherAttribute => Attribute //===================================================================================== var other_character_attribute = otherEntityAttribute as CharacterAttribute; if (null == other_character_attribute) { err_msg = $"Failed to cast !!!, other_character_attribute is null"; result.setFail(ServerErrorCode.ClassTypeCastIsNull, err_msg); Log.getLogger().error(result.toBasicString()); return result; } CharacterGuid = other_character_attribute.CharacterGuid; StateInfo = other_character_attribute.StateInfo; AppearanceProfileValue = (AppearanceProfile)other_character_attribute.AppearanceProfileValue.Clone(); //===================================================================================== // Attribute Try Pending Doc => Origin Doc //===================================================================================== var try_pending_doc = other_character_attribute.getTryPendingDocBase() as CharacterBaseDoc; if (null != try_pending_doc) { other_character_attribute.resetTryPendingDocBase(); syncOriginDocBaseWithNewDoc(try_pending_doc); } var origin_doc_base = getOriginDocBase(); if (null == origin_doc_base) { // DB 에 저장되어 있지 않는 경우 OriginDoc은 null 이다 !!! return result; } var character_base_attrib = origin_doc_base.getAttrib(); NullReferenceCheckHelper.throwIfNull(character_base_attrib, () => $"character_base_attrib is null !!! - {owner.toBasicString()}"); character_base_attrib.CharacterGuid = CharacterGuid; character_base_attrib.StateInfo = StateInfo; character_base_attrib.ApperanceProfileValue.copyFromAppearanceProfile(AppearanceProfileValue); return result; } public bool copyEntityAttributeFromMeta(MetaAssets.IMetaData customMeta) { var err_msg = string.Empty; bool is_success = false; var test_user_create_data = customMeta as MetaAssets.TestUserCreateMetaData; if (null != test_user_create_data) { is_success = copyEntityAttributeFromTestUserCreateData(test_user_create_data); } var user_create_data = customMeta as MetaAssets.UserCreateMetaData; if(null != user_create_data) { is_success = copyEntityAttributeFromUserCreateData(user_create_data); } if (false == is_success) { err_msg = $"Failed to copyEntityAttributeFromMeta() !!! : {customMeta.getTypeName()} - {getOwner().toBasicString()}"; Log.getLogger().error(err_msg); return false; } return true; } private bool copyEntityAttributeFromTestUserCreateData(MetaAssets.TestUserCreateMetaData testUserCreateData) { var err_msg = string.Empty; var to_cast_string = typeof(MetaAssets.TestUserCreateMetaData).Name; if (null == testUserCreateData) { err_msg = $"Failed to copyEntityAttributeFromTestUserCreateData() !!!, testUserCreateData is null : {to_cast_string} - {getOwner().toBasicString()}"; Log.getLogger().warn(err_msg); return false; } AppearanceProfileValue.BasicStyle = (UInt32)testUserCreateData.BasicStyle; AppearanceProfileValue.BodyShape = (UInt32)testUserCreateData.BodyShape; AppearanceProfileValue.HairStyle = (UInt32)testUserCreateData.HairStyle; AppearanceProfileValue.CustomValues = testUserCreateData.CustomValues.Select(x => x).ToList(); return true; } private bool copyEntityAttributeFromUserCreateData(MetaAssets.UserCreateMetaData userCreateData) { var err_msg = string.Empty; var to_cast_string = typeof(MetaAssets.UserCreateMetaData).Name; if (null == userCreateData) { err_msg = $"Failed to copyEntityAttributeFromUserCreateData() !!!, userCreateData is null : {to_cast_string}"; Log.getLogger().warn(err_msg); return false; } return true; } public bool copyEntityAttributeFromDoc(DynamoDbDocBase docBase) { var err_msg = string.Empty; var owner = getOwner(); NullReferenceCheckHelper.throwIfNull(owner, () => $"owner is null !!!"); var parent = owner.getRootParent(); NullReferenceCheckHelper.throwIfNull(parent, () => $"parent is null !!! - {owner.toBasicString()}"); var to_cast_string = typeof(CharacterBaseDoc).Name; var character_doc_base = docBase as CharacterBaseDoc; if (null == character_doc_base) { err_msg = $"Failed to copyEntityAttributeFromDoc() !!!, character_doc_base is null :{to_cast_string} - {owner.toBasicString()}"; Log.getLogger().error(err_msg); return false; } //===================================================================================== // New Doc => Origin Doc //===================================================================================== syncOriginDocBaseWithNewDoc(character_doc_base); //===================================================================================== // Doc => Attribute //===================================================================================== var doc_character_base_attrib = character_doc_base.getAttrib(); NullReferenceCheckHelper.throwIfNull(doc_character_base_attrib, () => $"doc_character_base_attrib is null !!! - {owner.toBasicString()}"); CharacterGuid = doc_character_base_attrib.CharacterGuid; StateInfo = doc_character_base_attrib.StateInfo; AppearanceProfileValue.copyFromAppearanceProfile(doc_character_base_attrib.ApperanceProfileValue); return true; } } public class CharacterAttributeTransactor : EntityAttributeTransactorBase, ICopyEntityAttributeTransactorFromEntityAttribute { public CharacterAttributeTransactor(EntityBase owner) : base(owner) { } public bool copyEntityAttributeTransactorFromEntityAttribute(EntityAttributeBase? entityAttributeBase) { var err_msg = string.Empty; var to_cast_string = typeof(CharacterAttribute).Name; var copy_from_character_attribute = entityAttributeBase as CharacterAttribute; if (null == copy_from_character_attribute) { err_msg = $"Failed to copyEntityAttributeTransactorFromEntityAttribute() !!!, copy_from_character_attribute is null :{to_cast_string}"; Log.getLogger().error(err_msg); return false; } var copy_to_character_attribute = getClonedEntityAttribute() as CharacterAttribute; if (null == copy_to_character_attribute) { err_msg = $"Failed to copyEntityAttributeTransactorFromEntityAttribute() !!!, copy_to_character_attribute is null :{to_cast_string}"; Log.getLogger().error(err_msg); return false; } copy_to_character_attribute.CharacterGuid = copy_from_character_attribute.CharacterGuid; copy_to_character_attribute.StateInfo = copy_from_character_attribute.StateInfo; copy_to_character_attribute.AppearanceProfileValue = (CharacterAttribute.AppearanceProfile)(copy_from_character_attribute.AppearanceProfileValue.Clone()); return true; } } }