/// <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);
        }
Exemple #2
0
			/// <summary>
			/// Removes the timer from the table.
			/// </summary>
			/// <param name="timer">The timer to remove</param>
			internal void RemoveTimer(GameTimer timer)
			{
				lock (m_buckets)
				{
					RemoveTimerUnsafe(timer);
				}
			}
Exemple #3
0
			/// <summary>
			/// Inserts the timer into the table.
			/// </summary>
			/// <param name="t">The timer to insert</param>
			/// <param name="offsetTick">The offset from current tick. min value=1, max value&lt;MaxInterval</param>
			internal void InsertTimer(GameTimer t, int offsetTick)
			{
				if (offsetTick > MaxInterval || offsetTick < 1)
					throw new ArgumentOutOfRangeException("offsetTick", offsetTick.ToString(), "Offset must be in range from 1 to "+MaxInterval);

				GameTimer timer = t;

				lock (m_buckets)
				{
					long timerTick = timer.m_tick;
					long targetTick = m_tick + offsetTick;
					
					if (timerTick == m_tick || (timerTick & TIMER_RESCHEDULED) != 0)
					{
						timer.m_targetTime = (int) (CurrentTime + offsetTick);
						timer.m_tick = targetTick | TIMER_RESCHEDULED;
						return;
					}

					if ((timerTick & TIMER_DISABLED) == 0)
					{
						RemoveTimerUnsafe(timer);
					}

					timer.m_targetTime = (int) (CurrentTime + offsetTick);
					m_activeTimers++;

					if (offsetTick <= CACHE_MASK + 1)
					{
						timer.m_tick = targetTick & TICK_MASK;
						targetTick &= CACHE_MASK;
						CacheBucket bucket = m_cachedBucket[targetTick];
						GameTimer prev = bucket.LastTimer;
						if (prev != null)
						{
							prev.m_nextTimer = timer;
							m_cachedBucket[targetTick].LastTimer = timer;
						}
						else
						{
							bucket.FirstTimer = timer;
							bucket.LastTimer = timer;
							m_cachedBucket[targetTick] = bucket;
						}
					}
					else
					{
						if ((targetTick & TICK_MASK) > (m_tick & ~BUCKET_MASK) + BUCKET_MASK)
							targetTick += TICK_MASK + 1; // extra pass if the timer is ahead of current tick
						timer.m_tick = targetTick;
                        targetTick = (targetTick >> BUCKET_BITS) & TABLE_MASK;
						GameTimer next = m_buckets[targetTick];
						m_buckets[targetTick] = timer;
						if (next != null)
						{
							timer.m_nextTimer = next;
						}
					}
				}
			}
Exemple #4
0
			/// <summary>
			/// Checks one timers chain
			/// </summary>
			/// <param name="t"></param>
			/// <param name="tableName"></param>
			/// <returns></returns>
			private static int CheckChain(GameTimer t, string tableName)
			{
				int res = 0;
				while (t != null)
				{
					if (res++ > 500000)
					{
						log.WarnFormat("possible circular chain (500000 timers in one bucket)");
						break;
					}
					t = t.m_nextTimer;
				}
				return res;
			}
Exemple #5
0
 /// <summary>
 /// Call this function to close the door
 /// </summary>
 public virtual void Close(GameLiving closer = null)
 {
     if (!m_openDead)
         this.State = eDoorState.Closed;
     m_closeDoorAction = null;
 }
Exemple #6
0
        /// <summary>
        /// Call this function to open the door
        /// </summary>
        public virtual void Open(GameLiving opener = null)
        {
            if (Locked == 0)
                this.State = eDoorState.Open;

            if (HealthPercent > 40 || !m_openDead)
            {
                lock (m_LockObject)
                {
                    if (m_closeDoorAction == null)
                    {
                        m_closeDoorAction = new CloseDoorAction(this);
                    }
                    m_closeDoorAction.Start(CLOSE_DOOR_TIME);
                }
            }
        }
 /// <summary>
 /// Check if this player can be updated
 /// </summary>
 /// <param name="lastUpdate"></param>
 /// <returns></returns>
 private static bool PlayerNeedUpdate(long lastUpdate)
 {
     return((GameTimer.GetTickCount() - lastUpdate) >= GetPlayerWorldUpdateInterval);
 }
Exemple #8
0
 /// <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;
 }
Exemple #9
0
        /// <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;
                }
            }
        }
Exemple #10
0
		/// <summary>
		/// Call this function to close the door
		/// </summary>
		public void Close()
		{
			if (!m_openDead)
				this.State = eDoorState.Closed;
			m_closeDoorAction = null;
		}
Exemple #11
0
		/// <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;
		}
Exemple #12
0
        /// <summary>
        /// Try to Send Tooltip to Client, return false if cache hit.
        /// Return true and register cache before you can send tooltip !
        /// </summary>
        /// <param name="type"></param>
        /// <param name="id"></param>
        /// <returns></returns>
        public bool CanSendTooltip(int type, int id)
        {
            m_tooltipRequestTimes.TryAdd(type, new ConcurrentDictionary <int, long>());

            // Queries cleanup
            foreach (Tuple <int, int> keys in m_tooltipRequestTimes.SelectMany(e => e.Value.Where(it => it.Value < GameTimer.GetTickCount()).Select(el => new Tuple <int, int>(e.Key, el.Key))))
            {
                long dummy;
                m_tooltipRequestTimes[keys.Item1].TryRemove(keys.Item2, out dummy);
            }

            // Query hit ?
            if (m_tooltipRequestTimes[type].ContainsKey(id))
            {
                return(false);
            }

            // Query register
            m_tooltipRequestTimes[type].TryAdd(id, GameTimer.GetTickCount() + 3600000);
            return(true);
        }
        /// <summary>
        /// This thread updates the NPCs and objects around the player at very short
        /// intervalls! But since the update is very quick the thread will
        /// sleep most of the time!
        /// </summary>
        public static void WorldUpdateThreadStart()
        {
            // Tasks Collection of running Player updates, with starting time.
            var clientsUpdateTasks = new Dictionary <GameClient, Tuple <long, Task, Region> >();

            bool running = true;

            if (log.IsInfoEnabled)
            {
                log.InfoFormat("World Update Thread Starting - ThreadId = {0}", Thread.CurrentThread.ManagedThreadId);
            }

            while (running)
            {
                try
                {
                    // Start Time of the loop
                    long begin = GameTimer.GetTickCount();

                    // Get All Clients
                    var clients = WorldMgr.GetAllClients();

                    // Clean Tasks Dict on Client Exiting.
                    foreach (GameClient cli in clientsUpdateTasks.Keys.ToArray())
                    {
                        if (cli == null)
                        {
                            continue;
                        }

                        GamePlayer player = cli.Player;

                        bool notActive    = cli.ClientState != GameClient.eClientState.Playing || player == null || player.ObjectState != GameObject.eObjectState.Active;
                        bool notConnected = !clients.Contains(cli);

                        if (notConnected || (notActive && IsTaskCompleted(cli, clientsUpdateTasks)))
                        {
                            clientsUpdateTasks.Remove(cli);
                            cli.GameObjectUpdateArray.Clear();
                            cli.HouseUpdateArray.Clear();
                        }
                    }

                    // Browse all clients to check if they can be updated.
                    for (int cl = 0; cl < clients.Count; cl++)
                    {
                        GameClient client = clients[cl];

                        // Check that client is healthy
                        if (client == null)
                        {
                            continue;
                        }

                        GamePlayer player = client.Player;

                        if (client.ClientState == GameClient.eClientState.Playing && player == null)
                        {
                            if (log.IsErrorEnabled)
                            {
                                log.Error("account has no active player but is playing, disconnecting! => " + client.Account.Name);
                            }

                            // Disconnect buggy Client
                            GameServer.Instance.Disconnect(client);
                            continue;
                        }

                        // Check that player is active.
                        if (client.ClientState != GameClient.eClientState.Playing || player == null || player.ObjectState != GameObject.eObjectState.Active)
                        {
                            continue;
                        }

                        // Start Update Task
                        StartPlayerUpdateTask(client, clientsUpdateTasks, begin);
                    }

                    long took = GameTimer.GetTickCount() - begin;

                    if (took >= 500)
                    {
                        if (log.IsWarnEnabled)
                        {
                            log.WarnFormat("World Update Thread (NPC/Object update) took {0} ms", took);
                        }
                    }

                    // relaunch update thread every 100 ms to check if any player need updates.
                    Thread.Sleep((int)Math.Max(1, 100 - took));
                }
                catch (ThreadInterruptedException)
                {
                    if (log.IsInfoEnabled)
                    {
                        log.Info("World Update Thread stopping...");
                    }

                    running = false;
                    break;
                }
                catch (Exception e)
                {
                    if (log.IsErrorEnabled)
                    {
                        log.Error("Error in World Update (NPC/Object Update) Thread!", e);
                    }
                }
            }
        }
        private static bool StartPlayerUpdateTask(GameClient client, IDictionary <GameClient, Tuple <long, Task, Region> > clientsUpdateTasks, long begin)
        {
            var player = client.Player;
            // Check for existing Task
            Tuple <long, Task, Region> clientEntry;

            if (!clientsUpdateTasks.TryGetValue(client, out clientEntry))
            {
                // Client not in tasks, create it and run it !
                clientEntry = new Tuple <long, Task, Region>(begin, Task.Factory.StartNew(() => UpdatePlayerWorld(player)), player.CurrentRegion);

                // Register.
                clientsUpdateTasks.Add(client, clientEntry);
                return(true);
            }
            else
            {
                // Get client entry data.
                long   lastUpdate = clientEntry.Item1;
                Task   taskEntry  = clientEntry.Item2;
                Region lastRegion = clientEntry.Item3;

                //Check if task finished
                if (!taskEntry.IsCompleted)
                {
                    // Check for how long
                    if ((begin - lastUpdate) > GetPlayerWorldUpdateInterval)
                    {
                        if (log.IsWarnEnabled && (GameTimer.GetTickCount() - player.TempProperties.getProperty <long>("LAST_WORLD_UPDATE_THREAD_WARNING", 0) >= 1000))
                        {
                            log.WarnFormat("Player Update Task ({0}) Taking more than world update refresh rate : {1} ms (real {2} ms) - Task Status : {3}!", player.Name, GetPlayerWorldUpdateInterval, begin - lastUpdate, taskEntry.Status);
                            player.TempProperties.setProperty("LAST_WORLD_UPDATE_THREAD_WARNING", GameTimer.GetTickCount());
                        }
                    }
                    // Don't init this client.
                    return(false);
                }

                // Display Exception
                if (taskEntry.IsFaulted)
                {
                    if (log.IsErrorEnabled)
                    {
                        log.ErrorFormat("Error in World Update Thread, Player Task ({0})! Exception : {1}", player.Name, taskEntry.Exception);
                    }
                }

                // Region Refresh
                if (player.CurrentRegion != lastRegion)
                {
                    lastUpdate = 0;
                    lastRegion = player.CurrentRegion;
                    client.GameObjectUpdateArray.Clear();
                    client.HouseUpdateArray.Clear();
                }

                // If this player need update.
                if (PlayerNeedUpdate(lastUpdate))
                {
                    // Update Time, Region and Create Task
                    var newClientEntry = new Tuple <long, Task, Region>(begin, Task.Factory.StartNew(() => UpdatePlayerWorld(player)), lastRegion);
                    // Register Tuple
                    clientsUpdateTasks[client] = newClientEntry;
                    return(true);
                }
            }

            return(false);
        }
Exemple #15
0
			/// <summary>
			/// Removes the timer from the table without locking the table
			/// </summary>
			/// <param name="timer">The timer to remove</param>
			private void RemoveTimerUnsafe(GameTimer timer)
			{
				GameTimer t = timer;
				long tick = t.m_tick;
				if ((tick & TIMER_DISABLED) != 0)
					return;

				timer.m_targetTime = -1;
				// never change the active chain
				if (tick == m_tick || (tick & TIMER_RESCHEDULED) != 0)
				{
					t.m_tick = TIMER_DISABLED | TIMER_RESCHEDULED;
					return;
				}

				m_activeTimers--;

				// check the cache first
				long cachedIndex = tick & CACHE_MASK;
				CacheBucket bucket = m_cachedBucket[cachedIndex];
				if (bucket.FirstTimer == t)
				{
					t.m_tick = TIMER_DISABLED;
					bucket.FirstTimer = t.m_nextTimer;
					if (bucket.LastTimer == t)
						bucket.LastTimer = t.m_nextTimer;
					t.m_nextTimer = null;
					m_cachedBucket[cachedIndex] = bucket;
					return;
				}

				GameTimer timerChain = bucket.FirstTimer;
				GameTimer prev;
				while (timerChain != null)
				{
					prev = timerChain;
					timerChain = timerChain.m_nextTimer;
					if (timerChain == t)
					{
						prev.m_nextTimer = t.m_nextTimer;
						t.m_nextTimer = null;
						t.m_tick = TIMER_DISABLED;
						if (bucket.LastTimer == t)
						{
							bucket.LastTimer = prev;
							m_cachedBucket[cachedIndex] = bucket;
						}
						return;
					}
				}

				// check the buckets
				tick = (tick >> BUCKET_BITS) & TABLE_MASK;
				timerChain = m_buckets[tick];
				if (timerChain == t)
				{
					timerChain = timerChain.m_nextTimer;
					m_buckets[tick] = timerChain;
					t.m_nextTimer = null;
					t.m_tick = TIMER_DISABLED;
					return;
				}

				while (timerChain != null)
				{
					prev = timerChain;
					timerChain = timerChain.m_nextTimer;
					if (timerChain == t)
					{
						prev.m_nextTimer = t.m_nextTimer;
						break;
					}
				}
				t.m_nextTimer = null;
				t.m_tick = TIMER_DISABLED;
			}
Exemple #16
0
        /// <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);
        }
Exemple #17
0
			/// <summary>
			/// The time thread loop
			/// </summary>
			private void TimeThread()
			{
				log.InfoFormat("started timer thread {0} (ID:{1})", m_name, Thread.CurrentThread.ManagedThreadId);

				int timeBalance = 0;
				uint workStart, workEnd;
				GameTimer chain, next, bucketTimer;

				workStart = workEnd = (uint)GetTickCount();
				
#if MonitorCallbacks
				Timer t = new Timer(new TimerCallback(SlowTimerCallback), null, Timeout.Infinite, Timeout.Infinite);
#endif

				while (m_running)
				{
					try
					{
						// fire timers
						lock (m_buckets)
						{
							if(DOL.GS.GameEvents.RegionTimersResynch.watch!=null)
								m_time = DOL.GS.GameEvents.RegionTimersResynch.watch.ElapsedMilliseconds;
							else m_time++;
							
							int newTick = m_tick = (m_tick + 1) & TICK_MASK;
							if ((newTick & BUCKET_MASK) == 0)
							{
								// cache next bucket
								int index = newTick >> BUCKET_BITS;
								next = m_buckets[index];
								if (next != null)
								{
									m_buckets[index] = null;
									// sort the new cached bucket
									do
									{
										GameTimer timer = next;
										next = next.m_nextTimer;
										long index2 = timer.m_tick;
										if ((index2 & LONGTERM_MASK) != 0
											&& ((index2 -= (1 << TABLE_BITS + BUCKET_BITS)) & LONGTERM_MASK) != 0)
										{
											// reinsert longterm timers back
											timer.m_tick = index2;
											bucketTimer = m_buckets[index];
											m_buckets[index] = timer;
										}
										else
										{
											timer.m_tick = index2;
											index2 &= CACHE_MASK;
											bucketTimer = m_cachedBucket[index2].FirstTimer;
											m_cachedBucket[index2].FirstTimer = timer;
											if (m_cachedBucket[index2].LastTimer == null)
												m_cachedBucket[index2].LastTimer = timer;
										}

										if (bucketTimer == null)
										{
											timer.m_nextTimer = null;
										}
										else
										{
											timer.m_nextTimer = bucketTimer;
										}
									}
									while (next != null);
								}
							}

							int cacheIndex = m_tick & CACHE_MASK;
							chain = m_cachedBucket[cacheIndex].FirstTimer;
							if (chain != null)
							{
								m_cachedBucket[cacheIndex] = CacheBucket.EmptyBucket;
							}
						}

						GameTimer current = chain;
						int curTick = m_tick;
						int currentBucketMax = (curTick & ~BUCKET_MASK) + BUCKET_MASK;
						while (current != null)
						{
							if (current.m_tick == curTick)
							{
								try
								{
									long callbackStart = GetTickCount();
									
#if MonitorCallbacks
									m_currentTimer = current;
									m_timerTickStart = callbackStart;
									t.Change(200, 100);
#endif

									current.OnTick();

#if MonitorCallbacks
									m_currentTimer = null;
									t.Change(Timeout.Infinite, Timeout.Infinite);
									if (GetTickCount() - callbackStart > 200)
									{
										lock (m_delayLog)
										{
											m_delayLog.Write("\n========================================================\n\n");
										}
									}
#endif

									if (GetTickCount() - callbackStart > 250) 
									{
										if (log.IsWarnEnabled)
										{
											string curStr;
											try { curStr = current.ToString(); }
											catch(Exception ee) { curStr = "error in timer.ToString(): " + current.GetType().FullName + "; " + ee.ToString(); }
											string warning = "callback took "+(GetTickCount() - callbackStart)+"ms! "+curStr;
											log.Warn(warning);
										}
									}

#if CollectStatistic
									// statistic
									int start = GetTickCount();
									string callback;
									if (current is RegionTimer)
									{
										callback = ((RegionTimer)current).Callback.Method.ToString();
									}
									else
									{
										callback = current.GetType().FullName;
									}
									lock (m_timerCallbackStatistic) 
									{
										object obj = m_timerCallbackStatistic[callback];
										if (obj == null) 
										{
											m_timerCallbackStatistic[callback] = 1;	
										} 
										else 
										{
											m_timerCallbackStatistic[callback] = ((int)obj) + 1;
										}
									}
									if (GetTickCount()-start > 500) 
									{
										if (log.IsWarnEnabled)
											log.Warn("Ticker statistic "+callback+" took more than 500ms!");
									}
#endif
								}
								catch (Exception e)
								{
									string curStr;
									try { curStr = current.ToString(); }
									catch(Exception ee) { curStr = "error in timer.ToString(): " + current.GetType().FullName + "; " + ee.ToString(); }
									if (log.IsErrorEnabled)
										log.Error("Timer callback (" + curStr + ")", e);
									current.m_tick = TIMER_DISABLED | TIMER_RESCHEDULED;
								}
								
								m_invokedCount++;
							}
							else if ((current.m_tick & TIMER_RESCHEDULED) == 0)
							{
								//log.ErrorFormat("timer tick != current tick (0x{0:X4}), fired anyway: {1}", curTick, current);
								try
								{
									current.OnTick();
								}
								catch (Exception e)
								{
									log.Error("timer error", e);
									current.m_tick = TIMER_DISABLED | TIMER_RESCHEDULED;
								}
							}

							lock (m_buckets)
							{
								next = current.m_nextTimer;
								long tick = current.m_tick;
								long interval = current.m_interval;

								if ((tick & TIMER_DISABLED) != 0 || (interval == 0 && (tick & TIMER_RESCHEDULED) == 0))
								{
									m_activeTimers--;
									current.m_nextTimer = null;
									current.m_tick = TIMER_DISABLED;
									current.m_targetTime = -1;
								}
								else
								{
									///// REINSERT all including rescheduled timers
									if ((tick & TIMER_RESCHEDULED) != 0)
									{
										current.m_tick = tick &= ~TIMER_RESCHEDULED;
									}
									else
									{
										current.m_targetTime = (int) (CurrentTime + interval);
										current.m_tick = tick = curTick + interval;
									}

									if (tick - curTick <= CACHE_MASK + 1)
									{
										tick &= CACHE_MASK;
										current.m_tick &= TICK_MASK;
										CacheBucket bucket = m_cachedBucket[tick];
										GameTimer prev = bucket.LastTimer;
										current.m_nextTimer = null;
										if (prev != null)
										{
											prev.m_nextTimer = current;
											bucket.LastTimer = current;
										}
										else
										{
											bucket.FirstTimer = current;
											bucket.LastTimer = current;
										}
										m_cachedBucket[tick] = bucket;
									}
									else
									{
										if ((tick & TICK_MASK) > currentBucketMax)
											current.m_tick = tick += TICK_MASK + 1; // extra pass if the timer is ahead of current tick
										tick = (tick >> BUCKET_BITS) & TABLE_MASK;
										bucketTimer = m_buckets[tick];
										if (bucketTimer == null)
										{
											current.m_nextTimer = null;
										}
										else
										{
											current.m_nextTimer = bucketTimer;
										}
										m_buckets[tick] = current;
									}

									/////
								}
							}

							current = next;
						}

						bucketTimer = null;




						workEnd = (uint)GetTickCount();
						timeBalance += 1 - (int)(workEnd - workStart);

						if (timeBalance > 0)
						{
							Thread.Sleep(timeBalance);
							workStart = (uint)GetTickCount();
							timeBalance -= (int)(workStart - workEnd);
						}
						else
						{
							if (timeBalance < -1000)
							{
								//We can not increase forever if we get out of
								//sync. At some point we have to print out a warning
								//and catch up some time!
								if (log.IsWarnEnabled && timeBalance < -2000)
								{
									// Again, too much warning spam is meaningless.  Will warn if time sync is more than the typical 1 to 2 seconds
									// -tolakram
									log.Warn(Name + " out of sync, over 2000ms lost! " + timeBalance.ToString());
								}
								timeBalance += 1000;
							}
							workStart = workEnd;
						}
					}
					catch (ThreadAbortException e)
					{
						if (log.IsWarnEnabled)
							log.Warn("Time manager thread \"" + m_name + "\" was aborted", e);
						m_running = false;
						break;
					}
					catch (Exception e)
					{
						if (log.IsErrorEnabled)
							log.Error("Exception in time manager \"" + m_name + "\"!", e);
					}
				}

				log.InfoFormat("stopped timer thread {0} (ID:{1})", m_name, Thread.CurrentThread.ManagedThreadId);
			}
 /// <summary>
 /// AdventureWingInstance Constructor
 /// </summary>
 public AdventureWingInstance(ushort ID, GameTimer.TimeManager time, RegionData dat)
     : base(ID, time, dat)
 {
 }
Exemple #19
0
		/// <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>
 /// Update all World Around Player
 /// </summary>
 /// <param name="player">The player needing update</param>
 private static void UpdatePlayerWorld(GamePlayer player)
 {
     UpdatePlayerWorld(player, GameTimer.GetTickCount());
 }