public Task <bool> CheckCharacterExistsDbAsync(string characterName) { if (string.IsNullOrWhiteSpace(characterName)) { throw new ArgumentException(@"Value cannot be null or whitespace.", nameof(characterName)); } //run the database request on the thread pool. var task = new Task <bool>(() => { //Access the database and search for a character with the given name. try { using (CharacterManagementContext db = _ContextFactory.Create()) { return(db.Characters.Any(c => c.CharacterName.Equals(characterName, StringComparison.InvariantCultureIgnoreCase))); } } catch (Exception e) { string msg = $"Something went wrong while checking for the existence of a character with the name '{characterName}'"; _Log.Error(msg); throw new DatabaseRequestException(msg, e); } }); task.Start(); return(task); }
public Task <int> GetCharacterOwnershipsCountFromDbAsync(Account account) { if (account == null) { throw new ArgumentNullException(nameof(account)); } var task = new Task <int>(() => { try { using (var db = _ContextFactory.Create()) { return(db.CharacterOwnerships.Count(os => os.OwnerId == account.AccountId)); } } catch (Exception e) { string msg = $"Something went wrong while requesting the amount of character ownerships for account '{account.UserName}' from the database"; _Log.Error(msg); throw new DatabaseRequestException(msg, e); } }); //Start the task on the thread pool and return it. task.Start(); return(task); }
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 SetAccountActiveCharacterAsync(Account account, Character character) { return(Task.Run(() => { try { using (var db = _ContextFactory.Create()) { //Find out if we have a entry for the last active character in the database. AccountLastUsedCharacterEntity activeCharEntity = db.LastUsedCharacters.FirstOrDefault(lastChar => lastChar.Account.AccountId == account.AccountId); //An entity does exist. Simply update the character key if (activeCharEntity != null) { //The ids do match, so lets just return because no further action is required. if (activeCharEntity.CharacterId == character.CharacterId) { return; } activeCharEntity.CharacterId = character.CharacterId; } //No last used character entity found, create a new one. else { db.LastUsedCharacters.Add(new AccountLastUsedCharacterEntity { AccountId = account.AccountId, CharacterId = character.CharacterId }); } //We have made changes, lets write them back to the database. db.SaveChanges(); } } catch (Exception e) { string msg = $"Something went wrong while setting the active character(last used character) of account '{account.UserName}' to character '{character.Name}'"; _Log.Error(msg); throw new DatabaseRequestException(msg, e); } })); }
public Task SaveCharacterAsync(Character character) { if (character == null) { throw new ArgumentNullException(nameof(character)); } return(Task.Run(() => { try { using (var db = _ContextFactory.Create()) { var changedEntity = new CharacterEntity { CharacterId = character.CharacterId, CharacterName = character.Name, PositionX = character.LastKnownPosition.X, PositionY = character.LastKnownPosition.Y, PositionZ = character.LastKnownPosition.Z, Rotation = character.Rotation.Yaw, WorldName = character.World.Path, TemplateName = character.Template.CodeName, }; db.Characters.Attach(changedEntity); //Create a character entity which represents the changes to the character. //Explicitly ignore the character name as changing this is currently not planed. db.Entry(changedEntity).Property(ce => ce.PositionX).IsModified = true; db.Entry(changedEntity).Property(ce => ce.PositionY).IsModified = true; db.Entry(changedEntity).Property(ce => ce.PositionZ).IsModified = true; db.Entry(changedEntity).Property(ce => ce.Rotation).IsModified = true; db.Entry(changedEntity).Property(ce => ce.WorldName).IsModified = true; db.Entry(changedEntity).Property(ce => ce.TemplateName).IsModified = true; //Save the changes db.SaveChanges(); } } catch (Exception e) { Console.WriteLine(e); throw; } })); }
public Task <ActiveCharacterResult> GetAccountActiveCharacterAsync(Account account) { if (account == null) { throw new ArgumentNullException(nameof(account)); } Task <ActiveCharacterResult> task = new Task <ActiveCharacterResult>(() => { try { using (var db = _ContextFactory.Create()) { AccountLastUsedCharacterEntity lastUsedEntity = db.LastUsedCharacters.FirstOrDefault(lc => lc.AccountId == account.AccountId); if (lastUsedEntity != null) { if (!db.CharacterOwnerships.Any(os => os.OwnerId == account.AccountId && os.CharacterId == lastUsedEntity.CharacterId)) { //We found a last used character but it is not owned by the given account(ownership was removed since setting the active character). Remove the database entity. db.LastUsedCharacters.Remove(lastUsedEntity); return(new NoActiveCharacterFound(account)); } //Last used character was found and it is still owned by the given account. return(new ActiveCharacterFound(account, lastUsedEntity.CharacterId)); } // No last used character found. return(new NoActiveCharacterFound(account)); } } catch (Exception e) { string msg = $"Something went wrong while requesting the last used character of the account '{account.UserName}' from the database"; _Log.Error(msg); throw new DatabaseRequestException(msg, e); } }); task.Start(); return(task); }
public CharacterItemsInitialization(ICharacterManagementContextFactory contextFactory, IItemDefList itemDefList, ILoggerFactory loggerFactory) { if (contextFactory == null) { throw new ArgumentNullException(nameof(contextFactory)); } if (itemDefList == null) { throw new ArgumentNullException(nameof(itemDefList)); } if (loggerFactory == null) { throw new ArgumentNullException(nameof(loggerFactory)); } var logger = loggerFactory.GetLogger(GetType()); using (var db = contextFactory.Create()) { //Get items types that have already been registered in the database. var characterItemEntities = db.CharacterItems.ToDictionary(entity => entity.ItemName.ToUpperInvariant()); //Add all items that are defined but not registered in the database to the database. foreach (var itemDef in itemDefList.AllDefinitions) { if (!characterItemEntities.ContainsKey(itemDef.CodeName.ToUpperInvariant())) { db.CharacterItems.Add( new CharacterItemEntity() { ItemName = itemDef.CodeName.ToUpperInvariant() }); logger.Info($"Added item definition '{itemDef.CodeName.ToUpperInvariant()}'"); } } //Save the changes to the database. db.SaveChanges(); } }
public Task <IList <Character> > GetAccountOwnedCharactersFromDbAsync(Account owner) { var task = new Task <IList <Character> >(() => { try { using (var db = _ContextFactory.Create()) { var characters = new List <Character>(); //Call to list or we will get problems with trying to create multiple result sets on the same connection without using the MARS-Mode(Multiple Active Result Sets). foreach (var characterEntity in db.CharacterOwnerships.Where(os => os.Owner.AccountId == owner.AccountId).Select(os => os.Character).ToList()) { var humanVisuals = db.CustomVisuals.FirstOrDefault(vis => vis.OwnerCharacter.CharacterId == characterEntity.CharacterId); //If we have human visuals in the database, we create a human character. characters.Add(humanVisuals != null ? _CharacterBuilder.HumanCharacterFromEntities(characterEntity, humanVisuals) : _CharacterBuilder.NonHumanCharacterFromEntities(characterEntity)); } return(characters); } } catch (Exception e) { string msg = $"Something went wrong while requesting the characters of account '{owner.UserName}' form the database. Exception: {e}"; _Log.Error(msg); throw new DatabaseRequestException(msg, e); } }); 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); } })); }