Example #1
0
        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);
        }
Example #2
0
        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);
        }
Example #3
0
        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);
        }
Example #4
0
        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);
                }
            }));
        }
Example #5
0
        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;
                }
            }));
        }
Example #6
0
        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);
        }
Example #7
0
        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();
            }
        }
Example #8
0
        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);
        }
Example #9
0
        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);
                }
            }));
        }