/// <summary> /// Creates an instance object. This shouldn't be used directly - Please use WorldMgr.CreateInstance /// to create an instance. /// </summary> public BaseInstance(ushort ID, GameTimer.TimeManager time, RegionData data) :base(time, data) { m_regionID = ID; m_skinID = data.Id; //Notify we've created an instance. log.Warn("An instance is created! " + Name + ", RegionID: " + ID + ", SkinID: " + Skin); }
[TestFixtureSetUp] public override void Init() { base.Init(); RegionData data = new RegionData(); data.Id = 5555; data.Name = "reg data1"; data.Description = "reg test1"; data.Mobs = new Mob[0]; m_reg = WorldMgr.RegisterRegion(new GameTimer.TimeManager("RegTest1"), data); //WorldMgr.RegisterZone(5555, 5555, "test zone1", 0, 0, 16, 16); m_reg.StartRegionMgr(); }
/// <summary> /// Creates an instance object. This shouldn't be used directly - Please use WorldMgr.CreateInstance /// to create an instance. /// </summary> public Instance(ushort ID, GameTimer.TimeManager time, RegionData data) :base(ID, time, data) { }
/// <summary> /// AdventureWingInstance Constructor /// </summary> public AdventureWingInstance(ushort ID, GameTimer.TimeManager time, RegionData dat) : base(ID, time, dat) { }
/// <summary> /// Factory method to create regions. Will create a region of data.ClassType, or default to Region if /// an error occurs or ClassType is not specified /// </summary> /// <param name="time"></param> /// <param name="data"></param> /// <returns></returns> public static Region Create(GameTimer.TimeManager time, RegionData data) { try { Type t = typeof(Region); if (string.IsNullOrEmpty(data.ClassType) == false) { t = Type.GetType(data.ClassType); if (t == null) { t = ScriptMgr.GetType(data.ClassType); } if (t != null) { ConstructorInfo info = t.GetConstructor(new Type[] { typeof(GameTimer.TimeManager), typeof(RegionData) }); Region r = (Region)info.Invoke(new object[] { time, data }); if (r != null) { // Success with requested classtype log.InfoFormat("Created Region {0} using ClassType '{1}'", r.ID, data.ClassType); return r; } log.ErrorFormat("Failed to Invoke Region {0} using ClassType '{1}'", r.ID, data.ClassType); } else { log.ErrorFormat("Failed to find ClassType '{0}' for region {1}!", data.ClassType, data.Id); } } } catch (Exception ex) { log.ErrorFormat("Failed to start region {0} with requested classtype: {1}. Exception: {2}!", data.Id, data.ClassType, ex.Message); } // Create region using default type return new Region(time, data); }
/// <summary> /// Constructs a new empty Region /// </summary> /// <param name="time">The time manager for this region</param> /// <param name="data">The region data</param> public Region(GameTimer.TimeManager time, RegionData data) { m_regionData = data; m_objects = new GameObject[0]; m_objectsInRegion = 0; m_nextObjectSlot = 0; m_objectsAllocatedSlots = new uint[0]; m_graveStones = new Hashtable(); m_zones = new ReaderWriterList<Zone>(1); m_ZoneAreas = new ushort[64][]; m_ZoneAreasCount = new ushort[64]; for (int i = 0; i < 64; i++) { m_ZoneAreas[i] = new ushort[AbstractArea.MAX_AREAS_PER_ZONE]; } m_Areas = new Dictionary<ushort, IArea>(); m_timeManager = time; List<string> list = null; if (ServerProperties.Properties.DEBUG_LOAD_REGIONS != string.Empty) list = ServerProperties.Properties.DEBUG_LOAD_REGIONS.SplitCSV(true); if (list != null && list.Count > 0) { m_loadObjects = false; foreach (string region in list) { if (region.ToString() == ID.ToString()) { m_loadObjects = true; break; } } } list = ServerProperties.Properties.DISABLED_REGIONS.SplitCSV(true); foreach (string region in list) { if (region.ToString() == ID.ToString()) { m_isDisabled = true; break; } } list = ServerProperties.Properties.DISABLED_EXPANSIONS.SplitCSV(true); foreach (string expansion in list) { if (expansion.ToString() == m_regionData.Expansion.ToString()) { m_isDisabled = true; break; } } }
/// <summary> /// RegionInstance Constructor /// </summary> /// <param name="player"></param> public RegionInstance(ushort ID, GameTimer.TimeManager time, RegionData dat) : base(ID, time, dat) { this.m_players_in = new List<GamePlayer>(); this.DestroyWhenEmpty = false; }
/// <summary> /// Initializes the WorldMgr. This function must be called /// before the WorldMgr can be used! /// </summary> public static bool Init(RegionData[] regionsData) { try { m_clients = new GameClient[GameServer.Instance.Configuration.MaxClientCount]; LootMgr.Init(); long mobs = 0; long merchants = 0; long items = 0; long bindpoints = 0; foreach (RegionData data in regionsData) { Region reg = (Region)m_regions[data.Id]; reg.LoadFromDatabase(data.Mobs, ref mobs, ref merchants, ref items, ref bindpoints); } if (log.IsInfoEnabled) { log.Info("Total Mobs: " + mobs); log.Info("Total Merchants: " + merchants); log.Info("Total Items: " + items); log.Info("Total Bind Points: " + bindpoints); } m_WorldUpdateThread = new Thread(new ThreadStart(WorldUpdateThreadStart)); m_WorldUpdateThread.Priority = ThreadPriority.AboveNormal; m_WorldUpdateThread.Name = "NpcUpdate"; m_WorldUpdateThread.IsBackground = true; m_WorldUpdateThread.Start(); m_dayIncrement = Math.Max(0, Math.Min(1000, ServerProperties.Properties.WORLD_DAY_INCREMENT)); // increments > 1000 do not render smoothly on clients m_dayStartTick = Environment.TickCount - (int)(DAY / Math.Max(1, m_dayIncrement) / 2); // set start time to 12pm m_dayResetTimer = new Timer(new TimerCallback(DayReset), null, DAY / Math.Max(1, m_dayIncrement) / 2, DAY / Math.Max(1, m_dayIncrement)); m_pingCheckTimer = new Timer(new TimerCallback(PingCheck), null, 10 * 1000, 0); // every 10s a check m_relocationThread = new Thread(new ThreadStart(RelocateRegions)); m_relocationThread.Name = "RelocateReg"; m_relocationThread.IsBackground = true; m_relocationThread.Start(); } catch (Exception e) { if (log.IsErrorEnabled) log.Error("Init", e); return false; } return true; }
/// <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> /// Creates and adds a new region to the WorldMgr /// </summary> /// <param name="time">Time manager for the region</param> /// <param name="data">The region data</param> /// <returns>Registered region</returns> public static Region RegisterRegion(GameTimer.TimeManager time, RegionData data) { Region region = Region.Create(time, data); lock (m_regions.SyncRoot) { m_regions.Add(data.Id, region); } return region; }
/// <summary> /// Creates an instance object. This shouldn't be used directly - Please use WorldMgr.CreateInstance /// to create an instance. /// </summary> public Instance(ushort ID, GameTimer.TimeManager time, RegionData data) : base(ID, time, data) { }