internal Task <AddCharacterOwnershipResult> AddCharacterOwnershipAsync(Account owner, Character character, DateTime expirationDate, bool deleteOnExpiration) { if (owner == null) { throw new ArgumentNullException(nameof(owner)); } if (character == null) { throw new ArgumentNullException(nameof(character)); } var task = new Task <AddCharacterOwnershipResult>(() => { try { using (CharacterManagementContext db = _ContextFactory.Create()) { //Limit the characters that can be created if (db.CharacterOwnerships.Count(os => os.OwnerId == owner.AccountId) >= _RpConfig.MaxCharacterPerAccount) { return(new AddCharacterOwnershipFailed(owner, character, AddCharacterOwnershipFailure.CharacterLimitReached)); } if (!db.CharacterOwnerships.Any(os => os.Owner.AccountId == owner.AccountId && os.Character.CharacterId == character.CharacterId)) { db.CharacterOwnerships.Add(new CharacterOwnershipEntity() { OwnerId = owner.AccountId, CharacterId = character.CharacterId, DeleteCharacterOnExpiration = deleteOnExpiration, ExpiryDate = expirationDate, CreationDate = DateTime.Now }); db.SaveChanges(); } return(new AddCharacterOwnershipSuccessful(owner, character)); } } catch (Exception e) { string msg = $"Something went wrong while adding the ownership of the character with the name '{character.Name}' to the account with the name {owner.UserName}"; _Log.Error(msg); throw new DatabaseRequestException(msg, e); } }); //Start the task on the thread pool and return it. task.Start(); return(task); }
public Task <CharacterCreationResult> CreateHumanPlayerCharacterAsync(CharCreationInfo creationInfo) { if (creationInfo == null) { throw new ArgumentNullException(nameof(creationInfo)); } return(_CharacterService.CheckCharacterExistsAsync(creationInfo.Name).ContinueWith <CharacterCreationResult>(task => { //Validate the creation info because it comes directly from the client(we do not trust the client). if (!creationInfo.Validate(out string invalidProperty, out object value)) { _Log.Warn($"Character creation failed due to invalid {nameof(CharCreationInfo)}, invalid attribute is '{invalidProperty}' with value '{value}'"); return new CharacterCreationFailed(CharacterCreationFailure.InvalidCreationInfo); } //Check whether the name can be used for a character. if (!_NameValidator.IsValid(creationInfo.Name)) { return (CharacterCreationResult) new CharacterCreationFailed(CharacterCreationFailure.NameIsInvalid); } //The character does already exist. if (task.Result) { return (CharacterCreationResult) new CharacterCreationFailed(CharacterCreationFailure .AlreadyExists); } //Create the new character try { using (CharacterManagementContext db = _ContextFactory.Create()) { SpawnPoint spawn = _SpawnPointProvider.GetSpawnPoint(); //Add the character var characterEntity = new CharacterEntity { CharacterName = creationInfo.Name, PositionX = spawn.Point.X, PositionY = spawn.Point.Y, PositionZ = spawn.Point.Z, Rotation = spawn.Rotation.Yaw, WorldName = spawn.World.Path, TemplateName = _CharacterTemplateSelector.GetTemplate(creationInfo) }; db.Characters.Add(characterEntity); //Add the visuals of the character. var customVisuals = new CharacterCustomVisualsEntity { OwnerCharacter = characterEntity, BodyMesh = creationInfo.BodyMesh, BodyTex = creationInfo.BodyTex, HeadMesh = creationInfo.HeadMesh, HeadTex = creationInfo.HeadTex, Voice = creationInfo.Voice, Fatness = creationInfo.Fatness, BodyWidth = creationInfo.BodyWidth }; db.CustomVisuals.Add(customVisuals); //Save the changes. db.SaveChanges(); Character character = _CharacterBuilder.HumanCharacterFromEntities(characterEntity, customVisuals); //Invoke the character creation event(later so we can inform the client first) _Dispatcher.EnqueueAction(() => { _CharacterService.OnCharacterCreated(new CharacterCreatedArgs(character)); }); //Return information about successful character creation. return new CharacterCreationSuccess(character); } } catch (Exception e) { throw new DatabaseRequestException("Something went wrong while adding the new character to the database.", e); } })); }