예제 #1
0
        /// <summary>
        /// Check if Custom Creation Points Distribution is Valid.
        /// </summary>
        /// <param name="character"></param>
        /// <param name="stats"></param>
        /// <param name="points"></param>
        /// <returns></returns>
        public static bool IsCustomPointsDistributionValid(DOLCharacters character, IDictionary <eStat, int> stats, out int points)
        {
            ICharacterClass charClass = ScriptMgr.FindCharacterClass(character.Class);

            if (charClass != null)
            {
                points = 0;

                // check if each stat is valid.
                foreach (var stat in stats.Keys)
                {
                    int raceAmount = GlobalConstants.STARTING_STATS_DICT[(eRace)character.Race][stat];

                    int classAmount = 0;

                    for (int level = character.Level; level > 5; level--)
                    {
                        if (charClass.PrimaryStat != eStat.UNDEFINED && charClass.PrimaryStat == stat)
                        {
                            classAmount++;
                        }

                        if (charClass.SecondaryStat != eStat.UNDEFINED && charClass.SecondaryStat == stat && (level - 6) % 2 == 0)
                        {
                            classAmount++;
                        }

                        if (charClass.TertiaryStat != eStat.UNDEFINED && charClass.TertiaryStat == stat && (level - 6) % 3 == 0)
                        {
                            classAmount++;
                        }
                    }

                    int above = stats[stat] - raceAmount - classAmount;

                    // Miss Some points...
                    if (above < 0)
                    {
                        return(false);
                    }

                    points += above;
                    points += Math.Max(0, above - 10); // two points used
                    points += Math.Max(0, above - 15); // three points used
                }

                return(points == MaxStartingBonusPoints);
            }

            points = -1;
            return(false);
        }
        /// <summary>
        /// Check if a Character Needs update based to packet data
        /// </summary>
        /// <param name="pdata">packet data</param>
        /// <param name="client">client</param>
        /// <param name="character">db character</param>
        /// <returns>True if character need refreshment false if no refresh needed.</returns>
        private bool CheckCharacterForUpdates(CreationCharacterData pdata, GameClient client, DOLCharacters character)
        {
            int newModel = character.CurrentModel;

            if (pdata.CustomMode == 1 || pdata.CustomMode == 2 || pdata.CustomMode == 3)
            {
                bool flagChangedStats = false;

                if (Properties.ALLOW_CUSTOMIZE_FACE_AFTER_CREATION)
                {
                    character.EyeSize   = (byte)pdata.EyeSize;
                    character.LipSize   = (byte)pdata.LipSize;
                    character.EyeColor  = (byte)pdata.EyeColor;
                    character.HairColor = (byte)pdata.HairColor;
                    character.FaceType  = (byte)pdata.FaceType;
                    character.HairStyle = (byte)pdata.HairStyle;
                    character.MoodType  = (byte)pdata.MoodType;
                }

                if (pdata.CustomMode != 3 && client.Version >= GameClient.eClientVersion.Version189)
                {
                    var stats = new Dictionary <eStat, int>();
                    stats[eStat.STR] = pdata.Strength;                  // Strength
                    stats[eStat.DEX] = pdata.Dexterity;                 // Dexterity
                    stats[eStat.CON] = pdata.NewConstitution;           // New Constitution
                    stats[eStat.QUI] = pdata.Quickness;                 // Quickness
                    stats[eStat.INT] = pdata.Intelligence;              // Intelligence
                    stats[eStat.PIE] = pdata.Piety;                     // Piety
                    stats[eStat.EMP] = pdata.Empathy;                   // Empathy
                    stats[eStat.CHR] = pdata.Charisma;                  // Charisma

                    // check for changed stats.
                    flagChangedStats |= stats[eStat.STR] != character.Strength;
                    flagChangedStats |= stats[eStat.CON] != character.Constitution;
                    flagChangedStats |= stats[eStat.DEX] != character.Dexterity;
                    flagChangedStats |= stats[eStat.QUI] != character.Quickness;
                    flagChangedStats |= stats[eStat.INT] != character.Intelligence;
                    flagChangedStats |= stats[eStat.PIE] != character.Piety;
                    flagChangedStats |= stats[eStat.EMP] != character.Empathy;
                    flagChangedStats |= stats[eStat.CHR] != character.Charisma;

                    if (flagChangedStats)
                    {
                        ICharacterClass charClass = ScriptMgr.FindCharacterClass(character.Class);

                        if (charClass != null)
                        {
                            int  points;
                            bool valid = IsCustomPointsDistributionValid(character, stats, out points);

                            // Hacking attemp ?
                            if (points > MAX_STARTING_BONUS_POINTS)
                            {
                                if ((ePrivLevel)client.Account.PrivLevel == ePrivLevel.Player)
                                {
                                    if (ServerProperties.Properties.BAN_HACKERS)
                                    {
                                        client.BanAccount(string.Format("Autoban Hack char update : Wrong allowed points:{0}", points));
                                    }

                                    client.Disconnect();
                                    return(false);
                                }
                            }

                            // Error in setting points
                            if (!valid)
                            {
                                return(true);
                            }

                            if (Properties.ALLOW_CUSTOMIZE_STATS_AFTER_CREATION)
                            {
                                // Set Stats, valid is ok.
                                character.Strength     = stats[eStat.STR];
                                character.Constitution = stats[eStat.CON];
                                character.Dexterity    = stats[eStat.DEX];
                                character.Quickness    = stats[eStat.QUI];
                                character.Intelligence = stats[eStat.INT];
                                character.Piety        = stats[eStat.PIE];
                                character.Empathy      = stats[eStat.EMP];
                                character.Charisma     = stats[eStat.CHR];

                                if (log.IsInfoEnabled)
                                {
                                    log.InfoFormat("Character {0} Stats updated in cache!", character.Name);
                                }

                                if (client.Player != null)
                                {
                                    foreach (var stat in stats.Keys)
                                    {
                                        client.Player.ChangeBaseStat(stat, (short)(stats[stat] - client.Player.GetBaseStat(stat)));
                                    }

                                    if (log.IsInfoEnabled)
                                    {
                                        log.InfoFormat("Character {0} Player Stats updated in cache!", character.Name);
                                    }
                                }
                            }
                        }
                        else if (log.IsErrorEnabled)
                        {
                            log.ErrorFormat("No CharacterClass with ID {0} found", character.Class);
                        }
                    }
                }


                if (pdata.CustomMode == 2)                 // change player customization
                {
                    if (client.Account.PrivLevel == 1 && ((pdata.CreationModel >> 11) & 3) == 0)
                    {
                        if (ServerProperties.Properties.BAN_HACKERS)                         // Player size must be > 0 (from 1 to 3)
                        {
                            client.BanAccount(string.Format("Autoban Hack char update : zero character size in model:{0}", newModel));
                            client.Disconnect();
                            return(false);
                        }
                        return(true);
                    }

                    character.CustomisationStep = 2;                     // disable config button

                    if (Properties.ALLOW_CUSTOMIZE_FACE_AFTER_CREATION)
                    {
                        if (pdata.CreationModel != character.CreationModel)
                        {
                            character.CurrentModel = newModel;
                        }

                        if (log.IsInfoEnabled)
                        {
                            log.InfoFormat("Character {0} face properties configured by account {1}!", character.Name, client.Account.Name);
                        }
                    }
                }
                else if (pdata.CustomMode == 3)                 //auto config -- seems someone thinks this is not possible?
                {
                    character.CustomisationStep = 3;            // enable config button to player
                }

                //Save the character in the database
                GameServer.Database.SaveObject(character);
            }

            return(false);
        }