From f5906bce10f5ca6a2c067736816f2c1ee502fabc Mon Sep 17 00:00:00 2001 From: Hondacrx Date: Thu, 4 Sep 2025 22:30:57 -0400 Subject: [PATCH] Core/World: Refactor World::LoadConfigSettings to unify validation of all config options and reduce its impact on compile time Port From (https://github.com/TrinityCore/TrinityCore/commit/b6d64447ba3a9aa4e3759e2c3582b07438da8633) --- Source/Framework/Constants/SharedConst.cs | 12 + Source/Game/Entities/Player/Player.cs | 2 +- Source/Game/Garrisons/GarrisonMap.cs | 4 +- Source/Game/Handlers/CharacterHandler.cs | 6 +- Source/Game/Maps/Map.cs | 12 +- Source/Game/Server/WorldConfig.cs | 1471 ++++++++------------- Source/Game/Server/WorldSession.cs | 2 +- Source/Game/World/WorldManager.cs | 95 +- 8 files changed, 580 insertions(+), 1024 deletions(-) diff --git a/Source/Framework/Constants/SharedConst.cs b/Source/Framework/Constants/SharedConst.cs index ba9b8a0ce..7df014d57 100644 --- a/Source/Framework/Constants/SharedConst.cs +++ b/Source/Framework/Constants/SharedConst.cs @@ -131,6 +131,7 @@ namespace Framework.Constants /// /// Misc Const /// + public const int MaxCharactersPerRealm = 200; public const Locale DefaultLocale = Locale.enUS; public const int MaxAccountTutorialValues = 8; public const int MinAuctionTime = (12 * Time.Hour); @@ -1584,6 +1585,8 @@ namespace Framework.Constants ChatChannelLevelReq, ChatEmoteLevelReq, ChatFakeMessagePreventing, + ChatFloodAddonMessageCount, + ChatFloodAddonMessageDelay, ChatFloodMessageCount, ChatFloodMessageDelay, ChatFloodMuteTime, @@ -1621,6 +1624,7 @@ namespace Framework.Constants CurrencyResetHour, CurrencyResetInterval, DailyQuestResetTimeHour, + DbPingInterval, DbcEnforceItemAttributes, DeathBonesBgOrArena, DeathBonesWorld, @@ -1693,6 +1697,10 @@ namespace Framework.Constants MaxRecruitAFriendBonusPlayerLevelDifference, MaxRecruitAFriendDistance, MaxResultsLookupCommands, + MaxVisibilityDistanceContinent, + MaxVisibilityDistanceInstance, + MaxVisibilityDistanceBattleground, + MaxVisibilityDistanceArena, MaxWho, MinCharterName, MinCreatureScaledXpRatio, @@ -1885,6 +1893,10 @@ namespace Framework.Constants TolbaradRestartAfterCrash, TradeLevelReq, UptimeUpdate, + VisibilityNotifyPeriodContinent, + VisibilityNotifyPeriodInstance, + VisibilityNotifyPeriodBattleground, + VisibilityNotifyPeriodArena, VmapIndoorCheck, WardenClientResponseDelay, WardenClientCheckHoldoff, diff --git a/Source/Game/Entities/Player/Player.cs b/Source/Game/Entities/Player/Player.cs index 287ed79f1..be53a15a5 100644 --- a/Source/Game/Entities/Player/Player.cs +++ b/Source/Game/Entities/Player/Player.cs @@ -247,7 +247,7 @@ namespace Game.Entities InitRunes(); - SetUpdateFieldValue(m_values.ModifyValue(m_activePlayerData).ModifyValue(m_activePlayerData.Coinage), (ulong)WorldConfig.GetIntValue(WorldCfg.StartPlayerMoney)); + SetUpdateFieldValue(m_values.ModifyValue(m_activePlayerData).ModifyValue(m_activePlayerData.Coinage), WorldConfig.GetUInt64Value(WorldCfg.StartPlayerMoney)); // Played time m_Last_tick = GameTime.GetGameTime(); diff --git a/Source/Game/Garrisons/GarrisonMap.cs b/Source/Game/Garrisons/GarrisonMap.cs index cc387230d..75b8f35be 100644 --- a/Source/Game/Garrisons/GarrisonMap.cs +++ b/Source/Game/Garrisons/GarrisonMap.cs @@ -39,8 +39,8 @@ namespace Game.Garrisons public override void InitVisibilityDistance() { //init visibility distance for instances - m_VisibleDistance = Global.WorldMgr.GetMaxVisibleDistanceInInstances(); - m_VisibilityNotifyPeriod = Global.WorldMgr.GetVisibilityNotifyPeriodInInstances(); + m_VisibleDistance = WorldConfig.GetFloatValue(WorldCfg.MaxVisibilityDistanceInstance); + m_VisibilityNotifyPeriod = WorldConfig.GetIntValue(WorldCfg.VisibilityNotifyPeriodInstance); } public override bool AddPlayerToMap(Player player, bool initPlayer = true) diff --git a/Source/Game/Handlers/CharacterHandler.cs b/Source/Game/Handlers/CharacterHandler.cs index 11393451c..d9a1335cc 100644 --- a/Source/Game/Handlers/CharacterHandler.cs +++ b/Source/Game/Handlers/CharacterHandler.cs @@ -109,7 +109,7 @@ namespace Game charResult.MaxCharacterLevel = Math.Max(charResult.MaxCharacterLevel, charInfo.ExperienceLevel); } - while (result.NextRow() && charResult.Characters.Count < 200); + while (result.NextRow() && charResult.Characters.Count < SharedConst.MaxCharactersPerRealm); } foreach (var requirement in Global.ObjectMgr.GetRaceUnlockRequirements()) @@ -893,6 +893,10 @@ namespace Game break; } } + + // send new char string if not empty + if (!Global.WorldMgr.GetNewCharString().IsEmpty()) + pCurrChar.SendSysMessage(Global.WorldMgr.GetNewCharString()); } if (!pCurrChar.GetMap().AddPlayerToMap(pCurrChar)) diff --git a/Source/Game/Maps/Map.cs b/Source/Game/Maps/Map.cs index 927c6d8f8..900968630 100644 --- a/Source/Game/Maps/Map.cs +++ b/Source/Game/Maps/Map.cs @@ -90,8 +90,8 @@ namespace Game.Maps public virtual void InitVisibilityDistance() { //init visibility for continents - m_VisibleDistance = Global.WorldMgr.GetMaxVisibleDistanceOnContinents(); - m_VisibilityNotifyPeriod = Global.WorldMgr.GetVisibilityNotifyPeriodOnContinents(); + m_VisibleDistance = WorldConfig.GetFloatValue(WorldCfg.MaxVisibilityDistanceContinent); + m_VisibilityNotifyPeriod = WorldConfig.GetIntValue(WorldCfg.VisibilityNotifyPeriodContinent); } public void AddToGrid(T obj, Cell cell) where T : WorldObject @@ -4915,8 +4915,8 @@ namespace Game.Maps public override void InitVisibilityDistance() { //init visibility distance for instances - m_VisibleDistance = Global.WorldMgr.GetMaxVisibleDistanceInInstances(); - m_VisibilityNotifyPeriod = Global.WorldMgr.GetVisibilityNotifyPeriodInInstances(); + m_VisibleDistance = WorldConfig.GetFloatValue(WorldCfg.MaxVisibilityDistanceInstance); + m_VisibilityNotifyPeriod = WorldConfig.GetIntValue(WorldCfg.VisibilityNotifyPeriodInstance); } public override TransferAbortParams CannotEnter(Player player) @@ -5354,8 +5354,8 @@ namespace Game.Maps public override void InitVisibilityDistance() { - m_VisibleDistance = IsBattleArena() ? Global.WorldMgr.GetMaxVisibleDistanceInArenas() : Global.WorldMgr.GetMaxVisibleDistanceInBG(); - m_VisibilityNotifyPeriod = IsBattleArena() ? Global.WorldMgr.GetVisibilityNotifyPeriodInArenas() : Global.WorldMgr.GetVisibilityNotifyPeriodInBG(); + m_VisibleDistance = WorldConfig.GetFloatValue(IsBattleArena() ? WorldCfg.MaxVisibilityDistanceArena : WorldCfg.MaxVisibilityDistanceBattleground); + m_VisibilityNotifyPeriod = WorldConfig.GetIntValue(IsBattleArena() ? WorldCfg.VisibilityNotifyPeriodArena : WorldCfg.VisibilityNotifyPeriodBattleground); } string GetScriptName() diff --git a/Source/Game/Server/WorldConfig.cs b/Source/Game/Server/WorldConfig.cs index 41982d40a..50c991657 100644 --- a/Source/Game/Server/WorldConfig.cs +++ b/Source/Game/Server/WorldConfig.cs @@ -16,738 +16,550 @@ namespace Game if (reload) Load("WorldServer.conf"); - // Read support system setting from the config file - Values[WorldCfg.SupportEnabled] = GetDefaultValue("Support.Enabled", true); - Values[WorldCfg.SupportTicketsEnabled] = GetDefaultValue("Support.TicketsEnabled", false); - Values[WorldCfg.SupportBugsEnabled] = GetDefaultValue("Support.BugsEnabled", false); - Values[WorldCfg.SupportComplaintsEnabled] = GetDefaultValue("Support.ComplaintsEnabled", false); - Values[WorldCfg.SupportSuggestionsEnabled] = GetDefaultValue("Support.SuggestionsEnabled", false); + uint databaseCacheVersion = (uint)Values[WorldCfg.ClientCacheVersion]; - // Send server info on login? - Values[WorldCfg.EnableSinfoLogin] = GetDefaultValue("Server.LoginInfo", 0); + ConfigOptionLoadDefinition[] bools = + [ + new() { Name = "Support.Enabled", DefaultValue = true, Index = WorldCfg.SupportEnabled }, + new() { Name = "Support.TicketsEnabled", DefaultValue = false, Index = WorldCfg.SupportTicketsEnabled }, + new() { Name = "Support.BugsEnabled", DefaultValue = false, Index = WorldCfg.SupportBugsEnabled }, + new() { Name = "Support.ComplaintsEnabled", DefaultValue = false, Index = WorldCfg.SupportComplaintsEnabled }, + new() { Name = "Support.SuggestionsEnabled", DefaultValue = false, Index = WorldCfg.SupportSuggestionsEnabled }, + new() { Name = "DurabilityLoss.InPvP", DefaultValue = false, Index = WorldCfg.DurabilityLossInPvp }, + new() { Name = "AddonChannel", DefaultValue = true, Index = WorldCfg.AddonChannel }, + new() { Name = "CleanCharacterDB", DefaultValue = false, Index = WorldCfg.CleanCharacterDb }, + new() { Name = "PreserveCustomChannels", DefaultValue = false, Index = WorldCfg.PreserveCustomChannels }, + new() { Name = "GridUnload", DefaultValue = true, Index = WorldCfg.GridUnload }, + new() { Name = "BaseMapLoadAllGrids", DefaultValue = false, Index = WorldCfg.BasemapLoadGrids }, + new() { Name = "InstanceMapLoadAllGrids", DefaultValue = false, Index = WorldCfg.InstancemapLoadGrids }, + new() { Name = "BattlegroundMapLoadAllGrids", DefaultValue = true, Index = WorldCfg.BattlegroundMapLoadGrids }, + new() { Name = "PlayerSave.Stats.SaveOnlyOnLogout", DefaultValue = true, Index = WorldCfg.StatsSaveOnlyOnLogout }, + new() { Name = "Creature.RegenHPCannotReachTargetInRaid", DefaultValue = true, Index = WorldCfg.RegenHpCannotReachTargetInRaid }, + new() { Name = "AllowTwoSide.Interaction.Calendar", DefaultValue = false, Index = WorldCfg.AllowTwoSideInteractionCalendar }, + new() { Name = "AllowTwoSide.Interaction.Channel", DefaultValue = false, Index = WorldCfg.AllowTwoSideInteractionChannel }, + new() { Name = "AllowTwoSide.Interaction.Group", DefaultValue = false, Index = WorldCfg.AllowTwoSideInteractionGroup }, + new() { Name = "AllowTwoSide.Interaction.Guild", DefaultValue = false, Index = WorldCfg.AllowTwoSideInteractionGuild }, + new() { Name = "AllowTwoSide.Interaction.Auction", DefaultValue = true, Index = WorldCfg.AllowTwoSideInteractionAuction }, + new() { Name = "AllowTwoSide.Trade", DefaultValue = false, Index = WorldCfg.AllowTwoSideTrade }, + new() { Name = "CharacterCreating.DisableAlliedRaceAchievementRequirement", DefaultValue = false, Index = WorldCfg.CharacterCreatingDisableAlliedRaceAchievementRequirement }, + new() { Name = "AllFlightPaths", DefaultValue = false, Index = WorldCfg.AllTaxiPaths }, + new() { Name = "InstantFlightPaths", DefaultValue = false, Index = WorldCfg.InstantTaxi }, + new() { Name = "Instance.IgnoreLevel", DefaultValue = false, Index = WorldCfg.InstanceIgnoreLevel }, + new() { Name = "Instance.IgnoreRaid", DefaultValue = false, Index = WorldCfg.InstanceIgnoreRaid }, + new() { Name = "CastUnstuck", DefaultValue = true, Index = WorldCfg.CastUnstuck }, + new() { Name = "GM.AllowInvite", DefaultValue = false, Index = WorldCfg.AllowGmGroup }, + new() { Name = "GM.LowerSecurity", DefaultValue = false, Index = WorldCfg.GmLowerSecurity }, + new() { Name = "SkillChance.Prospecting", DefaultValue = false, Index = WorldCfg.SkillProspecting }, + new() { Name = "SkillChance.Milling", DefaultValue = false, Index = WorldCfg.SkillMilling }, + new() { Name = "ActivateWeather", DefaultValue = true, Index = WorldCfg.Weather }, + new() { Name = "Event.Announce", DefaultValue = false, Index = WorldCfg.EventAnnounce }, + new() { Name = "Quests.EnableQuestTracker", DefaultValue = false, Index = WorldCfg.QuestEnableQuestTracker }, + new() { Name = "Quests.IgnoreRaid", DefaultValue = false, Index = WorldCfg.QuestIgnoreRaid }, + new() { Name = "Quests.IgnoreAutoAccept", DefaultValue = false, Index = WorldCfg.QuestIgnoreAutoAccept }, + new() { Name = "Quests.IgnoreAutoComplete", DefaultValue = false, Index = WorldCfg.QuestIgnoreAutoComplete }, + new() { Name = "DetectPosCollision", DefaultValue = true, Index = WorldCfg.DetectPosCollision }, + new() { Name = "Channel.RestrictedLfg", DefaultValue = true, Index = WorldCfg.RestrictedLfgChannel }, + new() { Name = "ChatFakeMessagePreventing", DefaultValue = false, Index = WorldCfg.ChatFakeMessagePreventing }, + new() { Name = "Death.CorpseReclaimDelay.PvP", DefaultValue = true, Index = WorldCfg.DeathCorpseReclaimDelayPvp }, + new() { Name = "Death.CorpseReclaimDelay.PvE", DefaultValue = true, Index = WorldCfg.DeathCorpseReclaimDelayPve }, + new() { Name = "Death.Bones.World", DefaultValue = true, Index = WorldCfg.DeathBonesWorld }, + new() { Name = "Death.Bones.BattlegroundOrArena", DefaultValue = true, Index = WorldCfg.DeathBonesBgOrArena }, + new() { Name = "Die.Command.Mode", DefaultValue = true, Index = WorldCfg.DieCommandMode }, + new() { Name = "DeclinedNames", DefaultValue = false, Index = WorldCfg.DeclinedNamesUsed }, + new() { Name = "Battleground.CastDeserter", DefaultValue = true, Index = WorldCfg.BattlegroundCastDeserter }, + new() { Name = "Battleground.QueueAnnouncer.Enable", DefaultValue = false, Index = WorldCfg.BattlegroundQueueAnnouncerEnable }, + new() { Name = "Battleground.QueueAnnouncer.PlayerOnly", DefaultValue = false, Index = WorldCfg.BattlegroundQueueAnnouncerPlayeronly }, + new() { Name = "Battleground.StoreStatistics.Enable", DefaultValue = false, Index = WorldCfg.BattlegroundStoreStatisticsEnable }, + new() { Name = "Battleground.GiveXPForKills", DefaultValue = false, Index = WorldCfg.BgXpForKill }, + new() { Name = "Arena.QueueAnnouncer.Enable", DefaultValue = false, Index = WorldCfg.ArenaQueueAnnouncerEnable }, + new() { Name = "Arena.ArenaSeason.InProgress", DefaultValue = false, Index = WorldCfg.ArenaSeasonInProgress }, + new() { Name = "ArenaLog.ExtendedInfo", DefaultValue = false, Index = WorldCfg.ArenaLogExtendedInfo }, + new() { Name = "OffhandCheckAtSpellUnlearn", DefaultValue = true, Index = WorldCfg.OffhandCheckAtSpellUnlearn }, + new() { Name = "Respawn.DynamicEscortNPC", DefaultValue = false, Index = WorldCfg.RespawnDynamicEscortNpc }, + new() { Name = "mmap.enablePathFinding", DefaultValue = true, Index = WorldCfg.EnableMmaps }, + new() { Name = "vmap.enableIndoorCheck", DefaultValue = true, Index = WorldCfg.VmapIndoorCheck }, + new() { Name = "PlayerStart.AllSpells", DefaultValue = false, Index = WorldCfg.StartAllSpells }, + new() { Name = "ResetDuelCooldowns", DefaultValue = false, Index = WorldCfg.ResetDuelCooldowns }, + new() { Name = "ResetDuelHealthMana", DefaultValue = false, Index = WorldCfg.ResetDuelHealthMana }, + new() { Name = "PlayerStart.MapsExplored", DefaultValue = false, Index = WorldCfg.StartAllExplored }, + new() { Name = "PlayerStart.AllReputation", DefaultValue = false, Index = WorldCfg.StartAllRep }, + new() { Name = "PvPToken.Enable", DefaultValue = false, Index = WorldCfg.PvpTokenEnable }, + new() { Name = "NoResetTalentsCost", DefaultValue = false, Index = WorldCfg.NoResetTalentCost }, + new() { Name = "ShowKickInWorld", DefaultValue = false, Index = WorldCfg.ShowKickInWorld }, + new() { Name = "ShowMuteInWorld", DefaultValue = false, Index = WorldCfg.ShowMuteInWorld }, + new() { Name = "ShowBanInWorld", DefaultValue = false, Index = WorldCfg.ShowBanInWorld }, + new() { Name = "Warden.Enabled", DefaultValue = false, Index = WorldCfg.WardenEnabled }, + new() { Name = "FeatureSystem.CharacterUndelete.Enabled", DefaultValue = false, Index = WorldCfg.FeatureSystemCharacterUndeleteEnabled }, + new() { Name = "DBC.EnforceItemAttributes", DefaultValue = true, Index = WorldCfg.DbcEnforceItemAttributes }, + new() { Name = "InstancesResetAnnounce", DefaultValue = false, Index = WorldCfg.InstancesResetAnnounce }, + new() { Name = "AutoBroadcast.On", DefaultValue = false, Index = WorldCfg.AutoBroadcast }, + new() { Name = "PlayerDump.DisallowPaths", DefaultValue = true, Index = WorldCfg.PdumpNoPaths }, + new() { Name = "PlayerDump.DisallowOverwrite", DefaultValue = true, Index = WorldCfg.PdumpNoOverwrite }, + new() { Name = "Wintergrasp.Enable", DefaultValue = false, Index = WorldCfg.WintergraspEnable }, + new() { Name = "TolBarad.Enable", DefaultValue = true, Index = WorldCfg.TolbaradEnable }, + new() { Name = "Stats.Limits.Enable", DefaultValue = false, Index = WorldCfg.StatsLimitsEnable }, + new() { Name = "Allow.IP.Based.Action.Logging", DefaultValue = false, Index = WorldCfg.IpBasedActionLogging }, + new() { Name = "Calculate.Creature.Zone.Area.Data", DefaultValue = false, Index = WorldCfg.CalculateCreatureZoneAreaData }, + new() { Name = "Calculate.Gameoject.Zone.Area.Data", DefaultValue = false, Index = WorldCfg.CalculateGameobjectZoneAreaData }, + new() { Name = "BlackMarket.Enabled", DefaultValue = true, Index = WorldCfg.BlackmarketEnabled }, + new() { Name = "PreventRenameCharacterOnCustomization", DefaultValue = false, Index = WorldCfg.PreventRenameCustomization }, + new() { Name = "PartyRaidWarnings", DefaultValue = false, Index = WorldCfg.ChatPartyRaidWarnings }, + new() { Name = "CacheDataQueries", DefaultValue = true, Index = WorldCfg.CacheDataQueries }, + new() { Name = "Creature.CheckInvalidPosition", DefaultValue = false, Index = WorldCfg.CreatureCheckInvalidPostion }, + new() { Name = "GameObject.CheckInvalidPosition", DefaultValue = false, Index = WorldCfg.GameobjectCheckInvalidPostion }, + new() { Name = "CheckGameObjectLoS", DefaultValue = true, Index = WorldCfg.CheckGobjectLos }, + new() { Name = "AllowLoggingIPAddressesInDatabase", DefaultValue = true, Index = WorldCfg.AllowLogginIpAddressesInDatabase }, + new() { Name = "Loot.EnableAELoot", DefaultValue = true, Index = WorldCfg.EnableAeLoot }, + new() { Name = "Load.Locales", DefaultValue = true, Index = WorldCfg.LoadLocales }, + ]; - // Read all rates from the config file - static void SetRegenRate(WorldCfg rate, string configKey) + ConfigOptionLoadDefinition[] ints = + [ + new() { Name = "Server.LoginInfo", DefaultValue = 0, Index = WorldCfg.EnableSinfoLogin }, + new() { Name = "XP.Boost.Daymask", DefaultValue = 0, Index = WorldCfg.XpBoostDaymask }, + new() { Name = "Compression", DefaultValue = 1, Index = WorldCfg.Compression, Min = 1, Max = 9 }, + new() { Name = "PersistentCharacterCleanFlags", DefaultValue = 0, Index = WorldCfg.PersistentCharacterCleanFlags }, + new() { Name = "Auction.ReplicateItemsCooldown", DefaultValue = 900, Index = WorldCfg.AuctionReplicateDelay }, + new() { Name = "Auction.SearchDelay", DefaultValue = 300, Index = WorldCfg.AuctionSearchDelay, Min = 100, Max = 10000 }, + new() { Name = "Auction.TaintedSearchDelay", DefaultValue = 3000, Index = WorldCfg.AuctionTaintedSearchDelay, Min = 100, Max = 10000 }, + new() { Name = "ChatLevelReq.Channel", DefaultValue = 1, Index = WorldCfg.ChatChannelLevelReq }, + new() { Name = "ChatLevelReq.Whisper", DefaultValue = 1, Index = WorldCfg.ChatWhisperLevelReq }, + new() { Name = "ChatLevelReq.Emote", DefaultValue = 1, Index = WorldCfg.ChatEmoteLevelReq }, + new() { Name = "ChatLevelReq.Say", DefaultValue = 1, Index = WorldCfg.ChatSayLevelReq }, + new() { Name = "ChatLevelReq.Yell", DefaultValue = 1, Index = WorldCfg.ChatYellLevelReq }, + new() { Name = "PartyLevelReq", DefaultValue = 1, Index = WorldCfg.PartyLevelReq }, + new() { Name = "LevelReq.Trade", DefaultValue = 1, Index = WorldCfg.TradeLevelReq }, + new() { Name = "LevelReq.Auction", DefaultValue = 1, Index = WorldCfg.AuctionLevelReq }, + new() { Name = "LevelReq.Mail", DefaultValue = 1, Index = WorldCfg.MailLevelReq }, + new() { Name = "PreserveCustomChannelDuration", DefaultValue = 14, Index = WorldCfg.PreserveCustomChannelDuration }, + new() { Name = "PreserveCustomChannelInterval", DefaultValue = 5, Index = WorldCfg.PreserveCustomChannelInterval }, + new() { Name = "PlayerSaveInterval", DefaultValue = 15 * Time.Minute * Time.InMilliseconds, Index = WorldCfg.IntervalSave }, + new() { Name = "DisconnectToleranceInterval", DefaultValue = 0, Index = WorldCfg.IntervalDisconnectTolerance }, + new() { Name = "PlayerSave.StatsMinLevel", DefaultValue = 0, Index = WorldCfg.MinLevelStatSave, Max = SharedConst.StrongMaxLevel }, + new() { Name = "GridCleanUpDelay", DefaultValue = 5 * Time.Minute * Time.InMilliseconds, Index = WorldCfg.IntervalGridclean, Min = MapConst.MinGridDelay }, + new() { Name = "MapUpdateInterval", DefaultValue = 10, Index = WorldCfg.IntervalMapupdate, Min = MapConst.MinMapUpdateDelay }, + new() { Name = "ChangeWeatherInterval", DefaultValue = 10 * Time.Minute * Time.InMilliseconds, Index = WorldCfg.IntervalChangeweather }, + new() { Name = "WorldServerPort", DefaultValue = 8085, Index = WorldCfg.PortWorld, Min = 1, Max = ushort.MaxValue, Reloadable = false }, + new() { Name = "SocketTimeOutTime", DefaultValue = 900000, Index = WorldCfg.SocketTimeoutTime }, + new() { Name = "SocketTimeOutTimeActive", DefaultValue = 60000, Index = WorldCfg.SocketTimeoutTimeActive }, + new() { Name = "SessionAddDelay", DefaultValue = 10000, Index = WorldCfg.SessionAddDelay }, + new() { Name = "MinQuestScaledXPRatio", DefaultValue = 0, Index = WorldCfg.MinQuestScaledXpRatio, Max = 100 }, + new() { Name = "MinCreatureScaledXPRatio", DefaultValue = 0, Index = WorldCfg.MinCreatureScaledXpRatio, Max = 100 }, + new() { Name = "MinDiscoveredScaledXPRatio", DefaultValue = 0, Index = WorldCfg.MinDiscoveredScaledXpRatio, Max = 100 }, + new() { Name = "GameType", DefaultValue = 0, Index = WorldCfg.GameType, Reloadable = false }, + new() { Name = "RealmZone", DefaultValue = RealmManager.HardcodedDevelopmentRealmCategoryId, Index = WorldCfg.RealmZone, Reloadable = false }, + new() { Name = "StrictPlayerNames", DefaultValue = 0, Index = WorldCfg.StrictPlayerNames }, + new() { Name = "StrictCharterNames", DefaultValue = 0, Index = WorldCfg.StrictCharterNames }, + new() { Name = "StrictPetNames", DefaultValue = 0, Index = WorldCfg.StrictPetNames }, + new() { Name = "MinPlayerName", DefaultValue = 2, Index = WorldCfg.MinPlayerName, Min = 1, Max = 12 }, + new() { Name = "MinCharterName", DefaultValue = 2, Index = WorldCfg.MinCharterName, Min = 1, Max = 24 }, + new() { Name = "MinPetName", DefaultValue = 2, Index = WorldCfg.MinPetName, Min = 1, Max = 12 }, + new() { Name = "Guild.CharterCost", DefaultValue = 1000, Index = WorldCfg.CharterCostGuild }, + new() { Name = "ArenaTeam.CharterCost.2v2", DefaultValue = 800000, Index = WorldCfg.CharterCostArena2v2 }, + new() { Name = "ArenaTeam.CharterCost.3v3", DefaultValue = 1200000, Index = WorldCfg.CharterCostArena3v3 }, + new() { Name = "ArenaTeam.CharterCost.5v5", DefaultValue = 2000000, Index = WorldCfg.CharterCostArena5v5 }, + new() { Name = "CharacterCreating.Disabled", DefaultValue = 0, Index = WorldCfg.CharacterCreatingDisabled }, + new() { Name = "CharacterCreating.Disabled.ClassMask", DefaultValue = 0, Index = WorldCfg.CharacterCreatingDisabledClassmask }, + new() { Name = "CharactersPerRealm", DefaultValue = 60, Index = WorldCfg.CharactersPerRealm, Min = 1, Max = SharedConst.MaxCharactersPerRealm }, + new() { Name = "CharactersPerAccount", DefaultValue = 60, Index = WorldCfg.CharactersPerAccount, Min = 1, Max = SharedConst.MaxCharactersPerRealm }, + new() { Name = "CharacterCreating.EvokersPerRealm", DefaultValue = 1, Index = WorldCfg.CharacterCreatingEvokersPerRealm, Min = 1, Max = SharedConst.MaxCharactersPerRealm }, + new() { Name = "CharacterCreatingMinLevelForDemonHunter", DefaultValue = 0, Index = WorldCfg.CharacterCreatingMinLevelForDemonHunter }, + new() { Name = "CharacterCreatingMinLevelForEvoker", DefaultValue = 50, Index = WorldCfg.CharacterCreatingMinLevelForEvoker }, + new() { Name = "SkipCinematics", DefaultValue = 0, Index = WorldCfg.SkipCinematics, Min = 0, Max = 2 }, + new() { Name = "MaxPlayerLevel", DefaultValue = SharedConst.DefaultMaxLevel, Index = WorldCfg.MaxPlayerLevel, Min = 1, Max = SharedConst.MaxLevel, Reloadable = false }, + new() { Name = "MinDualSpecLevel", DefaultValue = 40, Index = WorldCfg.MinDualspecLevel }, + new() { Name = "StartPlayerLevel", DefaultValue = 1, Index = WorldCfg.StartPlayerLevel, Min = 1 }, + new() { Name = "StartDeathKnightPlayerLevel", DefaultValue = 8, Index = WorldCfg.StartDeathKnightPlayerLevel, Min = 1 }, + new() { Name = "StartDemonHunterPlayerLevel", DefaultValue = 8, Index = WorldCfg.StartDemonHunterPlayerLevel, Min = 1 }, + new() { Name = "StartEvokerPlayerLevel", DefaultValue = 10, Index = WorldCfg.StartEvokerPlayerLevel, Min = 1 }, + new() { Name = "StartAlliedRacePlayerLevel", DefaultValue = 10, Index = WorldCfg.StartAlliedRaceLevel, Min = 1 }, + new() { Name = "Currency.ResetHour", DefaultValue = 3, Index = WorldCfg.CurrencyResetHour, Min = 0, Max = 23 }, + new() { Name = "Currency.ResetDay", DefaultValue = 3, Index = WorldCfg.CurrencyResetDay, Min = 0, Max = 6 }, + new() { Name = "Currency.ResetInterval", DefaultValue = 7, Index = WorldCfg.CurrencyResetInterval, Min = 1 }, + new() { Name = "RecruitAFriendMaxLevel", DefaultValue = SharedConst.DefaultMaxLevel, Index = WorldCfg.MaxRecruitAFriendBonusPlayerLevel, Min = 1 }, + new() { Name = "RecruitAFriendMaxDifference", DefaultValue = 4, Index = WorldCfg.MaxRecruitAFriendBonusPlayerLevelDifference }, + new() { Name = "ResetSchedule.WeekDay", DefaultValue = 2, Index = WorldCfg.ResetScheduleWeekDay, Min = 0, Max = 6 }, + new() { Name = "ResetSchedule.Hour", DefaultValue = 8, Index = WorldCfg.ResetScheduleHour, Min = 0, Max = 23 }, + new() { Name = "Instance.UnloadDelay", DefaultValue = 30 * Time.Minute * Time.InMilliseconds, Index = WorldCfg.InstanceUnloadDelay }, + new() { Name = "Quests.DailyResetTime", DefaultValue = 3, Index = WorldCfg.DailyQuestResetTimeHour, Min = 0, Max = 23 }, + new() { Name = "Quests.WeeklyResetWDay", DefaultValue = 3, Index = WorldCfg.WeeklyQuestResetTimeWDay, Min = 0, Max = 6 }, + new() { Name = "MaxPrimaryTradeSkill", DefaultValue = 2, Index = WorldCfg.MaxPrimaryTradeSkill }, + new() { Name = "MinPetitionSigns", DefaultValue = 4, Index = WorldCfg.MinPetitionSigns, Max = 4 }, + new() { Name = "GM.LoginState", DefaultValue = 2, Index = WorldCfg.GmLoginState }, + new() { Name = "GM.Visible", DefaultValue = 2, Index = WorldCfg.GmVisibleState }, + new() { Name = "GM.Chat", DefaultValue = 2, Index = WorldCfg.GmChat }, + new() { Name = "GM.WhisperingTo", DefaultValue = 2, Index = WorldCfg.GmWhisperingTo }, + new() { Name = "GM.FreezeAuraDuration", DefaultValue = 0, Index = WorldCfg.GmFreezeDuration }, + new() { Name = "GM.InGMList.Level", DefaultValue = (uint)AccountTypes.Administrator, Index = WorldCfg.GmLevelInGmList }, + new() { Name = "GM.InWhoList.Level", DefaultValue = (uint)AccountTypes.Administrator, Index = WorldCfg.GmLevelInWhoList }, + new() { Name = "GM.StartLevel", DefaultValue = 1, Index = WorldCfg.StartGmLevel, Min = 1, Max = SharedConst.MaxLevel }, + new() { Name = "GM.ForceShutdownThreshold", DefaultValue = 30, Index = WorldCfg.ForceShutdownThreshold }, + new() { Name = "Visibility.GroupMode", DefaultValue = 1, Index = WorldCfg.GroupVisibility, Min = 0, Max = 3 }, + new() { Name = "MailDeliveryDelay", DefaultValue = Time.Hour, Index = WorldCfg.MailDeliveryDelay }, + new() { Name = "CleanOldMailTime", DefaultValue = 4, Index = WorldCfg.CleanOldMailTime, Min = 0, Max = 23 }, + new() { Name = "UpdateUptimeInterval", DefaultValue = 10, Index = WorldCfg.UptimeUpdate, Min = 1 }, + new() { Name = "LogDB.Opt.ClearInterval", DefaultValue = 10, Index = WorldCfg.LogdbClearinterval, Min = 1 }, + new() { Name = "LogDB.Opt.ClearTime", DefaultValue = 1209600, Index = WorldCfg.LogdbCleartime, Min = 1 }, + new() { Name = "SkillChance.Orange", DefaultValue = 100, Index = WorldCfg.SkillChanceOrange }, + new() { Name = "SkillChance.Yellow", DefaultValue = 75, Index = WorldCfg.SkillChanceYellow }, + new() { Name = "SkillChance.Green", DefaultValue = 25, Index = WorldCfg.SkillChanceGreen }, + new() { Name = "SkillChance.Grey", DefaultValue = 0, Index = WorldCfg.SkillChanceGrey }, + new() { Name = "SkillChanceMiningSteps", DefaultValue = 75, Index = WorldCfg.SkillChanceMiningSteps }, + new() { Name = "SkillChance.SkinningSteps", DefaultValue = 75, Index = WorldCfg.SkillChanceSkinningSteps }, + new() { Name = "SkillGain.Crafting", DefaultValue = 1, Index = WorldCfg.SkillGainCrafting }, + new() { Name = "SkillGain.Gathering", DefaultValue = 1, Index = WorldCfg.SkillGainGathering }, + new() { Name = "MaxOverspeedPings", DefaultValue = 2, Index = WorldCfg.MaxOverspeedPings }, + new() { Name = "ClientCacheVersion", DefaultValue = 0, Index = WorldCfg.ClientCacheVersion }, + new() { Name = "DisableWaterBreath", DefaultValue = (uint)AccountTypes.Console, Index = WorldCfg.DisableBreathing }, + new() { Name = "Expansion", DefaultValue = (uint)PlayerConst.CurrentExpansion, Index = WorldCfg.Expansion, Min = 0, Max = (uint)Expansion.Max, Reloadable = false }, + new() { Name = "ChatFlood.MessageCount", DefaultValue = 10, Index = WorldCfg.ChatFloodMessageCount }, + new() { Name = "ChatFlood.MessageDelay", DefaultValue = 1, Index = WorldCfg.ChatFloodMessageDelay }, + new() { Name = "ChatFlood.AddonMessageCount", DefaultValue = 100, Index = WorldCfg.ChatFloodAddonMessageCount }, + new() { Name = "ChatFlood.AddonMessageDelay", DefaultValue = 1, Index = WorldCfg.ChatFloodAddonMessageDelay }, + new() { Name = "ChatFlood.MuteTime", DefaultValue = 10, Index = WorldCfg.ChatFloodMuteTime }, + new() { Name = "CreatureFamilyAssistanceDelay", DefaultValue = 1500, Index = WorldCfg.CreatureFamilyAssistanceDelay }, + new() { Name = "CreatureFamilyFleeDelay", DefaultValue = 7000, Index = WorldCfg.CreatureFamilyFleeDelay }, + new() { Name = "WorldBossLevelDiff", DefaultValue = 3, Index = WorldCfg.WorldBossLevelDiff }, + new() { Name = "Quests.LowLevelHideDiff", DefaultValue = 4, Index = WorldCfg.QuestLowLevelHideDiff, Max = SharedConst.MaxLevel }, + new() { Name = "Quests.HighLevelHideDiff", DefaultValue = 7, Index = WorldCfg.QuestHighLevelHideDiff, Max = SharedConst.MaxLevel }, + new() { Name = "Battleground.Random.ResetHour", DefaultValue = 6, Index = WorldCfg.RandomBgResetHour, Min = 0, Max = 23 }, + new() { Name = "Calendar.DeleteOldEventsHour", DefaultValue = 6, Index = WorldCfg.CalendarDeleteOldEventsHour, Min = 0, Max = 23 }, + new() { Name = "Guild.ResetHour", DefaultValue = 6, Index = WorldCfg.GuildResetHour, Min = 0, Max = 23 }, + new() { Name = "TalentsInspecting", DefaultValue = 1, Index = WorldCfg.TalentsInspecting }, + new() { Name = "ChatStrictLinkChecking.Severity", DefaultValue = 0, Index = WorldCfg.ChatStrictLinkCheckingSeverity }, + new() { Name = "ChatStrictLinkChecking.Kick", DefaultValue = 0, Index = WorldCfg.ChatStrictLinkCheckingKick }, + new() { Name = "Corpse.Decay.Normal", DefaultValue = 60, Index = WorldCfg.CorpseDecayNormal }, + new() { Name = "Corpse.Decay.Elite", DefaultValue = 300, Index = WorldCfg.CorpseDecayElite }, + new() { Name = "Corpse.Decay.RareElite", DefaultValue = 300, Index = WorldCfg.CorpseDecayRareelite }, + new() { Name = "Corpse.Decay.Obsolete", DefaultValue = 3600, Index = WorldCfg.CorpseDecayObsolete }, + new() { Name = "Corpse.Decay.Rare", DefaultValue = 300, Index = WorldCfg.CorpseDecayRare }, + new() { Name = "Corpse.Decay.Trivial", DefaultValue = 300, Index = WorldCfg.CorpseDecayTrivial }, + new() { Name = "Corpse.DecayMinusMob", DefaultValue = 150, Index = WorldCfg.CorpseDecayMinusMob }, + new() { Name = "Death.SicknessLevel", DefaultValue = 11, Index = WorldCfg.DeathSicknessLevel }, + new() { Name = "Battleground.ReportAFK", DefaultValue = 3, Index = WorldCfg.BattlegroundReportAfk, Min = 1, Max = 9 }, + new() { Name = "Battleground.InvitationType", DefaultValue = 0, Index = WorldCfg.BattlegroundInvitationType }, + new() { Name = "Battleground.PrematureFinishTimer", DefaultValue = 5 * Time.Minute * Time.InMilliseconds, Index = WorldCfg.BattlegroundPrematureFinishTimer }, + new() { Name = "Battleground.PremadeGroupWaitForMatch", DefaultValue = 30 * Time.Minute * Time.InMilliseconds, Index = WorldCfg.BattlegroundPremadeGroupWaitForMatch }, + new() { Name = "ArenaMaxRatingDifference", DefaultValue = 150, Index = WorldCfg.ArenaMaxRatingDifference }, + new() { Name = "Arena.RatingDiscardTimer", DefaultValue = 10 * Time.Minute * Time.InMilliseconds, Index = WorldCfg.ArenaRatingDiscardTimer }, + new() { Name = "Arena.RatedUpdateTimer", DefaultValue = 5 * Time.InMilliseconds, Index = WorldCfg.ArenaRatedUpdateTimer }, + new() { Name = "Arena.ArenaSeason.ID", DefaultValue = 32, Index = WorldCfg.ArenaSeasonId }, + new() { Name = "Arena.ArenaStartRating", DefaultValue = 0, Index = WorldCfg.ArenaStartRating }, + new() { Name = "Arena.ArenaStartPersonalRating", DefaultValue = 1000, Index = WorldCfg.ArenaStartPersonalRating }, + new() { Name = "Arena.ArenaStartMatchmakerRating", DefaultValue = 1500, Index = WorldCfg.ArenaStartMatchmakerRating }, + new() { Name = "Creature.PickPocketRefillDelay", DefaultValue = 10 * Time.Minute, Index = WorldCfg.CreaturePickpocketRefill }, + new() { Name = "Creature.MovingStopTimeForPlayer", DefaultValue = 3 * Time.Minute * Time.InMilliseconds, Index = WorldCfg.CreatureStopForPlayer }, + new() { Name = "Guild.NewsLogRecordsCount", DefaultValue = GuildConst.NewsLogMaxRecords, Index = WorldCfg.GuildNewsLogCount, Max = GuildConst.NewsLogMaxRecords }, + new() { Name = "Guild.EventLogRecordsCount", DefaultValue = GuildConst.EventLogMaxRecords, Index = WorldCfg.GuildEventLogCount, Max = GuildConst.EventLogMaxRecords }, + new() { Name = "Guild.BankEventLogRecordsCount", DefaultValue = GuildConst.BankLogMaxRecords, Index = WorldCfg.GuildBankEventLogCount, Max = GuildConst.BankLogMaxRecords }, + new() { Name = "Visibility.Notify.Period.OnContinents", DefaultValue = SharedConst.DefaultVisibilityNotifyPeriod, Index = WorldCfg.VisibilityNotifyPeriodContinent }, + new() { Name = "Visibility.Notify.Period.InInstances", DefaultValue = SharedConst.DefaultVisibilityNotifyPeriod, Index = WorldCfg.VisibilityNotifyPeriodInstance }, + new() { Name = "Visibility.Notify.Period.InBG", DefaultValue = SharedConst.DefaultVisibilityNotifyPeriod, Index = WorldCfg.VisibilityNotifyPeriodBattleground }, + new() { Name = "Visibility.Notify.Period.InArenas", DefaultValue = SharedConst.DefaultVisibilityNotifyPeriod, Index = WorldCfg.VisibilityNotifyPeriodArena }, + new() { Name = "CharDelete.Method", DefaultValue = 0, Index = WorldCfg.ChardeleteMethod }, + new() { Name = "CharDeleteMinLevel", DefaultValue = 0, Index = WorldCfg.ChardeleteMinLevel }, + new() { Name = "CharDelete.DeathKnightMinLevel", DefaultValue = 0, Index = WorldCfg.ChardeleteDeathKnightMinLevel }, + new() { Name = "CharDelete.DemonHunterMinLevel", DefaultValue = 0, Index = WorldCfg.ChardeleteDemonHunterMinLevel }, + new() { Name = "CharDelete.KeepDays", DefaultValue = 30, Index = WorldCfg.ChardeleteKeepDays }, + new() { Name = "NoGrayAggro.Above", DefaultValue = 0, Index = WorldCfg.NoGrayAggroAbove }, + new() { Name = "NoGrayAggro.Below", DefaultValue = 0, Index = WorldCfg.NoGrayAggroBelow }, + new() { Name = "RespawnMinCheckIntervalMS", DefaultValue = 5000, Index = WorldCfg.RespawnMinCheckIntervalMs }, + new() { Name = "Respawn.DynamicMode", DefaultValue = 0, Index = WorldCfg.RespawnDynamicMode, Min = 0, Max = 1 }, + new() { Name = "Respawn.GuidWarnLevel", DefaultValue = 12000000, Index = WorldCfg.RespawnGuidWarnLevel, Min = 0, Max = 16777215 }, + new() { Name = "Respawn.GuidAlertLevel", DefaultValue = 16000000, Index = WorldCfg.RespawnGuidAlertLevel, Min = 0, Max = 16777215 }, + new() { Name = "Respawn.RestartQuietTime", DefaultValue = 3, Index = WorldCfg.RespawnRestartQuietTime, Min = 0, Max = 23 }, + new() { Name = "Respawn.DynamicMinimumCreature", DefaultValue = 10, Index = WorldCfg.RespawnDynamicMinimumCreature }, + new() { Name = "Respawn.DynamicMinimumGameObject", DefaultValue = 10, Index = WorldCfg.RespawnDynamicMinimumGameObject }, + new() { Name = "Respawn.WarningFrequency", DefaultValue = 1800, Index = WorldCfg.RespawnGuidWarningFrequency }, + new() { Name = "MaxWhoListReturns", DefaultValue = 49, Index = WorldCfg.MaxWho }, + new() { Name = "HonorPointsAfterDuel", DefaultValue = 0, Index = WorldCfg.HonorAfterDuel }, + new() { Name = "PvPToken.MapAllowType", DefaultValue = 4, Index = WorldCfg.PvpTokenMapType, Min = 1, Max = 4 }, + new() { Name = "PvPToken.ItemID", DefaultValue = 29434, Index = WorldCfg.PvpTokenId }, + new() { Name = "PvPToken.ItemCount", DefaultValue = 1, Index = WorldCfg.PvpTokenCount, Min = 1 }, + new() { Name = "MapUpdate.Threads", DefaultValue = 1, Index = WorldCfg.Numthreads, Min = 1 }, + new() { Name = "Command.LookupMaxResults", DefaultValue = 0, Index = WorldCfg.MaxResultsLookupCommands }, + new() { Name = "Warden.NumInjectionChecks", DefaultValue = 9, Index = WorldCfg.WardenNumInjectChecks }, + new() { Name = "Warden.NumLuaSandboxChecks", DefaultValue = 1, Index = WorldCfg.WardenNumLuaChecks }, + new() { Name = "Warden.NumClientModChecks", DefaultValue = 1, Index = WorldCfg.WardenNumClientModChecks }, + new() { Name = "Warden.BanDuration", DefaultValue = 86400, Index = WorldCfg.WardenClientBanDuration }, + new() { Name = "Warden.ClientCheckHoldOff", DefaultValue = 30, Index = WorldCfg.WardenClientCheckHoldoff }, + new() { Name = "Warden.ClientCheckFailAction", DefaultValue = 0, Index = WorldCfg.WardenClientFailAction }, + new() { Name = "Warden.ClientResponseDelay", DefaultValue = 600, Index = WorldCfg.WardenClientResponseDelay }, + new() { Name = "FeatureSystem.CharacterUndelete.Cooldown", DefaultValue = 2592000, Index = WorldCfg.FeatureSystemCharacterUndeleteCooldown }, + new() { Name = "DungeonFinder.OptionsMask", DefaultValue = 1, Index = WorldCfg.LfgOptionsmask }, + new() { Name = "Account.PasswordChangeSecurity", DefaultValue = 0, Index = WorldCfg.AccPasschangesec }, + new() { Name = "Battleground.RewardWinnerHonorFirst", DefaultValue = 27000, Index = WorldCfg.BgRewardWinnerHonorFirst }, + new() { Name = "Battleground.RewardWinnerConquestFirst", DefaultValue = 10000, Index = WorldCfg.BgRewardWinnerConquestFirst }, + new() { Name = "Battleground.RewardWinnerHonorLast", DefaultValue = 13500, Index = WorldCfg.BgRewardWinnerHonorLast }, + new() { Name = "Battleground.RewardWinnerConquestLast", DefaultValue = 5000, Index = WorldCfg.BgRewardWinnerConquestLast }, + new() { Name = "Battleground.RewardLoserHonorFirst", DefaultValue = 4500, Index = WorldCfg.BgRewardLoserHonorFirst }, + new() { Name = "Battleground.RewardLoserHonorLast", DefaultValue = 3500, Index = WorldCfg.BgRewardLoserHonorLast }, + new() { Name = "AccountInstancesPerHour", DefaultValue = 10, Index = WorldCfg.MaxInstancesPerHour }, + new() { Name = "AutoBroadcast.Center", DefaultValue = 0, Index = WorldCfg.AutoBroadcastCenter }, + new() { Name = "AutoBroadcast.Timer", DefaultValue = 60000, Index = WorldCfg.AutoBroadcastInterval }, + new() { Name = "MaxPingTime", DefaultValue = 30, Index = WorldCfg.DbPingInterval }, + new() { Name = "Guild.SaveInterval", DefaultValue = 15, Index = WorldCfg.GuildSaveInterval }, + new() { Name = "Wintergrasp.PlayerMax", DefaultValue = 100, Index = WorldCfg.WintergraspPlrMax }, + new() { Name = "Wintergrasp.PlayerMin", DefaultValue = 0, Index = WorldCfg.WintergraspPlrMin }, + new() { Name = "Wintergrasp.PlayerMinLvl", DefaultValue = 77, Index = WorldCfg.WintergraspPlrMinLvl }, + new() { Name = "Wintergrasp.BattleTimer", DefaultValue = 30, Index = WorldCfg.WintergraspBattletime }, + new() { Name = "Wintergrasp.NoBattleTimer", DefaultValue = 150, Index = WorldCfg.WintergraspNobattletime }, + new() { Name = "Wintergrasp.CrashRestartTimer", DefaultValue = 10, Index = WorldCfg.WintergraspRestartAfterCrash }, + new() { Name = "TolBarad.PlayerMax", DefaultValue = 100, Index = WorldCfg.TolbaradPlrMax }, + new() { Name = "TolBarad.PlayerMin", DefaultValue = 0, Index = WorldCfg.TolbaradPlrMin }, + new() { Name = "TolBarad.PlayerMinLvl", DefaultValue = 85, Index = WorldCfg.TolbaradPlrMinLvl }, + new() { Name = "TolBarad.BattleTimer", DefaultValue = 15, Index = WorldCfg.TolbaradBattleTime }, + new() { Name = "TolBarad.BonusTime", DefaultValue = 5, Index = WorldCfg.TolbaradBonusTime }, + new() { Name = "TolBarad.NoBattleTimer", DefaultValue = 150, Index = WorldCfg.TolbaradNoBattleTime }, + new() { Name = "TolBarad.CrashRestartTimer", DefaultValue = 10, Index = WorldCfg.TolbaradRestartAfterCrash }, + new() { Name = "PacketSpoof.Policy", DefaultValue = (uint)DosProtection.Policy.Kick, Index = WorldCfg.PacketSpoofPolicy }, + new() { Name = "PacketSpoof.BanMode", DefaultValue = (uint)BanMode.Account, Index = WorldCfg.PacketSpoofBanmode, Min = (uint)BanMode.Account, Max = (uint)BanMode.IP }, + new() { Name = "PacketSpoof.BanDuration", DefaultValue = 86400, Index = WorldCfg.PacketSpoofBanduration }, + new() { Name = "AuctionHouseBot.Update.Interval", DefaultValue = 20, Index = WorldCfg.AhbotUpdateInterval }, + new() { Name = "BlackMarketMaxAuctions", DefaultValue = 12, Index = WorldCfg.BlackmarketMaxAuctions }, + new() { Name = "BlackMarket.UpdatePeriod", DefaultValue = 24, Index = WorldCfg.BlackmarketUpdatePeriod }, + new() { Name = "Pvp.FactionBalance.LevelCheckDiff", DefaultValue = 0, Index = WorldCfg.FactionBalanceLevelCheckDiff }, + ]; + + ConfigOptionLoadDefinition[] int64s = + [ + new() { Name = "CharacterCreating.Disabled.RaceMask", DefaultValue = 0, Index = WorldCfg.CharacterCreatingDisabledRacemask }, + new() { Name = "StartPlayerMoney", DefaultValue = 0, Index = WorldCfg.StartPlayerMoney, Min = 0, Max = PlayerConst.MaxMoneyAmount }, + ]; + + ConfigOptionLoadDefinition[] floats = + [ + new() { Name = "MaxGroupXPDistance", DefaultValue = 74.0f, Index = WorldCfg.GroupXpDistance }, + new() { Name = "MaxRecruitAFriendBonusDistance", DefaultValue = 100.0f, Index = WorldCfg.MaxRecruitAFriendDistance }, + new() { Name = "MonsterSight", DefaultValue = 50.0f, Index = WorldCfg.SightMonster }, + new() { Name = "CreatureFamilyFleeAssistanceRadius", DefaultValue = 30.0f, Index = WorldCfg.CreatureFamilyFleeAssistanceRadius }, + new() { Name = "CreatureFamilyAssistanceRadius", DefaultValue = 10.0f, Index = WorldCfg.CreatureFamilyAssistanceRadius }, + new() { Name = "ThreatRadius", DefaultValue = 60.0f, Index = WorldCfg.ThreatRadius }, + new() { Name = "ListenRange.Say", DefaultValue = 25.0f, Index = WorldCfg.ListenRangeSay }, + new() { Name = "ListenRange.TextEmote", DefaultValue = 25.0f, Index = WorldCfg.ListenRangeTextemote }, + new() { Name = "ListenRange.Yell", DefaultValue = 300.0f, Index = WorldCfg.ListenRangeYell }, + new() { Name = "Arena.ArenaWinRatingModifier1", DefaultValue = 48.0f, Index = WorldCfg.ArenaWinRatingModifier1 }, + new() { Name = "Arena.ArenaWinRatingModifier2", DefaultValue = 24.0f, Index = WorldCfg.ArenaWinRatingModifier2 }, + new() { Name = "Arena.ArenaLoseRatingModifier", DefaultValue = 24.0f, Index = WorldCfg.ArenaLoseRatingModifier }, + new() { Name = "Arena.ArenaMatchmakerRatingModifier", DefaultValue = 24.0f, Index = WorldCfg.ArenaMatchmakerRatingModifier }, + new() { Name = "Visibility.Distance.Continents", DefaultValue = SharedConst.DefaultVisibilityDistance, Index = WorldCfg.MaxVisibilityDistanceContinent, Min = 0.0f, Max = SharedConst.MaxVisibilityDistance }, + new() { Name = "Visibility.Distance.Instances", DefaultValue = SharedConst.DefaultVisibilityInstance, Index = WorldCfg.MaxVisibilityDistanceInstance, Min = 0.0f, Max = SharedConst.MaxVisibilityDistance }, + new() { Name = "Visibility.Distance.BG", DefaultValue = SharedConst.DefaultVisibilityBGAreans, Index = WorldCfg.MaxVisibilityDistanceBattleground, Min = 0.0f, Max = SharedConst.MaxVisibilityDistance }, + new() { Name = "Visibility.Distance.Arenas", DefaultValue = SharedConst.DefaultVisibilityBGAreans, Index = WorldCfg.MaxVisibilityDistanceArena, Min = 0.0f, Max = SharedConst.MaxVisibilityDistance }, + new() { Name = "Respawn.DynamicRateCreature", DefaultValue = 10.0f, Index = WorldCfg.RespawnDynamicRateCreature, Min = 0.0f }, + new() { Name = "Respawn.DynamicRateGameObject", DefaultValue = 10.0f, Index = WorldCfg.RespawnDynamicRateGameobject, Min = 0.0f }, + new() { Name = "Stats.Limits.Dodge", DefaultValue = 95.0f, Index = WorldCfg.StatsLimitsDodge }, + new() { Name = "Stats.Limits.Parry", DefaultValue = 95.0f, Index = WorldCfg.StatsLimitsParry }, + new() { Name = "Stats.Limits.Block", DefaultValue = 95.0f, Index = WorldCfg.StatsLimitsBlock }, + new() { Name = "Stats.Limits.Crit", DefaultValue = 95.0f, Index = WorldCfg.StatsLimitsCrit }, + new() { Name = "Pvp.FactionBalance.Pct5", DefaultValue = 0.6f, Index = WorldCfg.CallToArms5Pct }, + new() { Name = "Pvp.FactionBalance.Pct10", DefaultValue = 0.7f, Index = WorldCfg.CallToArms10Pct }, + new() { Name = "Pvp.FactionBalance.Pct20", DefaultValue = 0.8f, Index = WorldCfg.CallToArms20Pct }, + ]; + + ConfigOptionLoadDefinition[] rates = + [ + new() { Name = "Rate.Health", DefaultValue = 1.0f, Index = WorldCfg.RateHealth, Min = 0.01f }, + new() { Name = "Rate.Mana", DefaultValue = 1.0f, Index = WorldCfg.RatePowerMana, Min = 0.01f }, + new() { Name = "Rate.Rage.Gain", DefaultValue = 1.0f, Index = WorldCfg.RatePowerRageIncome, Min = 0.01f }, + new() { Name = "Rate.Rage.Loss", DefaultValue = 1.0f, Index = WorldCfg.RatePowerRageLoss, Min = 0.01f }, + new() { Name = "Rate.Focus", DefaultValue = 1.0f, Index = WorldCfg.RatePowerFocus, Min = 0.01f }, + new() { Name = "Rate.Energy", DefaultValue = 1.0f, Index = WorldCfg.RatePowerEnergy, Min = 0.01f }, + new() { Name = "Rate.ComboPoints.Loss", DefaultValue = 1.0f, Index = WorldCfg.RatePowerComboPointsLoss, Min = 0.01f }, + new() { Name = "Rate.RunicPower.Gain", DefaultValue = 1.0f, Index = WorldCfg.RatePowerRunicPowerIncome, Min = 0.01f }, + new() { Name = "Rate.RunicPower.Loss", DefaultValue = 1.0f, Index = WorldCfg.RatePowerRunicPowerLoss, Min = 0.01f }, + new() { Name = "Rate.SoulShards.Loss", DefaultValue = 1.0f, Index = WorldCfg.RatePowerSoulShards, Min = 0.01f }, + new() { Name = "Rate.LunarPower.Loss", DefaultValue = 1.0f, Index = WorldCfg.RatePowerLunarPower, Min = 0.01f }, + new() { Name = "Rate.HolyPower.Loss", DefaultValue = 1.0f, Index = WorldCfg.RatePowerHolyPower, Min = 0.01f }, + new() { Name = "Rate.Maelstrom.Loss", DefaultValue = 1.0f, Index = WorldCfg.RatePowerMaelstrom, Min = 0.01f }, + new() { Name = "Rate.Chi.Loss", DefaultValue = 1.0f, Index = WorldCfg.RatePowerChi, Min = 0.01f }, + new() { Name = "Rate.Insanity.Loss", DefaultValue = 1.0f, Index = WorldCfg.RatePowerInsanity, Min = 0.01f }, + new() { Name = "Rate.ArcaneCharges.Loss", DefaultValue = 1.0f, Index = WorldCfg.RatePowerArcaneCharges, Min = 0.01f }, + new() { Name = "Rate.Fury.Loss", DefaultValue = 1.0f, Index = WorldCfg.RatePowerFury, Min = 0.01f }, + new() { Name = "Rate.Pain.Loss", DefaultValue = 1.0f, Index = WorldCfg.RatePowerPain, Min = 0.01f }, + new() { Name = "Rate.Essence.Loss", DefaultValue = 1.0f, Index = WorldCfg.RatePowerEssence, Min = 0.01f }, + new() { Name = "Rate.Skill.Discovery", DefaultValue = 1.0f, Index = WorldCfg.RateSkillDiscovery }, + new() { Name = "Rate.Drop.Item.Poor", DefaultValue = 1.0f, Index = WorldCfg.RateDropItemPoor }, + new() { Name = "Rate.Drop.Item.Normal", DefaultValue = 1.0f, Index = WorldCfg.RateDropItemNormal }, + new() { Name = "Rate.Drop.Item.Uncommon", DefaultValue = 1.0f, Index = WorldCfg.RateDropItemUncommon }, + new() { Name = "Rate.Drop.Item.Rare", DefaultValue = 1.0f, Index = WorldCfg.RateDropItemRare }, + new() { Name = "Rate.Drop.Item.Epic", DefaultValue = 1.0f, Index = WorldCfg.RateDropItemEpic }, + new() { Name = "Rate.Drop.Item.Legendary", DefaultValue = 1.0f, Index = WorldCfg.RateDropItemLegendary }, + new() { Name = "Rate.Drop.Item.Artifact", DefaultValue = 1.0f, Index = WorldCfg.RateDropItemArtifact }, + new() { Name = "Rate.Drop.Item.Referenced", DefaultValue = 1.0f, Index = WorldCfg.RateDropItemReferenced }, + new() { Name = "Rate.Drop.Item.ReferencedAmount", DefaultValue = 1.0f, Index = WorldCfg.RateDropItemReferencedAmount }, + new() { Name = "Rate.Drop.Money", DefaultValue = 1.0f, Index = WorldCfg.RateDropMoney }, + new() { Name = "Rate.XP.Kill", DefaultValue = 1.0f, Index = WorldCfg.RateXpKill }, + new() { Name = "Rate.XP.BattlegroundKill", DefaultValue = 1.0f, Index = WorldCfg.RateXpBgKill }, + new() { Name = "Rate.XP.Quest", DefaultValue = 1.0f, Index = WorldCfg.RateXpQuest }, + new() { Name = "Rate.XP.Explore", DefaultValue = 1.0f, Index = WorldCfg.RateXpExplore }, + new() { Name = "XP.Boost.Rate", DefaultValue = 2.0f, Index = WorldCfg.RateXpBoost }, + new() { Name = "Rate.RepairCost", DefaultValue = 1.0f, Index = WorldCfg.RateRepaircost, Min = 0.0f }, + new() { Name = "Rate.Reputation.Gain", DefaultValue = 1.0f, Index = WorldCfg.RateReputationGain }, + new() { Name = "Rate.Reputation.LowLevel.Kill", DefaultValue = 1.0f, Index = WorldCfg.RateReputationLowLevelKill }, + new() { Name = "Rate.Reputation.LowLevel.Quest", DefaultValue = 1.0f, Index = WorldCfg.RateReputationLowLevelQuest }, + new() { Name = "Rate.Reputation.RecruitAFriendBonus", DefaultValue = 0.1f, Index = WorldCfg.RateReputationRecruitAFriendBonus}, + new() { Name = "Rate.Creature.HP.Normal", DefaultValue = 1.0f, Index = WorldCfg.RateCreatureHpNormal }, + new() { Name = "Rate.Creature.HP.Elite", DefaultValue = 1.0f, Index = WorldCfg.RateCreatureHpElite }, + new() { Name = "Rate.Creature.HP.RareElite", DefaultValue = 1.0f, Index = WorldCfg.RateCreatureHpRareelite }, + new() { Name = "Rate.Creature.HP.Obsolete", DefaultValue = 1.0f, Index = WorldCfg.RateCreatureHpObsolete }, + new() { Name = "Rate.Creature.HP.Rare", DefaultValue = 1.0f, Index = WorldCfg.RateCreatureHpRare }, + new() { Name = "Rate.Creature.HP.Trivial", DefaultValue = 1.0f, Index = WorldCfg.RateCreatureHpTrivial }, + new() { Name = "Rate.Creature.HPMinusMob", DefaultValue = 1.0f, Index = WorldCfg.RateCreatureHpMinusmob }, + new() { Name = "Rate.Creature.Damage.Normal", DefaultValue = 1.0f, Index = WorldCfg.RateCreatureDamageNormal }, + new() { Name = "Rate.Creature.Damage.Elite", DefaultValue = 1.0f, Index = WorldCfg.RateCreatureDamageElite }, + new() { Name = "Rate.Creature.Damage.RareElite", DefaultValue = 1.0f, Index = WorldCfg.RateCreatureDamageRareelite }, + new() { Name = "Rate.Creature.Damage.Obsolete", DefaultValue = 1.0f, Index = WorldCfg.RateCreatureDamageObsolete }, + new() { Name = "Rate.Creature.Damage.Rare", DefaultValue = 1.0f, Index = WorldCfg.RateCreatureDamageRare }, + new() { Name = "Rate.Creature.Damage.Trivial", DefaultValue = 1.0f, Index = WorldCfg.RateCreatureDamageTrivial }, + new() { Name = "Rate.Creature.DamageMinusMob", DefaultValue = 1.0f, Index = WorldCfg.RateCreatureDamageMinusmob }, + new() { Name = "Rate.Creature.SpellDamage.Normal", DefaultValue = 1.0f, Index = WorldCfg.RateCreatureSpelldamageNormal }, + new() { Name = "Rate.Creature.SpellDamage.Elite", DefaultValue = 1.0f, Index = WorldCfg.RateCreatureSpelldamageElite }, + new() { Name = "Rate.Creature.SpellDamage.RareElite", DefaultValue = 1.0f, Index = WorldCfg.RateCreatureSpelldamageRareelite }, + new() { Name = "Rate.Creature.SpellDamage.Obsolete", DefaultValue = 1.0f, Index = WorldCfg.RateCreatureSpelldamageObsolete }, + new() { Name = "Rate.Creature.SpellDamage.Rare", DefaultValue = 1.0f, Index = WorldCfg.RateCreatureSpelldamageRare }, + new() { Name = "Rate.Creature.SpellDamage.Trivial", DefaultValue = 1.0f, Index = WorldCfg.RateCreatureSpelldamageTrivial }, + new() { Name = "Rate.Creature.SpellDamageMinusMob", DefaultValue = 1.0f, Index = WorldCfg.RateCreatureSpelldamageMinusmob }, + new() { Name = "Rate.Creature.Aggro", DefaultValue = 1.0f, Index = WorldCfg.RateCreatureAggro }, + new() { Name = "Rate.Rest.InGame", DefaultValue = 1.0f, Index = WorldCfg.RateRestIngame }, + new() { Name = "Rate.Rest.Offline.InTavernOrCity", DefaultValue = 1.0f, Index = WorldCfg.RateRestOfflineInTavernOrCity }, + new() { Name = "Rate.Rest.Offline.InWilderness", DefaultValue = 1.0f, Index = WorldCfg.RateRestOfflineInWilderness }, + new() { Name = "Rate.Damage.Fall", DefaultValue = 1.0f, Index = WorldCfg.RateDamageFall }, + new() { Name = "Rate.Auction.Time", DefaultValue = 1.0f, Index = WorldCfg.RateAuctionTime }, + new() { Name = "Rate.Auction.Deposit", DefaultValue = 1.0f, Index = WorldCfg.RateAuctionDeposit }, + new() { Name = "Rate.Auction.Cut", DefaultValue = 1.0f, Index = WorldCfg.RateAuctionCut }, + new() { Name = "Rate.Honor", DefaultValue = 1.0f, Index = WorldCfg.RateHonor }, + new() { Name = "Rate.InstanceResetTime", DefaultValue = 1.0f, Index = WorldCfg.RateInstanceResetTime }, + new() { Name = "Rate.MoveSpeed", DefaultValue = 1.0f, Index = WorldCfg.RateMovespeed, Min = 0.01f }, + new() { Name = "Rate.Corpse.Decay.Looted", DefaultValue = 0.5f, Index = WorldCfg.RateCorpseDecayLooted }, + new() { Name = "DurabilityLoss.OnDeath", DefaultValue = 10.0f, Index = WorldCfg.RateDurabilityLossOnDeath, Min = 0.0f, Max = 100.0f }, + new() { Name = "DurabilityLossChance.Damage", DefaultValue = 0.5f, Index = WorldCfg.RateDurabilityLossDamage, Min = 0.0f }, + new() { Name = "DurabilityLossChance.Absorb", DefaultValue = 0.5f, Index = WorldCfg.RateDurabilityLossAbsorb, Min = 0.0f }, + new() { Name = "DurabilityLossChance.Parry", DefaultValue = 0.05f, Index = WorldCfg.RateDurabilityLossParry, Min = 0.0f }, + new() { Name = "DurabilityLossChance.Block", DefaultValue = 0.05f, Index = WorldCfg.RateDurabilityLossBlock, Min = 0.0f }, + new() { Name = "Rate.Quest.Money.Reward", DefaultValue = 1.0f, Index = WorldCfg.RateMoneyQuest, Min = 0.0f }, + new() { Name = "Rate.Quest.MoneyMax.Level.Reward", DefaultValue = 1.0f, Index = WorldCfg.RateMoneyMaxLevelQuest, Min = 0.0f }, + ]; + + foreach (ConfigOptionLoadDefinition definition in bools) + StoreConfigValue(GetDefaultValue(definition.Name, definition.DefaultValue), definition, reload); + + foreach (ConfigOptionLoadDefinition definition in ints) + StoreConfigValue(GetDefaultValue(definition.Name, definition.DefaultValue), definition, reload); + + foreach (ConfigOptionLoadDefinition definition in int64s) + StoreConfigValue(GetDefaultValue(definition.Name, definition.DefaultValue), definition, reload); + + foreach (ConfigOptionLoadDefinition definition in floats) + StoreConfigValue(GetDefaultValue(definition.Name, definition.DefaultValue), definition, reload); + + foreach (ConfigOptionLoadDefinition definition in rates) + StoreConfigValue(GetDefaultValue(definition.Name, definition.DefaultValue), definition, reload); + + Values[WorldCfg.RateDurabilityLossOnDeath] = (float)Values[WorldCfg.RateDurabilityLossOnDeath] / 100.0f; + + if ((bool)Values[WorldCfg.GridUnload]) { - Values[rate] = GetDefaultValue(configKey, 1.0f); - if ((float) Values[rate] < 0.0f) + if ((bool)Values[WorldCfg.BasemapLoadGrids]) { - Log.outError(LogFilter.ServerLoading, "{0} ({1}) must be > 0. Using 1 instead.", configKey, Values[rate]); - Values[rate] = 1; + Log.outError(LogFilter.ServerLoading, "BaseMapLoadAllGrids enabled, but GridUnload also enabled. GridUnload must be disabled to enable base map pre-loading. Base map pre-loading disabled"); + Values[WorldCfg.BasemapLoadGrids] = false; + } + if ((bool)Values[WorldCfg.InstancemapLoadGrids]) + { + Log.outError(LogFilter.ServerLoading, "InstanceMapLoadAllGrids enabled, but GridUnload also enabled. GridUnload must be disabled to enable instance map pre-loading. Instance map pre-loading disabled"); + Values[WorldCfg.InstancemapLoadGrids] = false; } } - SetRegenRate(WorldCfg.RateHealth, "Rate.Health"); - SetRegenRate(WorldCfg.RatePowerMana, "Rate.Mana"); - SetRegenRate(WorldCfg.RatePowerRageIncome, "Rate.Rage.Gain"); - SetRegenRate(WorldCfg.RatePowerRageLoss, "Rate.Rage.Loss"); - SetRegenRate(WorldCfg.RatePowerFocus, "Rate.Focus"); - SetRegenRate(WorldCfg.RatePowerEnergy, "Rate.Energy"); - SetRegenRate(WorldCfg.RatePowerComboPointsLoss, "Rate.ComboPoints.Loss"); - SetRegenRate(WorldCfg.RatePowerRunicPowerIncome, "Rate.RunicPower.Gain"); - SetRegenRate(WorldCfg.RatePowerRunicPowerLoss, "Rate.RunicPower.Loss"); - SetRegenRate(WorldCfg.RatePowerSoulShards, "Rate.SoulShards.Loss"); - SetRegenRate(WorldCfg.RatePowerLunarPower, "Rate.LunarPower.Loss"); - SetRegenRate(WorldCfg.RatePowerHolyPower, "Rate.HolyPower.Loss"); - SetRegenRate(WorldCfg.RatePowerMaelstrom, "Rate.Maelstrom.Loss"); - SetRegenRate(WorldCfg.RatePowerChi, "Rate.Chi.Loss"); - SetRegenRate(WorldCfg.RatePowerInsanity, "Rate.Insanity.Loss"); - SetRegenRate(WorldCfg.RatePowerArcaneCharges, "Rate.ArcaneCharges.Loss"); - SetRegenRate(WorldCfg.RatePowerFury, "Rate.Fury.Loss"); - SetRegenRate(WorldCfg.RatePowerPain, "Rate.Pain.Loss"); - SetRegenRate(WorldCfg.RatePowerEssence, "Rate.Essence.Loss"); - - Values[WorldCfg.RateSkillDiscovery] = GetDefaultValue("Rate.Skill.Discovery", 1.0f); - Values[WorldCfg.RateDropItemPoor] = GetDefaultValue("Rate.Drop.Item.Poor", 1.0f); - Values[WorldCfg.RateDropItemNormal] = GetDefaultValue("Rate.Drop.Item.Normal", 1.0f); - Values[WorldCfg.RateDropItemUncommon] = GetDefaultValue("Rate.Drop.Item.Uncommon", 1.0f); - Values[WorldCfg.RateDropItemRare] = GetDefaultValue("Rate.Drop.Item.Rare", 1.0f); - Values[WorldCfg.RateDropItemEpic] = GetDefaultValue("Rate.Drop.Item.Epic", 1.0f); - Values[WorldCfg.RateDropItemLegendary] = GetDefaultValue("Rate.Drop.Item.Legendary", 1.0f); - Values[WorldCfg.RateDropItemArtifact] = GetDefaultValue("Rate.Drop.Item.Artifact", 1.0f); - Values[WorldCfg.RateDropItemReferenced] = GetDefaultValue("Rate.Drop.Item.Referenced", 1.0f); - Values[WorldCfg.RateDropItemReferencedAmount] = GetDefaultValue("Rate.Drop.Item.ReferencedAmount", 1.0f); - Values[WorldCfg.RateDropMoney] = GetDefaultValue("Rate.Drop.Money", 1.0f); - Values[WorldCfg.RateXpKill] = GetDefaultValue("Rate.XP.Kill", 1.0f); - Values[WorldCfg.RateXpBgKill] = GetDefaultValue("Rate.XP.BattlegroundKill", 1.0f); - Values[WorldCfg.RateXpQuest] = GetDefaultValue("Rate.XP.Quest", 1.0f); - Values[WorldCfg.RateXpExplore] = GetDefaultValue("Rate.XP.Explore", 1.0f); - - Values[WorldCfg.XpBoostDaymask] = GetDefaultValue("XP.Boost.Daymask", 0); - Values[WorldCfg.RateXpBoost] = GetDefaultValue("XP.Boost.Rate", 2.0f); - - Values[WorldCfg.RateRepaircost] = GetDefaultValue("Rate.RepairCost", 1.0f); - if ((float)Values[WorldCfg.RateRepaircost] < 0.0f) - { - Log.outError(LogFilter.ServerLoading, "Rate.RepairCost ({0}) must be >=0. Using 0.0 instead.", Values[WorldCfg.RateRepaircost]); - Values[WorldCfg.RateRepaircost] = 0.0f; - } - Values[WorldCfg.RateReputationGain] = GetDefaultValue("Rate.Reputation.Gain", 1.0f); - Values[WorldCfg.RateReputationLowLevelKill] = GetDefaultValue("Rate.Reputation.LowLevel.Kill", 1.0f); - Values[WorldCfg.RateReputationLowLevelQuest] = GetDefaultValue("Rate.Reputation.LowLevel.Quest", 1.0f); - Values[WorldCfg.RateReputationRecruitAFriendBonus] = GetDefaultValue("Rate.Reputation.RecruitAFriendBonus", 0.1f); - Values[WorldCfg.RateCreatureHpNormal] = GetDefaultValue("Rate.Creature.HP.Normal", 1.0f); - Values[WorldCfg.RateCreatureHpElite] = GetDefaultValue("Rate.Creature.HP.Elite", 1.0f); - Values[WorldCfg.RateCreatureHpRareelite] = GetDefaultValue("Rate.Creature.HP.RareElite", 1.0f); - Values[WorldCfg.RateCreatureHpObsolete] = GetDefaultValue("Rate.Creature.HP.Obsolete", 1.0f); - Values[WorldCfg.RateCreatureHpRare] = GetDefaultValue("Rate.Creature.HP.Rare", 1.0f); - Values[WorldCfg.RateCreatureHpTrivial] = GetDefaultValue("Rate.Creature.HP.Trivial", 1.0f); - Values[WorldCfg.RateCreatureHpMinusmob] = GetDefaultValue("Rate.Creature.HP.MinusMob", 1.0f); - Values[WorldCfg.RateCreatureDamageNormal] = GetDefaultValue("Rate.Creature.Damage.Normal", 1.0f); - Values[WorldCfg.RateCreatureDamageElite] = GetDefaultValue("Rate.Creature.Damage.Elite", 1.0f); - Values[WorldCfg.RateCreatureDamageRareelite] = GetDefaultValue("Rate.Creature.Damage.RareElite", 1.0f); - Values[WorldCfg.RateCreatureDamageObsolete] = GetDefaultValue("Rate.Creature.Damage.Obsolete", 1.0f); - Values[WorldCfg.RateCreatureDamageRare] = GetDefaultValue("Rate.Creature.Damage.Rare", 1.0f); - Values[WorldCfg.RateCreatureDamageTrivial] = GetDefaultValue("Rate.Creature.Damage.Trivial", 1.0f); - Values[WorldCfg.RateCreatureDamageMinusmob] = GetDefaultValue("Rate.Creature.Damage.MinusMob", 1.0f); - Values[WorldCfg.RateCreatureSpelldamageNormal] = GetDefaultValue("Rate.Creature.SpellDamage.Normal", 1.0f); - Values[WorldCfg.RateCreatureSpelldamageElite] = GetDefaultValue("Rate.Creature.SpellDamage.Elite", 1.0f); - Values[WorldCfg.RateCreatureSpelldamageRareelite] = GetDefaultValue("Rate.Creature.SpellDamage.RareElite", 1.0f); - Values[WorldCfg.RateCreatureSpelldamageObsolete] = GetDefaultValue("Rate.Creature.SpellDamage.Obsolete", 1.0f); - Values[WorldCfg.RateCreatureSpelldamageRare] = GetDefaultValue("Rate.Creature.SpellDamage.Rare", 1.0f); - Values[WorldCfg.RateCreatureSpelldamageTrivial] = GetDefaultValue("Rate.Creature.SpellDamage.Trivial", 1.0f); - Values[WorldCfg.RateCreatureSpelldamageMinusmob] = GetDefaultValue("Rate.Creature.SpellDamage.MinusMob", 1.0f); - Values[WorldCfg.RateCreatureAggro] = GetDefaultValue("Rate.Creature.Aggro", 1.0f); - Values[WorldCfg.RateRestIngame] = GetDefaultValue("Rate.Rest.InGame", 1.0f); - Values[WorldCfg.RateRestOfflineInTavernOrCity] = GetDefaultValue("Rate.Rest.Offline.InTavernOrCity", 1.0f); - Values[WorldCfg.RateRestOfflineInWilderness] = GetDefaultValue("Rate.Rest.Offline.InWilderness", 1.0f); - Values[WorldCfg.RateDamageFall] = GetDefaultValue("Rate.Damage.Fall", 1.0f); - Values[WorldCfg.RateAuctionTime] = GetDefaultValue("Rate.Auction.Time", 1.0f); - Values[WorldCfg.RateAuctionDeposit] = GetDefaultValue("Rate.Auction.Deposit", 1.0f); - Values[WorldCfg.RateAuctionCut] = GetDefaultValue("Rate.Auction.Cut", 1.0f); - Values[WorldCfg.RateHonor] = GetDefaultValue("Rate.Honor", 1.0f); - Values[WorldCfg.RateInstanceResetTime] = GetDefaultValue("Rate.InstanceResetTime", 1.0f); - Values[WorldCfg.RateMovespeed] = GetDefaultValue("Rate.MoveSpeed", 1.0f); - if ((float)Values[WorldCfg.RateMovespeed] < 0.0f) - { - Log.outError(LogFilter.ServerLoading, "Rate.MoveSpeed ({0}) must be > 0. Using 1 instead.", Values[WorldCfg.RateMovespeed]); - Values[WorldCfg.RateMovespeed] = 1.0f; - } - - Values[WorldCfg.RateCorpseDecayLooted] = GetDefaultValue("Rate.Corpse.Decay.Looted", 0.5f); - - Values[WorldCfg.RateDurabilityLossOnDeath] = GetDefaultValue("DurabilityLoss.OnDeath", 10.0f); - if ((float)Values[WorldCfg.RateDurabilityLossOnDeath] < 0.0f) - { - Log.outError(LogFilter.ServerLoading, "DurabilityLoss.OnDeath ({0}) must be >=0. Using 0.0 instead.", Values[WorldCfg.RateDurabilityLossOnDeath]); - Values[WorldCfg.RateDurabilityLossOnDeath] = 0.0f; - } - if ((float)Values[WorldCfg.RateDurabilityLossOnDeath] > 100.0f) - { - Log.outError(LogFilter.ServerLoading, "DurabilityLoss.OnDeath ({0}) must be <= 100. Using 100.0 instead.", Values[WorldCfg.RateDurabilityLossOnDeath]); - Values[WorldCfg.RateDurabilityLossOnDeath] = 0.0f; - } - Values[WorldCfg.RateDurabilityLossOnDeath] = (float)Values[WorldCfg.RateDurabilityLossOnDeath] / 100.0f; - - Values[WorldCfg.RateDurabilityLossDamage] = GetDefaultValue("DurabilityLossChance.Damage", 0.5f); - if ((float)Values[WorldCfg.RateDurabilityLossDamage] < 0.0f) - { - Log.outError(LogFilter.ServerLoading, "DurabilityLossChance.Damage ({0}) must be >=0. Using 0.0 instead.", Values[WorldCfg.RateDurabilityLossDamage]); - Values[WorldCfg.RateDurabilityLossDamage] = 0.0f; - } - Values[WorldCfg.RateDurabilityLossAbsorb] = GetDefaultValue("DurabilityLossChance.Absorb", 0.5f); - if ((float)Values[WorldCfg.RateDurabilityLossAbsorb] < 0.0f) - { - Log.outError(LogFilter.ServerLoading, "DurabilityLossChance.Absorb ({0}) must be >=0. Using 0.0 instead.", Values[WorldCfg.RateDurabilityLossAbsorb]); - Values[WorldCfg.RateDurabilityLossAbsorb] = 0.0f; - } - Values[WorldCfg.RateDurabilityLossParry] = GetDefaultValue("DurabilityLossChance.Parry", 0.05f); - if ((float)Values[WorldCfg.RateDurabilityLossParry] < 0.0f) - { - Log.outError(LogFilter.ServerLoading, "DurabilityLossChance.Parry ({0}) must be >=0. Using 0.0 instead.", Values[WorldCfg.RateDurabilityLossParry]); - Values[WorldCfg.RateDurabilityLossParry] = 0.0f; - } - Values[WorldCfg.RateDurabilityLossBlock] = GetDefaultValue("DurabilityLossChance.Block", 0.05f); - if ((float)Values[WorldCfg.RateDurabilityLossBlock] < 0.0f) - { - Log.outError(LogFilter.ServerLoading, "DurabilityLossChance.Block ({0}) must be >=0. Using 0.0 instead.", Values[WorldCfg.RateDurabilityLossBlock]); - Values[WorldCfg.RateDurabilityLossBlock] = 0.0f; - } - Values[WorldCfg.RateMoneyQuest] = GetDefaultValue("Rate.Quest.Money.Reward", 1.0f); - if ((float)Values[WorldCfg.RateMoneyQuest] < 0.0f) - { - Log.outError(LogFilter.ServerLoading, "Rate.Quest.Money.Reward ({0}) must be >=0. Using 0 instead.", Values[WorldCfg.RateMoneyQuest]); - Values[WorldCfg.RateMoneyQuest] = 0.0f; - } - Values[WorldCfg.RateMoneyMaxLevelQuest] = GetDefaultValue("Rate.Quest.Money.Max.Level.Reward", 1.0f); - if ((float)Values[WorldCfg.RateMoneyMaxLevelQuest] < 0.0f) - { - Log.outError(LogFilter.ServerLoading, "Rate.Quest.Money.Max.Level.Reward ({0}) must be >=0. Using 0 instead.", Values[WorldCfg.RateMoneyMaxLevelQuest]); - Values[WorldCfg.RateMoneyMaxLevelQuest] = 0.0f; - } - - // Read other configuration items from the config file - Values[WorldCfg.DurabilityLossInPvp] = GetDefaultValue("DurabilityLoss.InPvP", false); - - Values[WorldCfg.Compression] = GetDefaultValue("Compression", 1); - if ((int)Values[WorldCfg.Compression] < 1 || (int)Values[WorldCfg.Compression] > 9) - { - Log.outError(LogFilter.ServerLoading, "Compression Level ({0}) must be in range 1..9. Using default compression Level (1).", Values[WorldCfg.Compression]); - Values[WorldCfg.Compression] = 1; - } - Values[WorldCfg.AddonChannel] = GetDefaultValue("AddonChannel", true); - Values[WorldCfg.CleanCharacterDb] = GetDefaultValue("CleanCharacterDB", false); - Values[WorldCfg.PersistentCharacterCleanFlags] = GetDefaultValue("PersistentCharacterCleanFlags", 0); - Values[WorldCfg.AuctionReplicateDelay] = GetDefaultValue("Auction.ReplicateItemsCooldown", 900); - Values[WorldCfg.AuctionSearchDelay] = GetDefaultValue("Auction.SearchDelay", 300); - if ((int)Values[WorldCfg.AuctionSearchDelay] < 100 || (int)Values[WorldCfg.AuctionSearchDelay] > 10000) - { - Log.outError(LogFilter.ServerLoading, "Auction.SearchDelay ({0}) must be between 100 and 10000. Using default of 300ms", Values[WorldCfg.AuctionSearchDelay]); - Values[WorldCfg.AuctionSearchDelay] = 300; - } - Values[WorldCfg.AuctionTaintedSearchDelay] = GetDefaultValue("Auction.TaintedSearchDelay", 3000); - if ((int)Values[WorldCfg.AuctionTaintedSearchDelay] < 100 || (int)Values[WorldCfg.AuctionTaintedSearchDelay] > 10000) - { - Log.outError(LogFilter.ServerLoading, $"Auction.TaintedSearchDelay ({Values[WorldCfg.AuctionTaintedSearchDelay]}) must be between 100 and 10000. Using default of 3s"); - Values[WorldCfg.AuctionTaintedSearchDelay] = 3000; - } - Values[WorldCfg.ChatChannelLevelReq] = GetDefaultValue("ChatLevelReq.Channel", 1); - Values[WorldCfg.ChatWhisperLevelReq] = GetDefaultValue("ChatLevelReq.Whisper", 1); - Values[WorldCfg.ChatEmoteLevelReq] = GetDefaultValue("ChatLevelReq.Emote", 1); - Values[WorldCfg.ChatSayLevelReq] = GetDefaultValue("ChatLevelReq.Say", 1); - Values[WorldCfg.ChatYellLevelReq] = GetDefaultValue("ChatLevelReq.Yell", 1); - Values[WorldCfg.PartyLevelReq] = GetDefaultValue("PartyLevelReq", 1); - Values[WorldCfg.TradeLevelReq] = GetDefaultValue("LevelReq.Trade", 1); - Values[WorldCfg.AuctionLevelReq] = GetDefaultValue("LevelReq.Auction", 1); - Values[WorldCfg.MailLevelReq] = GetDefaultValue("LevelReq.Mail", 1); - Values[WorldCfg.PreserveCustomChannels] = GetDefaultValue("PreserveCustomChannels", false); - Values[WorldCfg.PreserveCustomChannelDuration] = GetDefaultValue("PreserveCustomChannelDuration", 14); - Values[WorldCfg.PreserveCustomChannelInterval] = GetDefaultValue("PreserveCustomChannelInterval", 5); - Values[WorldCfg.GridUnload] = GetDefaultValue("GridUnload", true); - Values[WorldCfg.BasemapLoadGrids] = GetDefaultValue("BaseMapLoadAllGrids", false); - if ((bool)Values[WorldCfg.BasemapLoadGrids] && (bool)Values[WorldCfg.GridUnload]) - { - Log.outError(LogFilter.ServerLoading, "BaseMapLoadAllGrids enabled, but GridUnload also enabled. GridUnload must be disabled to enable base map pre-loading. Base map pre-loading disabled"); - Values[WorldCfg.BasemapLoadGrids] = false; - } - Values[WorldCfg.InstancemapLoadGrids] = GetDefaultValue("InstanceMapLoadAllGrids", false); - if ((bool)Values[WorldCfg.InstancemapLoadGrids] && (bool)Values[WorldCfg.GridUnload]) - { - Log.outError(LogFilter.ServerLoading, "InstanceMapLoadAllGrids enabled, but GridUnload also enabled. GridUnload must be disabled to enable instance map pre-loading. Instance map pre-loading disabled"); - Values[WorldCfg.InstancemapLoadGrids] = false; - } - - Values[WorldCfg.BattlegroundMapLoadGrids] = GetDefaultValue("BattlegroundMapLoadAllGrids", true); - Values[WorldCfg.IntervalSave] = GetDefaultValue("PlayerSaveInterval", 15 * Time.Minute * Time.InMilliseconds); - Values[WorldCfg.IntervalDisconnectTolerance] = GetDefaultValue("DisconnectToleranceInterval", 0); - Values[WorldCfg.StatsSaveOnlyOnLogout] = GetDefaultValue("PlayerSave.Stats.SaveOnlyOnLogout", true); - - Values[WorldCfg.MinLevelStatSave] = GetDefaultValue("PlayerSave.Stats.MinLevel", 0); - if ((int)Values[WorldCfg.MinLevelStatSave] > SharedConst.MaxLevel) - { - Log.outError(LogFilter.ServerLoading, "PlayerSave.Stats.MinLevel ({0}) must be in range 0..80. Using default, do not save character stats (0).", Values[WorldCfg.MinLevelStatSave]); - Values[WorldCfg.MinLevelStatSave] = 0; - } - - Values[WorldCfg.IntervalGridclean] = GetDefaultValue("GridCleanUpDelay", 5 * Time.Minute * Time.InMilliseconds); - if ((int)Values[WorldCfg.IntervalGridclean] < MapConst.MinGridDelay) - { - Log.outError(LogFilter.ServerLoading, "GridCleanUpDelay ({0}) must be greater {1} Use this minimal value.", Values[WorldCfg.IntervalGridclean], MapConst.MinGridDelay); - Values[WorldCfg.IntervalGridclean] = MapConst.MinGridDelay; - } - - Values[WorldCfg.IntervalMapupdate] = GetDefaultValue("MapUpdateInterval", 10); - if ((int)Values[WorldCfg.IntervalMapupdate] < MapConst.MinMapUpdateDelay) - { - Log.outError(LogFilter.ServerLoading, "MapUpdateInterval ({0}) must be greater {1}. Use this minimal value.", Values[WorldCfg.IntervalMapupdate], MapConst.MinMapUpdateDelay); - Values[WorldCfg.IntervalMapupdate] = MapConst.MinMapUpdateDelay; - } - - Values[WorldCfg.IntervalChangeweather] = GetDefaultValue("ChangeWeatherInterval", 10 * Time.Minute * Time.InMilliseconds); - if (reload) - { - int val = GetDefaultValue("WorldServerPort", 8085); - if (val != (int)Values[WorldCfg.PortWorld]) - Log.outError(LogFilter.ServerLoading, "WorldServerPort option can't be changed at worldserver.conf reload, using current value ({0}).", Values[WorldCfg.PortWorld]); - } - else - Values[WorldCfg.PortWorld] = GetDefaultValue("WorldServerPort", 8085); - // Config values are in "milliseconds" but we handle SocketTimeOut only as "seconds" so divide by 1000 - Values[WorldCfg.SocketTimeoutTime] = GetDefaultValue("SocketTimeOutTime", 900000) / 1000; - Values[WorldCfg.SocketTimeoutTimeActive] = GetDefaultValue("SocketTimeOutTimeActive", 60000) / 1000; - Values[WorldCfg.SessionAddDelay] = GetDefaultValue("SessionAddDelay", 10000); + Values[WorldCfg.SocketTimeoutTime] = (uint)Values[WorldCfg.SocketTimeoutTime] / 1000; + Values[WorldCfg.SocketTimeoutTimeActive] = (uint)Values[WorldCfg.SocketTimeoutTime] / 1000; - Values[WorldCfg.GroupXpDistance] = GetDefaultValue("MaxGroupXPDistance", 74.0f); - Values[WorldCfg.MaxRecruitAFriendDistance] = GetDefaultValue("MaxRecruitAFriendBonusDistance", 100.0f); - Values[WorldCfg.MinQuestScaledXpRatio] = GetDefaultValue("MinQuestScaledXPRatio", 0); - if ((int)Values[WorldCfg.MinQuestScaledXpRatio] > 100) + // must be after CONFIG_CHARACTERS_PER_REALM + if ((uint)Values[WorldCfg.CharactersPerAccount] < (uint)Values[WorldCfg.CharactersPerRealm]) { - Log.outError(LogFilter.ServerLoading, $"MinQuestScaledXPRatio ({Values[WorldCfg.MinQuestScaledXpRatio]}) must be in range 0..100. Set to 0."); - Values[WorldCfg.MinQuestScaledXpRatio] = 0; - } - - Values[WorldCfg.MinCreatureScaledXpRatio] = GetDefaultValue("MinCreatureScaledXPRatio", 0); - if ((int)Values[WorldCfg.MinCreatureScaledXpRatio] > 100) - { - Log.outError(LogFilter.ServerLoading, $"MinCreatureScaledXPRatio ({Values[WorldCfg.MinCreatureScaledXpRatio]}) must be in range 0..100. Set to 0."); - Values[WorldCfg.MinCreatureScaledXpRatio] = 0; - } - - Values[WorldCfg.MinDiscoveredScaledXpRatio] = GetDefaultValue("MinDiscoveredScaledXPRatio", 0); - if ((int)Values[WorldCfg.MinDiscoveredScaledXpRatio] > 100) - { - Log.outError(LogFilter.ServerLoading, $"MinDiscoveredScaledXPRatio ({Values[WorldCfg.MinDiscoveredScaledXpRatio]}) must be in range 0..100. Set to 0."); - Values[WorldCfg.MinDiscoveredScaledXpRatio] = 0; - } - - /// @todo Add MonsterSight (with meaning) in worldserver.conf or put them as define - Values[WorldCfg.SightMonster] = GetDefaultValue("MonsterSight", 50.0f); - - Values[WorldCfg.RegenHpCannotReachTargetInRaid] = GetDefaultValue("Creature.RegenHPCannotReachTargetInRaid", true); - - if (reload) - { - int val = GetDefaultValue("GameType", 0); - if (val != (int)Values[WorldCfg.GameType]) - Log.outError(LogFilter.ServerLoading, "GameType option can't be changed at worldserver.conf reload, using current value ({0}).", Values[WorldCfg.GameType]); - } - else - Values[WorldCfg.GameType] = GetDefaultValue("GameType", 0); - - if (reload) - { - int val = (int)GetDefaultValue("RealmZone", RealmManager.HardcodedDevelopmentRealmCategoryId); - if (val != (int)Values[WorldCfg.RealmZone]) - Log.outError(LogFilter.ServerLoading, "RealmZone option can't be changed at worldserver.conf reload, using current value ({0}).", Values[WorldCfg.RealmZone]); - } - else - Values[WorldCfg.RealmZone] = GetDefaultValue("RealmZone", RealmManager.HardcodedDevelopmentRealmCategoryId); - - Values[WorldCfg.AllowTwoSideInteractionCalendar] = GetDefaultValue("AllowTwoSide.Interaction.Calendar", false); - Values[WorldCfg.AllowTwoSideInteractionChannel] = GetDefaultValue("AllowTwoSide.Interaction.Channel", false); - Values[WorldCfg.AllowTwoSideInteractionGroup] = GetDefaultValue("AllowTwoSide.Interaction.Group", false); - Values[WorldCfg.AllowTwoSideInteractionGuild] = GetDefaultValue("AllowTwoSide.Interaction.Guild", false); - Values[WorldCfg.AllowTwoSideInteractionAuction] = GetDefaultValue("AllowTwoSide.Interaction.Auction", true); - Values[WorldCfg.AllowTwoSideTrade] = GetDefaultValue("AllowTwoSide.Trade", false); - Values[WorldCfg.StrictPlayerNames] = GetDefaultValue("StrictPlayerNames", 0); - Values[WorldCfg.StrictCharterNames] = GetDefaultValue("StrictCharterNames", 0); - Values[WorldCfg.StrictPetNames] = GetDefaultValue("StrictPetNames", 0); - - Values[WorldCfg.MinPlayerName] = GetDefaultValue("MinPlayerName", 2); - if ((int)Values[WorldCfg.MinPlayerName] < 1 || (int)Values[WorldCfg.MinPlayerName] > 12) - { - Log.outError(LogFilter.ServerLoading, "MinPlayerName ({0}) must be in range 1..{1}. Set to 2.", Values[WorldCfg.MinPlayerName], 12); - Values[WorldCfg.MinPlayerName] = 2; - } - - Values[WorldCfg.MinCharterName] = GetDefaultValue("MinCharterName", 2); - if ((int)Values[WorldCfg.MinCharterName] < 1 || (int)Values[WorldCfg.MinCharterName] > 24) - { - Log.outError(LogFilter.ServerLoading, "MinCharterName ({0}) must be in range 1..{1}. Set to 2.", Values[WorldCfg.MinCharterName], 24); - Values[WorldCfg.MinCharterName] = 2; - } - - Values[WorldCfg.MinPetName] = GetDefaultValue("MinPetName", 2); - if ((int)Values[WorldCfg.MinPetName] < 1 || (int)Values[WorldCfg.MinPetName] > 12) - { - Log.outError(LogFilter.ServerLoading, "MinPetName ({0}) must be in range 1..{1}. Set to 2.", Values[WorldCfg.MinPetName], 12); - Values[WorldCfg.MinPetName] = 2; - } - - Values[WorldCfg.CharterCostGuild] = GetDefaultValue("Guild.CharterCost", 1000); - Values[WorldCfg.CharterCostArena2v2] = GetDefaultValue("ArenaTeam.CharterCost.2v2", 800000); - Values[WorldCfg.CharterCostArena3v3] = GetDefaultValue("ArenaTeam.CharterCost.3v3", 1200000); - Values[WorldCfg.CharterCostArena5v5] = GetDefaultValue("ArenaTeam.CharterCost.5v5", 2000000); - - Values[WorldCfg.CharacterCreatingDisabled] = GetDefaultValue("CharacterCreating.Disabled", 0); - Values[WorldCfg.CharacterCreatingDisabledRacemask] = GetDefaultValue("CharacterCreating.Disabled.RaceMask", 0); - Values[WorldCfg.CharacterCreatingDisabledClassmask] = GetDefaultValue("CharacterCreating.Disabled.ClassMask", 0); - - Values[WorldCfg.CharactersPerRealm] = GetDefaultValue("CharactersPerRealm", 60); - if ((int)Values[WorldCfg.CharactersPerRealm] < 1 || (int)Values[WorldCfg.CharactersPerRealm] > 200) - { - Log.outError(LogFilter.ServerLoading, "CharactersPerRealm ({0}) must be in range 1..200. Set to 200.", Values[WorldCfg.CharactersPerRealm]); - Values[WorldCfg.CharactersPerRealm] = 200; - } - - // must be after CharactersPerRealm - Values[WorldCfg.CharactersPerAccount] = GetDefaultValue("CharactersPerAccount", 60); - if ((int)Values[WorldCfg.CharactersPerAccount] < (int)Values[WorldCfg.CharactersPerRealm]) - { - Log.outError(LogFilter.ServerLoading, "CharactersPerAccount ({0}) can't be less than CharactersPerRealm ({1}).", Values[WorldCfg.CharactersPerAccount], Values[WorldCfg.CharactersPerRealm]); + Log.outError(LogFilter.ServerLoading, $"CharactersPerAccount ({Values[WorldCfg.CharactersPerAccount]}) can't be less than CharactersPerRealm ({Values[WorldCfg.CharactersPerRealm]})."); Values[WorldCfg.CharactersPerAccount] = Values[WorldCfg.CharactersPerRealm]; } - Values[WorldCfg.CharacterCreatingEvokersPerRealm] = GetDefaultValue("CharacterCreating.EvokersPerRealm", 1); - if ((int)Values[WorldCfg.CharacterCreatingEvokersPerRealm] < 0 || (int)Values[WorldCfg.CharacterCreatingEvokersPerRealm] > 10) + void validateStartLevel(WorldCfg config, string name) { - Log.outError(LogFilter.ServerLoading, $"CharacterCreating.EvokersPerRealm ({Values[WorldCfg.CharacterCreatingEvokersPerRealm]}) must be in range 0..10. Set to 1."); - Values[WorldCfg.CharacterCreatingEvokersPerRealm] = 1; + uint maxLevel = (uint)Values[WorldCfg.MaxPlayerLevel]; + if ((uint)Values[config] > maxLevel) + { + Log.outError(LogFilter.ServerLoading, $"{name} ({Values[config]}) must be in range 1..MaxPlayerLevel({maxLevel}). Set to {maxLevel}."); + Values[config] = maxLevel; + } } - Values[WorldCfg.CharacterCreatingMinLevelForDemonHunter] = GetDefaultValue("CharacterCreating.MinLevelForDemonHunter", 0); - Values[WorldCfg.CharacterCreatingMinLevelForEvoker] = GetDefaultValue("CharacterCreating.MinLevelForEvoker", 50); - Values[WorldCfg.CharacterCreatingDisableAlliedRaceAchievementRequirement] = GetDefaultValue("CharacterCreating.DisableAlliedRaceAchievementRequirement", false); + validateStartLevel(WorldCfg.StartPlayerLevel, "StartPlayerLevel"); + validateStartLevel(WorldCfg.StartDeathKnightPlayerLevel, "StartDeathKnightPlayerLevel"); + validateStartLevel(WorldCfg.StartDemonHunterPlayerLevel, "StartDemonHunterPlayerLevel"); + validateStartLevel(WorldCfg.StartEvokerPlayerLevel, "StartEvokerPlayerLevel"); + validateStartLevel(WorldCfg.StartAlliedRaceLevel, "StartDemonHunterPlayerLevel"); + validateStartLevel(WorldCfg.MaxRecruitAFriendBonusPlayerLevel, "RecruitAFriend.MaxLevel"); - Values[WorldCfg.SkipCinematics] = GetDefaultValue("SkipCinematics", 0); - if ((int)Values[WorldCfg.SkipCinematics] < 0 || (int)Values[WorldCfg.SkipCinematics] > 2) - { - Log.outError(LogFilter.ServerLoading, "SkipCinematics ({0}) must be in range 0..2. Set to 0.", Values[WorldCfg.SkipCinematics]); - Values[WorldCfg.SkipCinematics] = 0; - } - - if (reload) - { - int val = GetDefaultValue("MaxPlayerLevel", SharedConst.DefaultMaxLevel); - if (val != (int)Values[WorldCfg.MaxPlayerLevel]) - Log.outError(LogFilter.ServerLoading, "MaxPlayerLevel option can't be changed at config reload, using current value ({0}).", Values[WorldCfg.MaxPlayerLevel]); - } - else - Values[WorldCfg.MaxPlayerLevel] = GetDefaultValue("MaxPlayerLevel", SharedConst.DefaultMaxLevel); - - if ((int)Values[WorldCfg.MaxPlayerLevel] > SharedConst.MaxLevel) - { - Log.outError(LogFilter.ServerLoading, "MaxPlayerLevel ({0}) must be in range 1..{1}. Set to {1}.", Values[WorldCfg.MaxPlayerLevel], SharedConst.MaxLevel); - Values[WorldCfg.MaxPlayerLevel] = SharedConst.MaxLevel; - } - - Values[WorldCfg.MinDualspecLevel] = GetDefaultValue("MinDualSpecLevel", 40); - - Values[WorldCfg.StartPlayerLevel] = GetDefaultValue("StartPlayerLevel", 1); - if ((int)Values[WorldCfg.StartPlayerLevel] < 1) - { - Log.outError(LogFilter.ServerLoading, "StartPlayerLevel ({0}) must be in range 1..MaxPlayerLevel({1}). Set to 1.", Values[WorldCfg.StartPlayerLevel], Values[WorldCfg.MaxPlayerLevel]); - Values[WorldCfg.StartPlayerLevel] = 1; - } - else if ((int)Values[WorldCfg.StartPlayerLevel] > (int)Values[WorldCfg.MaxPlayerLevel]) - { - Log.outError(LogFilter.ServerLoading, "StartPlayerLevel ({0}) must be in range 1..MaxPlayerLevel({1}). Set to {2}.", Values[WorldCfg.StartPlayerLevel], Values[WorldCfg.MaxPlayerLevel], Values[WorldCfg.MaxPlayerLevel]); - Values[WorldCfg.StartPlayerLevel] = Values[WorldCfg.MaxPlayerLevel]; - } - - Values[WorldCfg.StartDeathKnightPlayerLevel] = GetDefaultValue("StartDeathKnightPlayerLevel", 8); - if ((int)Values[WorldCfg.StartDeathKnightPlayerLevel] < 1) - { - Log.outError(LogFilter.ServerLoading, "StartDeathKnightPlayerLevel ({0}) must be in range 1..MaxPlayerLevel({1}). Set to 1.", - Values[WorldCfg.StartDeathKnightPlayerLevel], Values[WorldCfg.MaxPlayerLevel]); - Values[WorldCfg.StartDeathKnightPlayerLevel] = 1; - } - else if ((int)Values[WorldCfg.StartDeathKnightPlayerLevel] > (int)Values[WorldCfg.MaxPlayerLevel]) - { - Log.outError(LogFilter.ServerLoading, "StartDeathKnightPlayerLevel ({0}) must be in range 1..MaxPlayerLevel({1}). Set to {2}.", - Values[WorldCfg.StartDeathKnightPlayerLevel], Values[WorldCfg.MaxPlayerLevel], Values[WorldCfg.MaxPlayerLevel]); - Values[WorldCfg.StartDeathKnightPlayerLevel] = Values[WorldCfg.MaxPlayerLevel]; - } - - Values[WorldCfg.StartDemonHunterPlayerLevel] = GetDefaultValue("StartDemonHunterPlayerLevel", 8); - if ((int)Values[WorldCfg.StartDemonHunterPlayerLevel] < 1) - { - Log.outError(LogFilter.ServerLoading, "StartDemonHunterPlayerLevel ({0}) must be in range 1..MaxPlayerLevel({1}). Set to 1.", - Values[WorldCfg.StartDemonHunterPlayerLevel], Values[WorldCfg.MaxPlayerLevel]); - Values[WorldCfg.StartDemonHunterPlayerLevel] = 1; - } - else if ((int)Values[WorldCfg.StartDemonHunterPlayerLevel] > (int)Values[WorldCfg.MaxPlayerLevel]) - { - Log.outError(LogFilter.ServerLoading, "StartDemonHunterPlayerLevel ({0}) must be in range 1..MaxPlayerLevel({1}). Set to {2}.", - Values[WorldCfg.StartDemonHunterPlayerLevel], Values[WorldCfg.MaxPlayerLevel], Values[WorldCfg.MaxPlayerLevel]); - Values[WorldCfg.StartDemonHunterPlayerLevel] = Values[WorldCfg.MaxPlayerLevel]; - } - - Values[WorldCfg.StartEvokerPlayerLevel] = GetDefaultValue("StartEvokerPlayerLevel", 10); - if ((int)Values[WorldCfg.StartEvokerPlayerLevel] < 1) - { - Log.outError(LogFilter.ServerLoading, $"StartEvokerPlayerLevel ({Values[WorldCfg.StartEvokerPlayerLevel]}) must be in range 1..MaxPlayerLevel({Values[WorldCfg.MaxPlayerLevel]}). Set to 1."); - Values[WorldCfg.StartEvokerPlayerLevel] = 1; - } - else if ((int)Values[WorldCfg.StartEvokerPlayerLevel] > (int)Values[WorldCfg.MaxPlayerLevel]) - { - Log.outError(LogFilter.ServerLoading, $"StartEvokerPlayerLevel ({Values[WorldCfg.StartEvokerPlayerLevel]}) must be in range 1..MaxPlayerLevel({Values[WorldCfg.MaxPlayerLevel]}). Set to {Values[WorldCfg.MaxPlayerLevel]}."); - Values[WorldCfg.StartEvokerPlayerLevel] = Values[WorldCfg.MaxPlayerLevel]; - } - - Values[WorldCfg.StartAlliedRaceLevel] = GetDefaultValue("StartAlliedRacePlayerLevel", 10); - if ((int)Values[WorldCfg.StartAlliedRaceLevel] < 1) - { - Log.outError(LogFilter.ServerLoading, $"StartAlliedRaceLevel ({Values[WorldCfg.StartAlliedRaceLevel]}) must be in range 1..MaxPlayerLevel({Values[WorldCfg.MaxPlayerLevel]}). Set to 1."); - Values[WorldCfg.StartAlliedRaceLevel] = 1; - } - else if ((int)Values[WorldCfg.StartAlliedRaceLevel] > (int)Values[WorldCfg.MaxPlayerLevel]) - { - Log.outError(LogFilter.ServerLoading, $"StartAlliedRaceLevel ({Values[WorldCfg.StartAlliedRaceLevel]}) must be in range 1..MaxPlayerLevel({Values[WorldCfg.MaxPlayerLevel]}). Set to {Values[WorldCfg.MaxPlayerLevel]}."); - Values[WorldCfg.StartAlliedRaceLevel] = Values[WorldCfg.MaxPlayerLevel]; - } - - Values[WorldCfg.StartPlayerMoney] = GetDefaultValue("StartPlayerMoney", 0); - if ((int)Values[WorldCfg.StartPlayerMoney] < 0) - { - Log.outError(LogFilter.ServerLoading, "StartPlayerMoney ({0}) must be in range 0..{1}. Set to {2}.", Values[WorldCfg.StartPlayerMoney], PlayerConst.MaxMoneyAmount, 0); - Values[WorldCfg.StartPlayerMoney] = 0; - } - else if ((int)Values[WorldCfg.StartPlayerMoney] > 0x7FFFFFFF - 1) // TODO: (See MaxMoneyAMOUNT) - { - Log.outError(LogFilter.ServerLoading, "StartPlayerMoney ({0}) must be in range 0..{1}. Set to {2}.", - Values[WorldCfg.StartPlayerMoney], 0x7FFFFFFF - 1, 0x7FFFFFFF - 1); - Values[WorldCfg.StartPlayerMoney] = 0x7FFFFFFF - 1; - } - - Values[WorldCfg.CurrencyResetHour] = GetDefaultValue("Currency.ResetHour", 3); - if ((int)Values[WorldCfg.CurrencyResetHour] > 23) - { - Log.outError(LogFilter.ServerLoading, "StartPlayerMoney ({0}) must be in range 0..{1}. Set to {2}.", Values[WorldCfg.CurrencyResetHour] = 3); - } - Values[WorldCfg.CurrencyResetDay] = GetDefaultValue("Currency.ResetDay", 3); - if ((int)Values[WorldCfg.CurrencyResetDay] > 6) - { - Log.outError(LogFilter.ServerLoading, "Currency.ResetDay ({0}) can't be load. Set to 3.", Values[WorldCfg.CurrencyResetDay]); - Values[WorldCfg.CurrencyResetDay] = 3; - } - Values[WorldCfg.CurrencyResetInterval] = GetDefaultValue("Currency.ResetInterval", 7); - if ((int)Values[WorldCfg.CurrencyResetInterval] <= 0) - { - Log.outError(LogFilter.ServerLoading, "Currency.ResetInterval ({0}) must be > 0, set to default 7.", Values[WorldCfg.CurrencyResetInterval]); - Values[WorldCfg.CurrencyResetInterval] = 7; - } - - Values[WorldCfg.MaxRecruitAFriendBonusPlayerLevel] = GetDefaultValue("RecruitAFriend.MaxLevel", 60); - if ((int)Values[WorldCfg.MaxRecruitAFriendBonusPlayerLevel] > (int)Values[WorldCfg.MaxPlayerLevel]) - { - Log.outError(LogFilter.ServerLoading, "RecruitAFriend.MaxLevel ({0}) must be in the range 0..MaxLevel({1}). Set to {2}.", - Values[WorldCfg.MaxRecruitAFriendBonusPlayerLevel], Values[WorldCfg.MaxPlayerLevel], 60); - Values[WorldCfg.MaxRecruitAFriendBonusPlayerLevel] = 60; - } - - Values[WorldCfg.MaxRecruitAFriendBonusPlayerLevelDifference] = GetDefaultValue("RecruitAFriend.MaxDifference", 4); - Values[WorldCfg.AllTaxiPaths] = GetDefaultValue("AllFlightPaths", false); - Values[WorldCfg.InstantTaxi] = GetDefaultValue("InstantFlightPaths", false); - - Values[WorldCfg.InstanceIgnoreLevel] = GetDefaultValue("Instance.IgnoreLevel", false); - Values[WorldCfg.InstanceIgnoreRaid] = GetDefaultValue("Instance.IgnoreRaid", false); - - Values[WorldCfg.CastUnstuck] = GetDefaultValue("CastUnstuck", true); - Values[WorldCfg.ResetScheduleWeekDay] = GetDefaultValue("ResetSchedule.WeekDay", 2); - Values[WorldCfg.ResetScheduleHour] = GetDefaultValue("ResetSchedule.Hour", 8); - Values[WorldCfg.InstanceUnloadDelay] = GetDefaultValue("Instance.UnloadDelay", 30 * Time.Minute * Time.InMilliseconds); - Values[WorldCfg.DailyQuestResetTimeHour] = GetDefaultValue("Quests.DailyResetTime", 3); - if ((int)Values[WorldCfg.DailyQuestResetTimeHour] > 23) - { - Log.outError(LogFilter.ServerLoading, $"Quests.DailyResetTime ({Values[WorldCfg.DailyQuestResetTimeHour]}) must be in range 0..23. Set to 3."); - Values[WorldCfg.DailyQuestResetTimeHour] = 3; - } - - Values[WorldCfg.WeeklyQuestResetTimeWDay] = GetDefaultValue("Quests.WeeklyResetWDay", 3); - if ((int)Values[WorldCfg.WeeklyQuestResetTimeWDay] > 6) - { - Log.outError(LogFilter.ServerLoading, $"Quests.WeeklyResetDay ({Values[WorldCfg.WeeklyQuestResetTimeWDay]}) must be in range 0..6. Set to 3 (Wednesday)."); - Values[WorldCfg.WeeklyQuestResetTimeWDay] = 3; - } - - Values[WorldCfg.MaxPrimaryTradeSkill] = GetDefaultValue("MaxPrimaryTradeSkill", 2); - Values[WorldCfg.MinPetitionSigns] = GetDefaultValue("MinPetitionSigns", 4); - if ((int)Values[WorldCfg.MinPetitionSigns] > 4) - { - Log.outError(LogFilter.ServerLoading, "MinPetitionSigns ({0}) must be in range 0..4. Set to 4.", Values[WorldCfg.MinPetitionSigns]); - Values[WorldCfg.MinPetitionSigns] = 4; - } - - Values[WorldCfg.GmLoginState] = GetDefaultValue("GM.LoginState", 2); - Values[WorldCfg.GmVisibleState] = GetDefaultValue("GM.Visible", 2); - Values[WorldCfg.GmChat] = GetDefaultValue("GM.Chat", 2); - Values[WorldCfg.GmWhisperingTo] = GetDefaultValue("GM.WhisperingTo", 2); - Values[WorldCfg.GmFreezeDuration] = GetDefaultValue("GM.FreezeAuraDuration", 0); - - Values[WorldCfg.GmLevelInGmList] = GetDefaultValue("GM.InGMList.Level", (int)AccountTypes.Administrator); - Values[WorldCfg.GmLevelInWhoList] = GetDefaultValue("GM.InWhoList.Level", (int)AccountTypes.Administrator); - Values[WorldCfg.StartGmLevel] = GetDefaultValue("GM.StartLevel", 1); if ((int)Values[WorldCfg.StartGmLevel] < (int)Values[WorldCfg.StartPlayerLevel]) { - Log.outError(LogFilter.ServerLoading, "GM.StartLevel ({0}) must be in range StartPlayerLevel({1})..{2}. Set to {3}.", - Values[WorldCfg.StartGmLevel], Values[WorldCfg.StartPlayerLevel], SharedConst.MaxLevel, Values[WorldCfg.StartPlayerLevel]); + Log.outError(LogFilter.ServerLoading, $"GM.StartLevel ({Values[WorldCfg.StartGmLevel]}) must be in range StartPlayerLevel({Values[WorldCfg.StartPlayerLevel]})..{SharedConst.MaxLevel}. Set to {Values[WorldCfg.StartPlayerLevel]}."); Values[WorldCfg.StartGmLevel] = Values[WorldCfg.StartPlayerLevel]; } - else if ((int)Values[WorldCfg.StartGmLevel] > SharedConst.MaxLevel) - { - Log.outError(LogFilter.ServerLoading, "GM.StartLevel ({0}) must be in range 1..{1}. Set to {1}.", Values[WorldCfg.StartGmLevel], SharedConst.MaxLevel); - Values[WorldCfg.StartGmLevel] = SharedConst.MaxLevel; - } - Values[WorldCfg.AllowGmGroup] = GetDefaultValue("GM.AllowInvite", false); - Values[WorldCfg.GmLowerSecurity] = GetDefaultValue("GM.LowerSecurity", false); - Values[WorldCfg.ForceShutdownThreshold] = GetDefaultValue("GM.ForceShutdownThreshold", 30); - Values[WorldCfg.GroupVisibility] = GetDefaultValue("Visibility.GroupMode", 1); + Log.outInfo(LogFilter.ServerLoading, $"Will clear `logs` table of entries older than {Values[WorldCfg.LogdbCleartime]} seconds every {Values[WorldCfg.LogdbClearinterval]} minutes."); - Values[WorldCfg.MailDeliveryDelay] = GetDefaultValue("MailDeliveryDelay", Time.Hour); - Values[WorldCfg.CleanOldMailTime] = GetDefaultValue("CleanOldMailTime", 4); - if ((int)Values[WorldCfg.CleanOldMailTime] > 23) - { - Log.outError(LogFilter.ServerLoading, $"CleanOldMailTime ({Values[WorldCfg.CleanOldMailTime]}) must be an hour, between 0 and 23. Set to 4."); - Values[WorldCfg.CleanOldMailTime] = 4; - } - - Values[WorldCfg.UptimeUpdate] = GetDefaultValue("UpdateUptimeInterval", 10); - if ((int)Values[WorldCfg.UptimeUpdate] <= 0) - { - Log.outError(LogFilter.ServerLoading, "UpdateUptimeInterval ({0}) must be > 0, set to default 10.", Values[WorldCfg.UptimeUpdate]); - Values[WorldCfg.UptimeUpdate] = 10; - } - - // log db cleanup interval - Values[WorldCfg.LogdbClearinterval] = GetDefaultValue("LogDB.Opt.ClearInterval", 10); - if ((int)Values[WorldCfg.LogdbClearinterval] <= 0) - { - Log.outError(LogFilter.ServerLoading, "LogDB.Opt.ClearInterval ({0}) must be > 0, set to default 10.", Values[WorldCfg.LogdbClearinterval]); - Values[WorldCfg.LogdbClearinterval] = 10; - } - Values[WorldCfg.LogdbCleartime] = GetDefaultValue("LogDB.Opt.ClearTime", 1209600); // 14 days default - Log.outInfo(LogFilter.ServerLoading, "Will clear `logs` table of entries older than {0} seconds every {1} minutes.", Values[WorldCfg.LogdbCleartime], Values[WorldCfg.LogdbClearinterval]); - - Values[WorldCfg.SkillChanceOrange] = GetDefaultValue("SkillChance.Orange", 100); - Values[WorldCfg.SkillChanceYellow] = GetDefaultValue("SkillChance.Yellow", 75); - Values[WorldCfg.SkillChanceGreen] = GetDefaultValue("SkillChance.Green", 25); - Values[WorldCfg.SkillChanceGrey] = GetDefaultValue("SkillChance.Grey", 0); - - Values[WorldCfg.SkillChanceMiningSteps] = GetDefaultValue("SkillChance.MiningSteps", 75); - Values[WorldCfg.SkillChanceSkinningSteps] = GetDefaultValue("SkillChance.SkinningSteps", 75); - - Values[WorldCfg.SkillProspecting] = GetDefaultValue("SkillChance.Prospecting", false); - Values[WorldCfg.SkillMilling] = GetDefaultValue("SkillChance.Milling", false); - - Values[WorldCfg.SkillGainCrafting] = GetDefaultValue("SkillGain.Crafting", 1); - - Values[WorldCfg.SkillGainGathering] = GetDefaultValue("SkillGain.Gathering", 1); - - Values[WorldCfg.MaxOverspeedPings] = GetDefaultValue("MaxOverspeedPings", 2); if ((int)Values[WorldCfg.MaxOverspeedPings] != 0 && (int)Values[WorldCfg.MaxOverspeedPings] < 2) { - Log.outError(LogFilter.ServerLoading, "MaxOverspeedPings ({0}) must be in range 2..infinity (or 0 to disable check). Set to 2.", Values[WorldCfg.MaxOverspeedPings]); + Log.outError(LogFilter.ServerLoading, $"MaxOverspeedPings ({Values[WorldCfg.MaxOverspeedPings]}) must be in range 2..infinity (or 0 to disable check). Set to 2."); Values[WorldCfg.MaxOverspeedPings] = 2; } - Values[WorldCfg.Weather] = GetDefaultValue("ActivateWeather", true); + // always use declined names in the russian client + Cfg_CategoriesRecord category = CliDB.CfgCategoriesStorage.LookupByKey(Values[WorldCfg.RealmZone]); + if (category != null && category.GetCreateCharsetMask().HasFlag(CfgCategoriesCharsets.Russian)) + Values[WorldCfg.DeclinedNamesUsed] = true; - Values[WorldCfg.DisableBreathing] = GetDefaultValue("DisableWaterBreath", (int)AccountTypes.Console); + if ((int)Values[WorldCfg.ClientCacheVersion] == 0) + Values[WorldCfg.ClientCacheVersion] = databaseCacheVersion; - if (reload) + void validateVisibilityDistance(WorldCfg config, string name) { - int val = GetDefaultValue("Expansion", (int)Expansion.WarlordsOfDraenor); - if (val != (int)Values[WorldCfg.Expansion]) - Log.outError(LogFilter.ServerLoading, "Expansion option can't be changed at worldserver.conf reload, using current value ({0}).", Values[WorldCfg.Expansion]); - } - else - Values[WorldCfg.Expansion] = GetDefaultValue("Expansion", Expansion.WarlordsOfDraenor); - - Values[WorldCfg.ChatFloodMessageCount] = GetDefaultValue("ChatFlood.MessageCount", 10); - Values[WorldCfg.ChatFloodMessageDelay] = GetDefaultValue("ChatFlood.MessageDelay", 1); - Values[WorldCfg.ChatFloodMuteTime] = GetDefaultValue("ChatFlood.MuteTime", 10); - - Values[WorldCfg.EventAnnounce] = GetDefaultValue("Event.Announce", false); - - Values[WorldCfg.CreatureFamilyFleeAssistanceRadius] = GetDefaultValue("CreatureFamilyFleeAssistanceRadius", 30.0f); - Values[WorldCfg.CreatureFamilyAssistanceRadius] = GetDefaultValue("CreatureFamilyAssistanceRadius", 10.0f); - Values[WorldCfg.CreatureFamilyAssistanceDelay] = GetDefaultValue("CreatureFamilyAssistanceDelay", 1500); - Values[WorldCfg.CreatureFamilyFleeDelay] = GetDefaultValue("CreatureFamilyFleeDelay", 7000); - - Values[WorldCfg.WorldBossLevelDiff] = GetDefaultValue("WorldBossLevelDiff", 3); - - Values[WorldCfg.QuestEnableQuestTracker] = GetDefaultValue("Quests.EnableQuestTracker", false); - - // note: disable value (-1) will assigned as 0xFFFFFFF, to prevent overflow at calculations limit it to max possible player Level MaxLevel(100) - Values[WorldCfg.QuestLowLevelHideDiff] = GetDefaultValue("Quests.LowLevelHideDiff", 4); - if ((int)Values[WorldCfg.QuestLowLevelHideDiff] > SharedConst.MaxLevel) - Values[WorldCfg.QuestLowLevelHideDiff] = SharedConst.MaxLevel; - Values[WorldCfg.QuestHighLevelHideDiff] = GetDefaultValue("Quests.HighLevelHideDiff", 7); - if ((int)Values[WorldCfg.QuestHighLevelHideDiff] > SharedConst.MaxLevel) - Values[WorldCfg.QuestHighLevelHideDiff] = SharedConst.MaxLevel; - Values[WorldCfg.QuestIgnoreRaid] = GetDefaultValue("Quests.IgnoreRaid", false); - Values[WorldCfg.QuestIgnoreAutoAccept] = GetDefaultValue("Quests.IgnoreAutoAccept", false); - Values[WorldCfg.QuestIgnoreAutoComplete] = GetDefaultValue("Quests.IgnoreAutoComplete", false); - - Values[WorldCfg.RandomBgResetHour] = GetDefaultValue("Battleground.Random.ResetHour", 6); - if ((int)Values[WorldCfg.RandomBgResetHour] > 23) - { - Log.outError(LogFilter.ServerLoading, "Battleground.Random.ResetHour ({0}) can't be load. Set to 6.", Values[WorldCfg.RandomBgResetHour]); - Values[WorldCfg.RandomBgResetHour] = 6; + float minVisibilityDistance = 45.0f * (float)Values[WorldCfg.RateCreatureAggro]; + if ((float)Values[config] < minVisibilityDistance) + { + Log.outError(LogFilter.ServerLoading, $"{name} can't be less max aggro radius {minVisibilityDistance}"); + Values[config] = minVisibilityDistance; + } } - Values[WorldCfg.CalendarDeleteOldEventsHour] = GetDefaultValue("Calendar.DeleteOldEventsHour", 6); - if ((int)Values[WorldCfg.CalendarDeleteOldEventsHour] > 23) + // visibility on continents + validateVisibilityDistance(WorldCfg.MaxVisibilityDistanceContinent, "Visibility.Distance.Continents"); + + // visibility in instances + validateVisibilityDistance(WorldCfg.MaxVisibilityDistanceInstance, "Visibility.Distance.Instances"); + + // visibility in BG + validateVisibilityDistance(WorldCfg.MaxVisibilityDistanceBattleground, "Visibility.Distance.BG"); + + // Visibility in Arenas + validateVisibilityDistance(WorldCfg.MaxVisibilityDistanceArena, "Visibility.Distance.Arenas"); + + // No aggro from gray mobs + if ((int)Values[WorldCfg.NoGrayAggroAbove] > (int)Values[WorldCfg.MaxPlayerLevel]) { - Log.outError(LogFilter.Misc, $"Calendar.DeleteOldEventsHour ({Values[WorldCfg.CalendarDeleteOldEventsHour]}) can't be load. Set to 6."); - Values[WorldCfg.CalendarDeleteOldEventsHour] = 6; + Log.outError(LogFilter.ServerLoading, $"NoGrayAggro.Above ({Values[WorldCfg.NoGrayAggroAbove]}) must be in range 0..{Values[WorldCfg.MaxPlayerLevel]}. Set to {Values[WorldCfg.MaxPlayerLevel]}."); + Values[WorldCfg.NoGrayAggroAbove] = Values[WorldCfg.MaxPlayerLevel]; } - - Values[WorldCfg.GuildResetHour] = GetDefaultValue("Guild.ResetHour", 6); - if ((int)Values[WorldCfg.GuildResetHour] > 23) + if ((int)Values[WorldCfg.NoGrayAggroBelow] > (int)Values[WorldCfg.MaxPlayerLevel]) { - Log.outError(LogFilter.Server, "Guild.ResetHour ({0}) can't be load. Set to 6.", Values[WorldCfg.GuildResetHour]); - Values[WorldCfg.GuildResetHour] = 6; + Log.outError(LogFilter.ServerLoading, $"NoGrayAggro.Below ({Values[WorldCfg.NoGrayAggroBelow]}) must be in range 0..{Values[WorldCfg.MaxPlayerLevel]}. Set to {Values[WorldCfg.MaxPlayerLevel]}."); + Values[WorldCfg.NoGrayAggroBelow] = Values[WorldCfg.MaxPlayerLevel]; } - - Values[WorldCfg.DetectPosCollision] = GetDefaultValue("DetectPosCollision", true); - - Values[WorldCfg.RestrictedLfgChannel] = GetDefaultValue("Channel.RestrictedLfg", true); - Values[WorldCfg.TalentsInspecting] = GetDefaultValue("TalentsInspecting", 1); - Values[WorldCfg.ChatFakeMessagePreventing] = GetDefaultValue("ChatFakeMessagePreventing", false); - Values[WorldCfg.ChatStrictLinkCheckingSeverity] = GetDefaultValue("ChatStrictLinkChecking.Severity", 0); - Values[WorldCfg.ChatStrictLinkCheckingKick] = GetDefaultValue("ChatStrictLinkChecking.Kick", 0); - - Values[WorldCfg.CorpseDecayNormal] = GetDefaultValue("Corpse.Decay.Normal", 60); - Values[WorldCfg.CorpseDecayElite] = GetDefaultValue("Corpse.Decay.Elite", 300); - Values[WorldCfg.CorpseDecayRareelite] = GetDefaultValue("Corpse.Decay.RareElite", 300); - Values[WorldCfg.CorpseDecayObsolete] = GetDefaultValue("Corpse.Decay.Obsolete", 3600); - Values[WorldCfg.CorpseDecayRare] = GetDefaultValue("Corpse.Decay.Rare", 300); - Values[WorldCfg.CorpseDecayTrivial] = GetDefaultValue("Corpse.Decay.Trivial", 300); - Values[WorldCfg.CorpseDecayMinusMob] = GetDefaultValue("Corpse.Decay.MinusMob", 150); - - Values[WorldCfg.DeathSicknessLevel] = GetDefaultValue("Death.SicknessLevel", 11); - Values[WorldCfg.DeathCorpseReclaimDelayPvp] = GetDefaultValue("Death.CorpseReclaimDelay.PvP", true); - Values[WorldCfg.DeathCorpseReclaimDelayPve] = GetDefaultValue("Death.CorpseReclaimDelay.PvE", true); - Values[WorldCfg.DeathBonesWorld] = GetDefaultValue("Death.Bones.World", true); - Values[WorldCfg.DeathBonesBgOrArena] = GetDefaultValue("Death.Bones.BattlegroundOrArena", true); - - Values[WorldCfg.DieCommandMode] = GetDefaultValue("Die.Command.Mode", true); - - Values[WorldCfg.ThreatRadius] = GetDefaultValue("ThreatRadius", 60.0f); - - Values[WorldCfg.DeclinedNamesUsed] = GetDefaultValue("DeclinedNames", false); - Values[WorldCfg.ListenRangeSay] = GetDefaultValue("ListenRange.Say", 25.0f); - Values[WorldCfg.ListenRangeTextemote] = GetDefaultValue("ListenRange.TextEmote", 25.0f); - Values[WorldCfg.ListenRangeYell] = GetDefaultValue("ListenRange.Yell", 300.0f); - - Values[WorldCfg.BattlegroundCastDeserter] = GetDefaultValue("Battleground.CastDeserter", true); - Values[WorldCfg.BattlegroundQueueAnnouncerEnable] = GetDefaultValue("Battleground.QueueAnnouncer.Enable", false); - Values[WorldCfg.BattlegroundQueueAnnouncerPlayeronly] = GetDefaultValue("Battleground.QueueAnnouncer.PlayerOnly", false); - Values[WorldCfg.BattlegroundStoreStatisticsEnable] = GetDefaultValue("Battleground.StoreStatistics.Enable", false); - Values[WorldCfg.BattlegroundReportAfk] = GetDefaultValue("Battleground.ReportAFK", 3); - if ((int)Values[WorldCfg.BattlegroundReportAfk] < 1) + if ((int)Values[WorldCfg.NoGrayAggroAbove] > 0 && (int)Values[WorldCfg.NoGrayAggroAbove] < (int)Values[WorldCfg.NoGrayAggroBelow]) { - Log.outError(LogFilter.ServerLoading, "Battleground.ReportAFK ({0}) must be >0. Using 3 instead.", Values[WorldCfg.BattlegroundReportAfk]); - Values[WorldCfg.BattlegroundReportAfk] = 3; + Log.outError(LogFilter.ServerLoading, $"NoGrayAggro.Below ({Values[WorldCfg.NoGrayAggroBelow]}) cannot be greater than NoGrayAggro.Above ({Values[WorldCfg.NoGrayAggroAbove]}). Set to {Values[WorldCfg.NoGrayAggroAbove]}."); + Values[WorldCfg.NoGrayAggroBelow] = Values[WorldCfg.NoGrayAggroAbove]; } - if ((int)Values[WorldCfg.BattlegroundReportAfk] > 9) - { - Log.outError(LogFilter.ServerLoading, "Battleground.ReportAFK ({0}) must be <10. Using 3 instead.", Values[WorldCfg.BattlegroundReportAfk]); - Values[WorldCfg.BattlegroundReportAfk] = 3; - } - Values[WorldCfg.BattlegroundInvitationType] = GetDefaultValue("Battleground.InvitationType", 0); - Values[WorldCfg.BattlegroundPrematureFinishTimer] = GetDefaultValue("Battleground.PrematureFinishTimer", 5 * Time.Minute * Time.InMilliseconds); - Values[WorldCfg.BattlegroundPremadeGroupWaitForMatch] = GetDefaultValue("Battleground.PremadeGroupWaitForMatch", 30 * Time.Minute * Time.InMilliseconds); - Values[WorldCfg.BgXpForKill] = GetDefaultValue("Battleground.GiveXPForKills", false); - Values[WorldCfg.ArenaMaxRatingDifference] = GetDefaultValue("Arena.MaxRatingDifference", 150); - Values[WorldCfg.ArenaRatingDiscardTimer] = GetDefaultValue("Arena.RatingDiscardTimer", 10 * Time.Minute * Time.InMilliseconds); - Values[WorldCfg.ArenaRatedUpdateTimer] = GetDefaultValue("Arena.RatedUpdateTimer", 5 * Time.InMilliseconds); - Values[WorldCfg.ArenaQueueAnnouncerEnable] = GetDefaultValue("Arena.QueueAnnouncer.Enable", false); - Values[WorldCfg.ArenaSeasonId] = GetDefaultValue("Arena.ArenaSeason.ID", 32); - Values[WorldCfg.ArenaStartRating] = GetDefaultValue("Arena.ArenaStartRating", 0); - Values[WorldCfg.ArenaStartPersonalRating] = GetDefaultValue("Arena.ArenaStartPersonalRating", 1000); - Values[WorldCfg.ArenaStartMatchmakerRating] = GetDefaultValue("Arena.ArenaStartMatchmakerRating", 1500); - Values[WorldCfg.ArenaSeasonInProgress] = GetDefaultValue("Arena.ArenaSeason.InProgress", false); - Values[WorldCfg.ArenaLogExtendedInfo] = GetDefaultValue("ArenaLog.ExtendedInfo", false); - Values[WorldCfg.ArenaWinRatingModifier1] = GetDefaultValue("Arena.ArenaWinRatingModifier1", 48.0f); - Values[WorldCfg.ArenaWinRatingModifier2] = GetDefaultValue("Arena.ArenaWinRatingModifier2", 24.0f); - Values[WorldCfg.ArenaLoseRatingModifier] = GetDefaultValue("Arena.ArenaLoseRatingModifier", 24.0f); - Values[WorldCfg.ArenaMatchmakerRatingModifier] = GetDefaultValue("Arena.ArenaMatchmakerRatingModifier", 24.0f); - - if (reload) - { - Global.WorldStateMgr.SetValue(WorldStates.CurrentPvpSeasonId, GetBoolValue(WorldCfg.ArenaSeasonInProgress) ? GetIntValue(WorldCfg.ArenaSeasonId) : 0, false, null); - Global.WorldStateMgr.SetValue(WorldStates.PreviousPvpSeasonId, GetIntValue(WorldCfg.ArenaSeasonId) - (GetBoolValue(WorldCfg.ArenaSeasonInProgress) ? 1 : 0), false, null); - } - - Values[WorldCfg.OffhandCheckAtSpellUnlearn] = GetDefaultValue("OffhandCheckAtSpellUnlearn", true); - - Values[WorldCfg.CreaturePickpocketRefill] = GetDefaultValue("Creature.PickPocketRefillDelay", 10 * Time.Minute); - Values[WorldCfg.CreatureStopForPlayer] = GetDefaultValue("Creature.MovingStopTimeForPlayer", 3 * Time.Minute * Time.InMilliseconds); int clientCacheId = GetDefaultValue("ClientCacheVersion", 0); if (clientCacheId != 0) @@ -760,250 +572,35 @@ namespace Game } Log.outInfo(LogFilter.ServerLoading, "Client cache version set to: {0}", clientCacheId); - Values[WorldCfg.GuildNewsLogCount] = GetDefaultValue("Guild.NewsLogRecordsCount", GuildConst.NewsLogMaxRecords); - if ((int)Values[WorldCfg.GuildNewsLogCount] > GuildConst.NewsLogMaxRecords) - Values[WorldCfg.GuildNewsLogCount] = GuildConst.NewsLogMaxRecords; - - Values[WorldCfg.GuildEventLogCount] = GetDefaultValue("Guild.EventLogRecordsCount", GuildConst.EventLogMaxRecords); - if ((int)Values[WorldCfg.GuildEventLogCount] > GuildConst.EventLogMaxRecords) - Values[WorldCfg.GuildEventLogCount] = GuildConst.EventLogMaxRecords; - - Values[WorldCfg.GuildBankEventLogCount] = GetDefaultValue("Guild.BankEventLogRecordsCount", GuildConst.BankLogMaxRecords); - if ((int)Values[WorldCfg.GuildBankEventLogCount] > GuildConst.BankLogMaxRecords) - Values[WorldCfg.GuildBankEventLogCount] = GuildConst.BankLogMaxRecords; - - // Load the CharDelete related config options - Values[WorldCfg.ChardeleteMethod] = GetDefaultValue("CharDelete.Method", 0); - Values[WorldCfg.ChardeleteMinLevel] = GetDefaultValue("CharDelete.MinLevel", 0); - Values[WorldCfg.ChardeleteDeathKnightMinLevel] = GetDefaultValue("CharDelete.DeathKnight.MinLevel", 0); - Values[WorldCfg.ChardeleteDemonHunterMinLevel] = GetDefaultValue("CharDelete.DemonHunter.MinLevel", 0); - Values[WorldCfg.ChardeleteKeepDays] = GetDefaultValue("CharDelete.KeepDays", 30); - - // No aggro from gray mobs - Values[WorldCfg.NoGrayAggroAbove] = GetDefaultValue("NoGrayAggro.Above", 0); - Values[WorldCfg.NoGrayAggroBelow] = GetDefaultValue("NoGrayAggro.Below", 0); - if ((int)Values[WorldCfg.NoGrayAggroAbove] > (int)Values[WorldCfg.MaxPlayerLevel]) - { - Log.outError(LogFilter.ServerLoading, "NoGrayAggro.Above ({0}) must be in range 0..{1}. Set to {1}.", Values[WorldCfg.NoGrayAggroAbove], Values[WorldCfg.MaxPlayerLevel]); - Values[WorldCfg.NoGrayAggroAbove] = Values[WorldCfg.MaxPlayerLevel]; - } - if ((int)Values[WorldCfg.NoGrayAggroBelow] > (int)Values[WorldCfg.MaxPlayerLevel]) - { - Log.outError(LogFilter.ServerLoading, "NoGrayAggro.Below ({0}) must be in range 0..{1}. Set to {1}.", Values[WorldCfg.NoGrayAggroBelow], Values[WorldCfg.MaxPlayerLevel]); - Values[WorldCfg.NoGrayAggroBelow] = Values[WorldCfg.MaxPlayerLevel]; - } - if ((int)Values[WorldCfg.NoGrayAggroAbove] > 0 && (int)Values[WorldCfg.NoGrayAggroAbove] < (int)Values[WorldCfg.NoGrayAggroBelow]) - { - Log.outError(LogFilter.ServerLoading, "NoGrayAggro.Below ({0}) cannot be greater than NoGrayAggro.Above ({1}). Set to {1}.", Values[WorldCfg.NoGrayAggroBelow], Values[WorldCfg.NoGrayAggroAbove]); - Values[WorldCfg.NoGrayAggroBelow] = Values[WorldCfg.NoGrayAggroAbove]; - } - - // Respawn Settings - Values[WorldCfg.RespawnMinCheckIntervalMs] = GetDefaultValue("Respawn.MinCheckIntervalMS", 5000); - Values[WorldCfg.RespawnDynamicMode] = GetDefaultValue("Respawn.DynamicMode", 0); - if ((int)Values[WorldCfg.RespawnDynamicMode] > 1) - { - Log.outError(LogFilter.ServerLoading, $"Invalid value for Respawn.DynamicMode ({Values[WorldCfg.RespawnDynamicMode]}). Set to 0."); - Values[WorldCfg.RespawnDynamicMode] = 0; - } - Values[WorldCfg.RespawnDynamicEscortNpc] = GetDefaultValue("Respawn.DynamicEscortNPC", false); - Values[WorldCfg.RespawnGuidWarnLevel] = GetDefaultValue("Respawn.GuidWarnLevel", 12000000); - if ((int)Values[WorldCfg.RespawnGuidWarnLevel] > 16777215) - { - Log.outError(LogFilter.ServerLoading, $"Respawn.GuidWarnLevel ({Values[WorldCfg.RespawnGuidWarnLevel]}) cannot be greater than maximum GUID (16777215). Set to 12000000."); - Values[WorldCfg.RespawnGuidWarnLevel] = 12000000; - } - Values[WorldCfg.RespawnGuidAlertLevel] = GetDefaultValue("Respawn.GuidAlertLevel", 16000000); - if ((int)Values[WorldCfg.RespawnGuidAlertLevel] > 16777215) - { - Log.outError(LogFilter.ServerLoading, $"Respawn.GuidWarnLevel ({Values[WorldCfg.RespawnGuidAlertLevel]}) cannot be greater than maximum GUID (16777215). Set to 16000000."); - Values[WorldCfg.RespawnGuidAlertLevel] = 16000000; - } - Values[WorldCfg.RespawnRestartQuietTime] = GetDefaultValue("Respawn.RestartQuietTime", 3); - if ((int)Values[WorldCfg.RespawnRestartQuietTime] > 23) - { - Log.outError(LogFilter.ServerLoading, $"Respawn.RestartQuietTime ({Values[WorldCfg.RespawnRestartQuietTime]}) must be an hour, between 0 and 23. Set to 3."); - Values[WorldCfg.RespawnRestartQuietTime] = 3; - } - Values[WorldCfg.RespawnDynamicRateCreature] = GetDefaultValue("Respawn.DynamicRateCreature", 10.0f); - if ((float)Values[WorldCfg.RespawnDynamicRateCreature] < 0.0f) - { - Log.outError(LogFilter.ServerLoading, $"Respawn.DynamicRateCreature ({Values[WorldCfg.RespawnDynamicRateCreature]}) must be positive. Set to 10."); - Values[WorldCfg.RespawnDynamicRateCreature] = 10.0f; - } - Values[WorldCfg.RespawnDynamicMinimumCreature] = GetDefaultValue("Respawn.DynamicMinimumCreature", 10); - Values[WorldCfg.RespawnDynamicRateGameobject] = GetDefaultValue("Respawn.DynamicRateGameObject", 10.0f); - if ((float)Values[WorldCfg.RespawnDynamicRateGameobject] < 0.0f) - { - Log.outError(LogFilter.ServerLoading, $"Respawn.DynamicRateGameObject ({Values[WorldCfg.RespawnDynamicRateGameobject]}) must be positive. Set to 10."); - Values[WorldCfg.RespawnDynamicRateGameobject] = 10.0f; - } - Values[WorldCfg.RespawnDynamicMinimumGameObject] = GetDefaultValue("Respawn.DynamicMinimumGameObject", 10); - Values[WorldCfg.RespawnGuidWarningFrequency] = GetDefaultValue("Respawn.WarningFrequency", 1800); - - Values[WorldCfg.EnableMmaps] = GetDefaultValue("mmap.EnablePathFinding", true); - Values[WorldCfg.VmapIndoorCheck] = GetDefaultValue("vmap.EnableIndoorCheck", false); - - Values[WorldCfg.MaxWho] = GetDefaultValue("MaxWhoListReturns", 49); - Values[WorldCfg.StartAllSpells] = GetDefaultValue("PlayerStart.AllSpells", false); - if ((bool)Values[WorldCfg.StartAllSpells]) - Log.outWarn(LogFilter.ServerLoading, "PlayerStart.AllSpells Enabled - may not function as intended!"); - - Values[WorldCfg.HonorAfterDuel] = GetDefaultValue("HonorPointsAfterDuel", 0); - Values[WorldCfg.ResetDuelCooldowns] = GetDefaultValue("ResetDuelCooldowns", false); - Values[WorldCfg.ResetDuelHealthMana] = GetDefaultValue("ResetDuelHealthMana", false); - Values[WorldCfg.StartAllExplored] = GetDefaultValue("PlayerStart.MapsExplored", false); - Values[WorldCfg.StartAllRep] = GetDefaultValue("PlayerStart.AllReputation", false); - Values[WorldCfg.PvpTokenEnable] = GetDefaultValue("PvPToken.Enable", false); - Values[WorldCfg.PvpTokenMapType] = GetDefaultValue("PvPToken.MapAllowType", 4); - Values[WorldCfg.PvpTokenId] = GetDefaultValue("PvPToken.ItemID", 29434); - Values[WorldCfg.PvpTokenCount] = GetDefaultValue("PvPToken.ItemCount", 1); - if ((int)Values[WorldCfg.PvpTokenCount] < 1) - Values[WorldCfg.PvpTokenCount] = 1; - - Values[WorldCfg.NoResetTalentCost] = GetDefaultValue("NoResetTalentsCost", false); - Values[WorldCfg.ShowKickInWorld] = GetDefaultValue("ShowKickInWorld", false); - Values[WorldCfg.ShowMuteInWorld] = GetDefaultValue("ShowMuteInWorld", false); - Values[WorldCfg.ShowBanInWorld] = GetDefaultValue("ShowBanInWorld", false); - Values[WorldCfg.Numthreads] = GetDefaultValue("MapUpdate.Threads", 1); - Values[WorldCfg.MaxResultsLookupCommands] = GetDefaultValue("Command.LookupMaxResults", 0); - - // Warden - Values[WorldCfg.WardenEnabled] = GetDefaultValue("Warden.Enabled", false); - Values[WorldCfg.WardenNumInjectChecks] = GetDefaultValue("Warden.NumInjectionChecks", 9); - Values[WorldCfg.WardenNumLuaChecks] = GetDefaultValue("Warden.NumLuaSandboxChecks", 1); - Values[WorldCfg.WardenNumClientModChecks] = GetDefaultValue("Warden.NumClientModChecks", 1); - Values[WorldCfg.WardenClientBanDuration] = GetDefaultValue("Warden.BanDuration", 86400); - Values[WorldCfg.WardenClientCheckHoldoff] = GetDefaultValue("Warden.ClientCheckHoldOff", 30); - Values[WorldCfg.WardenClientFailAction] = GetDefaultValue("Warden.ClientCheckFailAction", 0); - Values[WorldCfg.WardenClientResponseDelay] = GetDefaultValue("Warden.ClientResponseDelay", 600); - - // Feature System - Values[WorldCfg.FeatureSystemBpayStoreEnabled] = GetDefaultValue("FeatureSystem.BpayStore.Enabled", false); - Values[WorldCfg.FeatureSystemCharacterUndeleteEnabled] = GetDefaultValue("FeatureSystem.CharacterUndelete.Enabled", false); - Values[WorldCfg.FeatureSystemCharacterUndeleteCooldown] = GetDefaultValue("FeatureSystem.CharacterUndelete.Cooldown", 2592000); - Values[WorldCfg.FeatureSystemWarModeEnabled] = GetDefaultValue("FeatureSystem.WarMode.Enabled", false); - - // Dungeon finder - Values[WorldCfg.LfgOptionsmask] = GetDefaultValue("DungeonFinder.OptionsMask", 1); - - // DBC_ItemAttributes - Values[WorldCfg.DbcEnforceItemAttributes] = GetDefaultValue("DBC.EnforceItemAttributes", true); - - // Accountpassword Secruity - Values[WorldCfg.AccPasschangesec] = GetDefaultValue("Account.PasswordChangeSecurity", 0); - - // Random Battleground Rewards - Values[WorldCfg.BgRewardWinnerHonorFirst] = GetDefaultValue("Battleground.RewardWinnerHonorFirst", 27000); - Values[WorldCfg.BgRewardWinnerConquestFirst] = GetDefaultValue("Battleground.RewardWinnerConquestFirst", 10000); - Values[WorldCfg.BgRewardWinnerHonorLast] = GetDefaultValue("Battleground.RewardWinnerHonorLast", 13500); - Values[WorldCfg.BgRewardWinnerConquestLast] = GetDefaultValue("Battleground.RewardWinnerConquestLast", 5000); - Values[WorldCfg.BgRewardLoserHonorFirst] = GetDefaultValue("Battleground.RewardLoserHonorFirst", 4500); - Values[WorldCfg.BgRewardLoserHonorLast] = GetDefaultValue("Battleground.RewardLoserHonorLast", 3500); - - // Max instances per hour - Values[WorldCfg.MaxInstancesPerHour] = GetDefaultValue("AccountInstancesPerHour", 5); - - // Anounce reset of instance to whole party - Values[WorldCfg.InstancesResetAnnounce] = GetDefaultValue("InstancesResetAnnounce", false); - - // Autobroadcast - //AutoBroadcast.On - Values[WorldCfg.AutoBroadcast] = GetDefaultValue("AutoBroadcast.On", false); - Values[WorldCfg.AutoBroadcastCenter] = GetDefaultValue("AutoBroadcast.Center", 0); - Values[WorldCfg.AutoBroadcastInterval] = GetDefaultValue("AutoBroadcast.Timer", 60000); - - // Guild save interval - Values[WorldCfg.GuildSaveInterval] = GetDefaultValue("Guild.SaveInterval", 15); - - // misc - Values[WorldCfg.PdumpNoPaths] = GetDefaultValue("PlayerDump.DisallowPaths", true); - Values[WorldCfg.PdumpNoOverwrite] = GetDefaultValue("PlayerDump.DisallowOverwrite", true); - - // Wintergrasp battlefield - Values[WorldCfg.WintergraspEnable] = GetDefaultValue("Wintergrasp.Enable", false); - Values[WorldCfg.WintergraspPlrMax] = GetDefaultValue("Wintergrasp.PlayerMax", 100); - Values[WorldCfg.WintergraspPlrMin] = GetDefaultValue("Wintergrasp.PlayerMin", 0); - Values[WorldCfg.WintergraspPlrMinLvl] = GetDefaultValue("Wintergrasp.PlayerMinLvl", 77); - Values[WorldCfg.WintergraspBattletime] = GetDefaultValue("Wintergrasp.BattleTimer", 30); - Values[WorldCfg.WintergraspNobattletime] = GetDefaultValue("Wintergrasp.NoBattleTimer", 150); - Values[WorldCfg.WintergraspRestartAfterCrash] = GetDefaultValue("Wintergrasp.CrashRestartTimer", 10); - - // Tol Barad battlefield - Values[WorldCfg.TolbaradEnable] = GetDefaultValue("TolBarad.Enable", true); - Values[WorldCfg.TolbaradPlrMax] = GetDefaultValue("TolBarad.PlayerMax", 100); - Values[WorldCfg.TolbaradPlrMin] = GetDefaultValue("TolBarad.PlayerMin", 0); - Values[WorldCfg.TolbaradPlrMinLvl] = GetDefaultValue("TolBarad.PlayerMinLvl", 85); - Values[WorldCfg.TolbaradBattleTime] = GetDefaultValue("TolBarad.BattleTimer", 15); - Values[WorldCfg.TolbaradBonusTime] = GetDefaultValue("TolBarad.BonusTime", 5); - Values[WorldCfg.TolbaradNoBattleTime] = GetDefaultValue("TolBarad.NoBattleTimer", 150); - Values[WorldCfg.TolbaradRestartAfterCrash] = GetDefaultValue("TolBarad.CrashRestartTimer", 10); - - // Stats limits - Values[WorldCfg.StatsLimitsEnable] = GetDefaultValue("Stats.Limits.Enable", false); - Values[WorldCfg.StatsLimitsDodge] = GetDefaultValue("Stats.Limits.Dodge", 95.0f); - Values[WorldCfg.StatsLimitsParry] = GetDefaultValue("Stats.Limits.Parry", 95.0f); - Values[WorldCfg.StatsLimitsBlock] = GetDefaultValue("Stats.Limits.Block", 95.0f); - Values[WorldCfg.StatsLimitsCrit] = GetDefaultValue("Stats.Limits.Crit", 95.0f); - - //packet spoof punishment - Values[WorldCfg.PacketSpoofPolicy] = GetDefaultValue("PacketSpoof.Policy", 1);//Kick - Values[WorldCfg.PacketSpoofBanmode] = GetDefaultValue("PacketSpoof.BanMode", (int)BanMode.Account); - if ((int)Values[WorldCfg.PacketSpoofBanmode] == 1 || (int)Values[WorldCfg.PacketSpoofBanmode] > 2) - Values[WorldCfg.PacketSpoofBanmode] = (int)BanMode.Account; - - Values[WorldCfg.PacketSpoofBanduration] = GetDefaultValue("PacketSpoof.BanDuration", 86400); - - Values[WorldCfg.IpBasedActionLogging] = GetDefaultValue("Allow.IP.Based.Action.Logging", false); - - // AHBot - Values[WorldCfg.AhbotUpdateInterval] = GetDefaultValue("AuctionHouseBot.Update.Interval", 20); - - Values[WorldCfg.CalculateCreatureZoneAreaData] = GetDefaultValue("Calculate.Creature.Zone.Area.Data", false); - Values[WorldCfg.CalculateGameobjectZoneAreaData] = GetDefaultValue("Calculate.Gameoject.Zone.Area.Data", false); - - // Black Market - Values[WorldCfg.BlackmarketEnabled] = GetDefaultValue("BlackMarket.Enabled", true); - - Values[WorldCfg.BlackmarketMaxAuctions] = GetDefaultValue("BlackMarket.MaxAuctions", 12); - Values[WorldCfg.BlackmarketUpdatePeriod] = GetDefaultValue("BlackMarket.UpdatePeriod", 24); - - // prevent character rename on character customization - Values[WorldCfg.PreventRenameCustomization] = GetDefaultValue("PreventRenameCharacterOnCustomization", false); - - // Allow 5-man parties to use raid warnings - Values[WorldCfg.ChatPartyRaidWarnings] = GetDefaultValue("PartyRaidWarnings", false); - - // Allow to cache data queries - Values[WorldCfg.CacheDataQueries] = GetDefaultValue("CacheDataQueries", true); - - // Check Invalid Position - Values[WorldCfg.CreatureCheckInvalidPostion] = GetDefaultValue("Creature.CheckInvalidPosition", false); - Values[WorldCfg.GameobjectCheckInvalidPostion] = GetDefaultValue("GameObject.CheckInvalidPosition", false); - - // Whether to use LoS from game objects - Values[WorldCfg.CheckGobjectLos] = GetDefaultValue("CheckGameObjectLoS", true); - - // FactionBalance - Values[WorldCfg.FactionBalanceLevelCheckDiff] = GetDefaultValue("Pvp.FactionBalance.LevelCheckDiff", 0); - Values[WorldCfg.CallToArms5Pct] = GetDefaultValue("Pvp.FactionBalance.Pct5", 0.6f); - Values[WorldCfg.CallToArms10Pct] = GetDefaultValue("Pvp.FactionBalance.Pct10", 0.7f); - Values[WorldCfg.CallToArms20Pct] = GetDefaultValue("Pvp.FactionBalance.Pct20", 0.8f); - - // Specifies if IP addresses can be logged to the database - Values[WorldCfg.AllowLogginIpAddressesInDatabase] = GetDefaultValue("AllowLoggingIPAddressesInDatabase", true); - - // Enable AE loot - Values[WorldCfg.EnableAeLoot] = GetDefaultValue("Loot.EnableAELoot", true); - - // Loading of Locales - Values[WorldCfg.LoadLocales] = GetDefaultValue("Load.Locales", true); - // call ScriptMgr if we're reloading the configuration if (reload) Global.ScriptMgr.OnConfigLoad(reload); } + static void StoreConfigValue(dynamic value, ConfigOptionLoadDefinition definition, bool reload) where T : struct + { + if (typeof(T) == typeof(bool)) + { + if (definition.Min.HasValue && value < definition.Min) + { + Log.outError(LogFilter.Sql, $"{definition.Name} {value} must be >= {definition.Min}. Using {definition.Min} instead."); + value = definition.Min; + } + if (definition.Max.HasValue && value > definition.Max) + { + Log.outError(LogFilter.ServerLoading, $"{definition.Name} {value} must be <= {definition.Max}. Using {definition.Max} instead."); + value = definition.Max; + } + } + if (reload && !definition.Reloadable) + { + if (value != Values[definition.Index]) + Log.outError(LogFilter.ServerLoading, $"{definition.Name} option can't be changed at worldserver.conf reload, using current value ({Values[definition.Index]})."); + return; + } + Values[definition.Index] = value; + } + public static uint GetUIntValue(WorldCfg confi) { return Convert.ToUInt32(Values.LookupByKey(confi)); @@ -1036,4 +633,14 @@ namespace Game static Dictionary Values = new(); } + + struct ConfigOptionLoadDefinition() where T : struct + { + public string Name; + public T DefaultValue; + public WorldCfg Index; + public T? Min; + public T? Max; + public bool Reloadable = true; + } } diff --git a/Source/Game/Server/WorldSession.cs b/Source/Game/Server/WorldSession.cs index b844c85b2..75230012c 100644 --- a/Source/Game/Server/WorldSession.cs +++ b/Source/Game/Server/WorldSession.cs @@ -1284,7 +1284,7 @@ namespace Game WorldSession Session; Dictionary _PacketThrottlingMap = new(); - enum Policy + public enum Policy { Log, Kick, diff --git a/Source/Game/World/WorldManager.cs b/Source/Game/World/WorldManager.cs index 8ea37b58f..cd474df2e 100644 --- a/Source/Game/World/WorldManager.cs +++ b/Source/Game/World/WorldManager.cs @@ -104,6 +104,10 @@ namespace Game return m_motd; } + public void SetNewCharString(string str) { m_newCharString = str; } + + public string GetNewCharString() { return m_newCharString; } + public void TriggerGuidWarning() { // Lock this only to prevent multiple maps triggering at the same time @@ -938,9 +942,6 @@ namespace Game Log.outInfo(LogFilter.ServerLoading, "Loading Persistend World Variables..."); // must be loaded before Battleground, outdoor PvP and conditions LoadPersistentWorldVariables(); - Global.WorldStateMgr.SetValue(WorldStates.CurrentPvpSeasonId, WorldConfig.GetBoolValue(WorldCfg.ArenaSeasonInProgress) ? WorldConfig.GetIntValue(WorldCfg.ArenaSeasonId) : 0, false, null); - Global.WorldStateMgr.SetValue(WorldStates.PreviousPvpSeasonId, WorldConfig.GetIntValue(WorldCfg.ArenaSeasonId) - (WorldConfig.GetBoolValue(WorldCfg.ArenaSeasonInProgress) ? 1 : 0), false, null); - Global.ObjectMgr.LoadPhases(); Log.outInfo(LogFilter.ServerLoading, "Loading Conditions..."); @@ -1204,69 +1205,20 @@ namespace Game m_timers[WorldTimers.AutoBroadcast].SetInterval(WorldConfig.GetIntValue(WorldCfg.AutoBroadcastInterval)); m_timers[WorldTimers.AutoBroadcast].Reset(); + + Global.WorldStateMgr.SetValue(WorldStates.CurrentPvpSeasonId, WorldConfig.GetBoolValue(WorldCfg.ArenaSeasonInProgress) ? WorldConfig.GetIntValue(WorldCfg.ArenaSeasonId) : 0, false, null); + Global.WorldStateMgr.SetValue(WorldStates.PreviousPvpSeasonId, WorldConfig.GetIntValue(WorldCfg.ArenaSeasonId) - (WorldConfig.GetBoolValue(WorldCfg.ArenaSeasonInProgress) ? 1 : 0), false, null); + + // call ScriptMgr if we're reloading the configuration + Global.ScriptMgr.OnConfigLoad(reload); } + // Get string for new logins (newly created characters) + SetNewCharString(ConfigMgr.GetDefaultValue("PlayerStart.String", "")); + for (byte i = 0; i < (int)UnitMoveType.Max; ++i) SharedConst.playerBaseMoveSpeed[i] = SharedConst.baseMoveSpeed[i] * WorldConfig.GetFloatValue(WorldCfg.RateMovespeed); - var rateCreatureAggro = WorldConfig.GetFloatValue(WorldCfg.RateCreatureAggro); - //visibility on continents - m_MaxVisibleDistanceOnContinents = ConfigMgr.GetDefaultValue("Visibility.Distance.Continents", SharedConst.DefaultVisibilityDistance); - if (m_MaxVisibleDistanceOnContinents < 45 * rateCreatureAggro) - { - Log.outError(LogFilter.ServerLoading, "Visibility.Distance.Continents can't be less max aggro radius {0}", 45 * rateCreatureAggro); - m_MaxVisibleDistanceOnContinents = 45 * rateCreatureAggro; - } - else if (m_MaxVisibleDistanceOnContinents > SharedConst.MaxVisibilityDistance) - { - Log.outError(LogFilter.ServerLoading, "Visibility.Distance.Continents can't be greater {0}", SharedConst.MaxVisibilityDistance); - m_MaxVisibleDistanceOnContinents = SharedConst.MaxVisibilityDistance; - } - - //visibility in instances - m_MaxVisibleDistanceInInstances = ConfigMgr.GetDefaultValue("Visibility.Distance.Instances", SharedConst.DefaultVisibilityInstance); - if (m_MaxVisibleDistanceInInstances < 45 * rateCreatureAggro) - { - Log.outError(LogFilter.ServerLoading, "Visibility.Distance.Instances can't be less max aggro radius {0}", 45 * rateCreatureAggro); - m_MaxVisibleDistanceInInstances = 45 * rateCreatureAggro; - } - else if (m_MaxVisibleDistanceInInstances > SharedConst.MaxVisibilityDistance) - { - Log.outError(LogFilter.ServerLoading, "Visibility.Distance.Instances can't be greater {0}", SharedConst.MaxVisibilityDistance); - m_MaxVisibleDistanceInInstances = SharedConst.MaxVisibilityDistance; - } - - //visibility in BG - m_MaxVisibleDistanceInBG = ConfigMgr.GetDefaultValue("Visibility.Distance.BG", SharedConst.DefaultVisibilityBGAreans); - if (m_MaxVisibleDistanceInBG < 45 * rateCreatureAggro) - { - Log.outError(LogFilter.ServerLoading, $"Visibility.Distance.BG can't be less max aggro radius {45 * rateCreatureAggro}"); - m_MaxVisibleDistanceInBG = 45 * rateCreatureAggro; - } - else if (m_MaxVisibleDistanceInBG > SharedConst.MaxVisibilityDistance) - { - Log.outError(LogFilter.ServerLoading, $"Visibility.Distance.BG can't be greater {SharedConst.MaxVisibilityDistance}"); - m_MaxVisibleDistanceInBG = SharedConst.MaxVisibilityDistance; - } - - // Visibility in Arenas - m_MaxVisibleDistanceInArenas = ConfigMgr.GetDefaultValue("Visibility.Distance.Arenas", SharedConst.DefaultVisibilityBGAreans); - if (m_MaxVisibleDistanceInArenas < 45 * rateCreatureAggro) - { - Log.outError(LogFilter.ServerLoading, $"Visibility.Distance.Arenas can't be less max aggro radius {45 * rateCreatureAggro}"); - m_MaxVisibleDistanceInArenas = 45 * rateCreatureAggro; - } - else if (m_MaxVisibleDistanceInArenas > SharedConst.MaxVisibilityDistance) - { - Log.outError(LogFilter.ServerLoading, $"Visibility.Distance.Arenas can't be greater {SharedConst.MaxVisibilityDistance}"); - m_MaxVisibleDistanceInArenas = SharedConst.MaxVisibilityDistance; - } - - m_visibility_notify_periodOnContinents = ConfigMgr.GetDefaultValue("Visibility.Notify.Period.OnContinents", SharedConst.DefaultVisibilityNotifyPeriod); - m_visibility_notify_periodInInstances = ConfigMgr.GetDefaultValue("Visibility.Notify.Period.InInstances", SharedConst.DefaultVisibilityNotifyPeriod); - m_visibility_notify_periodInBG = ConfigMgr.GetDefaultValue("Visibility.Notify.Period.InBG", SharedConst.DefaultVisibilityNotifyPeriod); - m_visibility_notify_periodInArenas = ConfigMgr.GetDefaultValue("Visibility.Notify.Period.InArenas", SharedConst.DefaultVisibilityNotifyPeriod); - _guidWarningMsg = WorldConfig.GetDefaultValue("Respawn.WarningMessage", "There will be an unscheduled server restart at 03:00. The server will be available again shortly after."); _alertRestartReason = WorldConfig.GetDefaultValue("Respawn.AlertRestartReason", "Urgent Maintenance"); @@ -2535,16 +2487,6 @@ namespace Game return Global.RealmMgr.GetCurrentRealmId().GetAddress(); } - public float GetMaxVisibleDistanceOnContinents() { return m_MaxVisibleDistanceOnContinents; } - public float GetMaxVisibleDistanceInInstances() { return m_MaxVisibleDistanceInInstances; } - public float GetMaxVisibleDistanceInBG() { return m_MaxVisibleDistanceInBG; } - public float GetMaxVisibleDistanceInArenas() { return m_MaxVisibleDistanceInArenas; } - - public int GetVisibilityNotifyPeriodOnContinents() { return m_visibility_notify_periodOnContinents; } - public int GetVisibilityNotifyPeriodInInstances() { return m_visibility_notify_periodInInstances; } - public int GetVisibilityNotifyPeriodInBG() { return m_visibility_notify_periodInBG; } - public int GetVisibilityNotifyPeriodInArenas() { return m_visibility_notify_periodInArenas; } - public Locale GetAvailableDbcLocale(Locale locale) { if (m_availableDbcLocaleMask[(int)locale]) @@ -2576,16 +2518,6 @@ namespace Game CleaningFlags m_CleaningFlags; - float m_MaxVisibleDistanceOnContinents = SharedConst.DefaultVisibilityDistance; - float m_MaxVisibleDistanceInInstances = SharedConst.DefaultVisibilityInstance; - float m_MaxVisibleDistanceInBG = SharedConst.DefaultVisibilityBGAreans; - float m_MaxVisibleDistanceInArenas = SharedConst.DefaultVisibilityBGAreans; - - int m_visibility_notify_periodOnContinents = SharedConst.DefaultVisibilityNotifyPeriod; - int m_visibility_notify_periodInInstances = SharedConst.DefaultVisibilityNotifyPeriod; - int m_visibility_notify_periodInBG = SharedConst.DefaultVisibilityNotifyPeriod; - int m_visibility_notify_periodInArenas = SharedConst.DefaultVisibilityNotifyPeriod; - bool m_isClosed; Dictionary m_timers = new(); @@ -2607,6 +2539,7 @@ namespace Game Locale m_defaultDbcLocale; // from config for one from loaded DBC locales BitSet m_availableDbcLocaleMask; // by loaded DBC List m_motd = new(); + string m_newCharString; // scheduled reset times long m_NextDailyQuestReset;