/// <summary> /// Initializes the most important things that is needed for some code /// </summary> /// <param name="regionsData">The loaded regions data</param> public static bool EarlyInit(out RegionData[] regionsData) { log.Debug(GC.GetTotalMemory(true) / 1024 / 1024 + "MB - World Manager: EarlyInit"); lock (m_regions.SyncRoot) m_regions.Clear(); lock (m_zones.SyncRoot) m_zones.Clear(); //If the files are missing this method //creates the default values CheckRegionAndZoneConfigs(); XMLConfigFile zoneCfg = XMLConfigFile.ParseXMLFile(new FileInfo(GameServer.Instance.Configuration.ZoneConfigFile)); ; XMLConfigFile regionCfg = XMLConfigFile.ParseXMLFile(new FileInfo(GameServer.Instance.Configuration.RegionConfigFile)); if (log.IsDebugEnabled) { log.Debug(string.Format("{0} blocks read from {1}", regionCfg.Children.Count, GameServer.Instance.Configuration.RegionConfigFile)); log.Debug(string.Format("{0} blocks read from {1}", zoneCfg.Children.Count, GameServer.Instance.Configuration.ZoneConfigFile)); } #region Instances //Dinberg: We now need to save regionData, indexed by regionID, for instances. //The information generated here is oddly ordered by number of mbos in the region, //so I'm contriving to generate this list myself. m_regionData = new Hashtable(); //We also will need to store zones, because we need at least one zone per region - hence //we will create zones inside our instances or the player gets banned by anti-telehack scripts. m_zonesData = new Dictionary<ushort, List<ZoneData>>(); #endregion log.Info(LoadTeleports()); // sort the regions by mob count log.Debug("loading mobs from DB..."); var mobList = new List<Mob>(); if (ServerProperties.Properties.DEBUG_LOAD_REGIONS != string.Empty) { foreach (string loadRegion in ServerProperties.Properties.DEBUG_LOAD_REGIONS.SplitCSV(true)) { mobList.AddRange(GameServer.Database.SelectObjects<Mob>("region = " + loadRegion)); } } else { mobList.AddRange(GameServer.Database.SelectAllObjects<Mob>()); } var mobsByRegionId = new Dictionary<ushort, List<Mob>>(512); foreach (Mob mob in mobList) { List<Mob> list; if (!mobsByRegionId.TryGetValue(mob.Region, out list)) { list = new List<Mob>(1024); mobsByRegionId.Add(mob.Region, list); } list.Add(mob); } if (GameServer.Database.GetObjectCount<DBRegions>() < regionCfg.Children.Count) { foreach (var entry in regionCfg.Children) { ConfigElement config = entry.Value; DBRegions dbRegion = GameServer.Database.FindObjectByKey<DBRegions>(config[ENTRY_REG_ID].GetInt()); if (dbRegion == null) { dbRegion = new DBRegions(); dbRegion.RegionID = (ushort)config[ENTRY_REG_ID].GetInt(); dbRegion.Name = entry.Key; dbRegion.Description = config[ENTRY_REG_DESC].GetString(); dbRegion.IP = config[ENTRY_REG_IP].GetString(); dbRegion.Port = (ushort)config[ENTRY_REG_PORT].GetInt(); dbRegion.Expansion = config[ENTRY_REG_EXPANSION].GetInt(); dbRegion.HousingEnabled = config[ENTRY_REG_HOUSING_ENABLE].GetBoolean(false); dbRegion.DivingEnabled = config[ENTRY_REG_DIVING_ENABLE].GetBoolean(false); dbRegion.WaterLevel = config[ENTRY_REG_WATER_LEVEL].GetInt(); log.Debug(string.Format("Region {0} was not found in the database. Added!", dbRegion.RegionID)); GameServer.Database.AddObject(dbRegion); } } } bool hasFrontierRegion = false; var regions = new List<RegionData>(512); foreach (DBRegions dbRegion in GameServer.Database.SelectAllObjects<DBRegions>()) { RegionData data = new RegionData(); data.Id = dbRegion.RegionID; data.Name = dbRegion.Name; data.Description = dbRegion.Description; data.Ip = dbRegion.IP; data.Port = dbRegion.Port; data.Expansion = dbRegion.Expansion; data.HousingEnabled = dbRegion.HousingEnabled; data.DivingEnabled = dbRegion.DivingEnabled; data.WaterLevel = dbRegion.WaterLevel; data.ClassType = dbRegion.ClassType; data.IsFrontier = dbRegion.IsFrontier; if (data.IsFrontier) { hasFrontierRegion = true; } List<Mob> mobs; if (!mobsByRegionId.TryGetValue(data.Id, out mobs)) data.Mobs = new Mob[0]; else data.Mobs = mobs.ToArray(); regions.Add(data); //Dinberg - save the data by ID. if (m_regionData.ContainsKey(data.Id)) log.Error("Duplicate key in region table - " + data.Id + ", EarlyInit in WorldMgr failed."); else m_regionData.Add(data.Id, data); } regions.Sort(); log.Debug(GC.GetTotalMemory(true) / 1024 / 1024 + "MB - Region Data Loaded"); int cpuCount = GameServer.Instance.Configuration.CpuCount; if (cpuCount < 1) cpuCount = 1; GameTimer.TimeManager[] timers = new GameTimer.TimeManager[cpuCount]; for (int i = 0; i < cpuCount; i++) { timers[i] = new GameTimer.TimeManager("RegionTime" + (i + 1).ToString()); } m_regionTimeManagers = timers; for (int i = 0; i < regions.Count; i++) { RegionData region = (RegionData)regions[i]; RegisterRegion(timers[FastMath.Abs(i % (cpuCount * 2) - cpuCount) % cpuCount], region); } log.Debug(GC.GetTotalMemory(true) / 1024 / 1024 + "MB - " + m_regions.Count + " Regions Loaded"); // if we don't have at least one frontier region add the default if (hasFrontierRegion == false) { if (m_regions.ContainsKey((ushort)Keeps.DefaultKeepManager.DEFAULT_FRONTIERS_REGION)) { ((Region)m_regions[(ushort)Keeps.DefaultKeepManager.DEFAULT_FRONTIERS_REGION]).IsFrontier = true; } else { log.ErrorFormat("Can't find default Frontier region {0}!", Keeps.DefaultKeepManager.DEFAULT_FRONTIERS_REGION); } } //stephenxpimentel - changed to SQL. if (GameServer.Database.GetObjectCount<Zones>() < zoneCfg.Children.Count) { foreach (var entry in zoneCfg.Children) { //string name = (string) entry.Key; ConfigElement config = entry.Value; Zones checkZone = GameServer.Database.FindObjectByKey<Zones>(config[ENTRY_ZONE_ZONEID].GetInt()); if (checkZone == null) { Zones dbZone = new Zones(); dbZone.Height = config[ENTRY_ZONE_HEIGHT].GetInt(0); dbZone.Width = config[ENTRY_ZONE_WIDTH].GetInt(0); dbZone.OffsetY = config[ENTRY_ZONE_OFFY].GetInt(0); dbZone.OffsetX = config[ENTRY_ZONE_OFFX].GetInt(0); dbZone.Name = config[ENTRY_ZONE_DESC].GetString(""); dbZone.RegionID = (ushort)config[ENTRY_ZONE_REGIONID].GetInt(0); dbZone.ZoneID = config[ENTRY_ZONE_ZONEID].GetInt(0); dbZone.WaterLevel = config[ENTRY_ZONE_WATER_LEVEL].GetInt(0); dbZone.DivingFlag = 0; if (config[ENTRY_ZONE_LAVA].GetInt(0) != 0) { dbZone.IsLava = true; } else { dbZone.IsLava = false; } log.Debug(string.Format("Zone {0} was not found in the database. Added!", dbZone.ZoneID)); GameServer.Database.AddObject(dbZone); } } } foreach (Zones dbZone in GameServer.Database.SelectAllObjects<Zones>()) { ZoneData zoneData = new ZoneData(); zoneData.Height = (byte)dbZone.Height; zoneData.Width = (byte)dbZone.Width; zoneData.OffY = (byte)dbZone.OffsetY; zoneData.OffX = (byte)dbZone.OffsetX; zoneData.Description = dbZone.Name; zoneData.RegionID = dbZone.RegionID; zoneData.ZoneID = (ushort)dbZone.ZoneID; zoneData.WaterLevel = dbZone.WaterLevel; zoneData.DivingFlag = dbZone.DivingFlag; zoneData.IsLava = dbZone.IsLava; RegisterZone(zoneData, zoneData.ZoneID, zoneData.RegionID, zoneData.Description, dbZone.Experience, dbZone.Realmpoints, dbZone.Bountypoints, dbZone.Coin, dbZone.Realm); //Save the zonedata. if (!m_zonesData.ContainsKey(zoneData.RegionID)) m_zonesData.Add(zoneData.RegionID, new List<ZoneData>()); m_zonesData[zoneData.RegionID].Add(zoneData); } log.Debug(GC.GetTotalMemory(true) / 1024 / 1024 + "MB - Zones Loaded for All Regions"); regionsData = regions.ToArray(); return true; }
/// <summary> /// Registers a Zone into a Region /// </summary> public static void RegisterZone(ZoneData zoneData, ushort zoneID, ushort regionID, string zoneName, int xpBonus, int rpBonus, int bpBonus, int coinBonus, byte realm) { Region region = GetRegion(regionID); if (region == null) { if (log.IsWarnEnabled) { log.Warn("Could not find Region " + regionID + " for Zone " + zoneData.Description); } return; } // Making an assumption that a zone waterlevel of 0 means it is not set and we should use the regions waterlevel - Tolakram if (zoneData.WaterLevel == 0) { zoneData.WaterLevel = region.WaterLevel; } bool isDivingEnabled = region.IsRegionDivingEnabled; if (zoneData.DivingFlag == 1) isDivingEnabled = true; else if (zoneData.DivingFlag == 2) isDivingEnabled = false; Zone zone = new Zone(region, zoneID, zoneName, zoneData.OffX * 8192, zoneData.OffY * 8192, zoneData.Width * 8192, zoneData.Height * 8192, zoneData.ZoneID, isDivingEnabled, zoneData.WaterLevel, zoneData.IsLava, xpBonus, rpBonus, bpBonus, coinBonus, realm); //Dinberg:Instances //ZoneID will always be constant as last parameter, because ZoneSkinID will effectively be a bluff, to remember //the original region that spawned this one! /*reg, zoneID, desc, offx * 8192, offy * 8192, width * 8192, height * 8192);*/ lock (region.Zones.SyncRoot) { region.Zones.Add(zone); } lock (m_zones.SyncRoot) { m_zones.Add(zoneID, zone); } log.Info("Added a zone, " + zoneData.Description + ", to region " + region.Name); }