Exemple #1
0
bool DayWatcherThread::run()
{
	SetThreadName("DayWatcher");

	Log.Notice("DayWatcherThread", "Started.");
	_loaded = false;
	currenttime = UNIXTIME;
	dupe_tm_pointer(localtime(&currenttime), &local_currenttime);
	load_settings();
	set_tm_pointers();
	m_busy = false;
	_firstrun[0] = true;
	_firstrun[1] = true;
	m_heroic_reset = false;

#ifdef WIN32
	m_abortEvent = CreateEvent(NULL, NULL, FALSE, NULL);
#else
	struct timeval now;
	struct timespec tv;

	pthread_mutex_init(&abortmutex,NULL);
	pthread_cond_init(&abortcond,NULL);
#endif
	uint32 interv = 120000; // Daywatcher check interval (in ms), must be >> 30secs !

	while(m_threadRunning)
	{
		m_busy=true;
		currenttime = UNIXTIME;
		dupe_tm_pointer(localtime(&currenttime), &local_currenttime);

		if(has_timeout_expired(&local_currenttime, &local_last_arena_time, arena_period))
			update_arena();

		if(has_timeout_expired(&local_currenttime, &local_last_daily_reset_time, DAILY))
			update_daily();

		// reset will occur daily between 07:59:00 CET and 08:01:30 CET (players inside will get 60 sec countdown)
		// 8AM = 25200s
		uint32 umod = uint32(currenttime + 3600) % 86400;
		if(!m_heroic_reset && umod >= 25140 && umod <= 25140 + (interv/1000) + 30 )
		{
			//It's approx 8AM, let's reset (if not done so already)
			Reset_Heroic_Instances();
			m_heroic_reset = true;
		}
		if(m_heroic_reset && umod > 25140 + (interv/1000) + 30 )
			m_heroic_reset = false;

		if(m_dirty)
			update_settings();

		m_busy=false;
		if(!m_threadRunning)
			break;

#ifdef WIN32
		WaitForSingleObject(m_abortEvent, interv);
#else
		gettimeofday(&now, NULL);
		tv.tv_sec = now.tv_sec + 120;
		tv.tv_nsec = now.tv_usec * 1000;
		pthread_mutex_lock(&abortmutex);
		pthread_cond_timedwait(&abortcond, &abortmutex, &tv);
		pthread_mutex_unlock(&abortmutex);
#endif
		if(!m_threadRunning)
			break;
	}
#ifdef WIN32
	CloseHandle(m_abortEvent);
#else
	pthread_mutex_destroy(&abortmutex);
	pthread_cond_destroy(&abortcond);
#endif
	return true;
}
bool DayWatcherThread::run()
{
	SetThreadName("DayWatcher");

	Log.Notice("DayWatcherThread", "Started.");
	_loaded = false;
	currenttime = UNIXTIME;
	dupe_tm_pointer(localtime(&currenttime), &local_currenttime);
	load_settings();
	set_tm_pointers();
	m_busy = false;
	_firstrun[0] = true;
	_firstrun[1] = true;
	m_heroic_reset = false;

#ifdef WIN32
	m_abortEvent = CreateEvent(NULL, NULL, FALSE, NULL);
#else

	struct timeval now;
	struct timespec tv;

	pthread_mutex_init(&abortmutex,NULL);
	pthread_cond_init(&abortcond,NULL);
#endif
	uint32 interv = 120000;//Daywatcher check interval (in ms), must be >> 30secs !
	uint32 counter = 0;

	while(m_threadRunning)
	{
		m_busy=true;
		currenttime = UNIXTIME;
		dupe_tm_pointer(localtime(&currenttime), &local_currenttime);

		if(has_timeout_expired(&local_currenttime, &local_last_arena_time, arena_period))
			update_arena();

		if(has_timeout_expired(&local_currenttime, &local_last_daily_reset_time, DAILY))
		{
			update_daily();
			runEvents = true;
		}

		// reset will occur daily between 07:59:00 CET and 08:01:30 CET (players inside will get 60 sec countdown)
		// 8AM = 25200s
		uint32 umod = uint32(currenttime + 3600) % 86400;
		if(!m_heroic_reset && umod >= 25140 && umod <= 25140 + (interv/1000) + 30 )
		{
			//It's approx 8AM, let's reset (if not done so already)
			Reset_Heroic_Instances();
			m_heroic_reset = true;
		}
		if(m_heroic_reset && umod > 25140 + (interv/1000) + 30 )
			m_heroic_reset = false;

		if(has_timeout_expired(&local_currenttime, &local_last_eventid_time, HOURLY))
		{
			Log.Notice("DayWatcherThread", "Running Hourly In Game Events checks...");
			for(EventsList::iterator itr = m_eventIdList.begin(); itr != m_eventIdList.end(); itr++)
			{
				if(!(*itr)->eventbyhour)
					continue;

				if((*itr)->isactive)
				{
					if((*itr)->lastactivated && !CheckHourlyEvent(&local_currenttime, (*itr)->starthour, (*itr)->endhour))
					{
						(*itr)->isactive = false;
						SpawnEventId((*itr)->eventId, false);
						update_event_settings((*itr)->eventId,0);
					}
					else
					{
						if((*itr)->lastactivated && _firstrun[0])
						{
							if(!SpawnEventId((*itr)->eventId))
									break;
						}
						if(!(*itr)->lastactivated)
						{
						time_t activated = (*itr)->lastactivated = UNIXTIME;
						update_event_settings((*itr)->eventId, activated);
						runEvents = true;
						}
						continue;
					}
				}
				else
				{
					if(CheckHourlyEvent(&local_currenttime, (*itr)->starthour, (*itr)->endhour))
					{
						if(!SpawnEventId((*itr)->eventId))
							break;

						(*itr)->isactive = true;
						time_t activated = (*itr)->lastactivated = UNIXTIME;
						update_event_settings((*itr)->eventId, activated);
						continue;
					}
				}
			}
			_firstrun[0] = false;
			last_eventid_time = UNIXTIME;
			dupe_tm_pointer(localtime(&last_eventid_time), &local_last_eventid_time);
			m_dirty = true;
		}

		if(runEvents = true) // We run checks every 2 minutes.
		{
			if(_loaded)
			{
				runEvents = false;
				bool monthexpired = false;
				counter++;
				/* If we used sWorld.SpamWaitTime, we would do counter == (sWorld.SpamWaitTime/2 + 3)
				This would be say 30 minutes in config, so 30/2 = 15 + 2 = 17 and we set counter to 2
				every time so 17 - 2 = 15 so 15x2 for every two minutes = 30 minutes timings.*/
				if(counter <= 2) // First ticks
				{
					Log.Notice("DayWatcherThread", "Running In Game Events checks...");
				}
				if(counter == 17/*15 + 2*/) // Tick every 30 minutes and reset.
				{
					Log.Notice("DayWatcherThread", "Running In Game Events checks...");
					counter = 2;
				}

				for(EventsList::iterator itr = m_eventIdList.begin(); itr != m_eventIdList.end(); itr++)
				{
					if((*itr)->eventbyhour)
						continue;

					if((*itr)->isactive)
					{
						if((*itr)->lastactivated && has_eventid_expired((*itr)->activedays, (*itr)->lastactivated))
						{
							(*itr)->isactive = false;
							SpawnEventId((*itr)->eventId, false);
							update_event_settings((*itr)->eventId,0);
						}
						else
						{
							if((*itr)->lastactivated && _firstrun[1])
							{
								if(!SpawnEventId((*itr)->eventId))
										break;
							}

							if(!(*itr)->lastactivated)
							{
							time_t activated = (*itr)->lastactivated = UNIXTIME;
							update_event_settings((*itr)->eventId, activated);
							runEvents = true;
							}
							continue;
						}
					}
					else
					{
						if((*itr)->monthnumber)
						{
							if(has_eventid_timeout_expired(&local_currenttime, ((*itr)->monthnumber - 1), MONTHLY))
							{
								if(!(*itr)->daynumber)
								{
									if(!SpawnEventId((*itr)->eventId))
											break;
									(*itr)->isactive = true;
									time_t activated = (*itr)->lastactivated = UNIXTIME;
									update_event_settings((*itr)->eventId, activated);
									continue;
								}
								monthexpired = true;
							}
						}
						if(monthexpired && (*itr)->daynumber && has_eventid_timeout_expired(&local_currenttime, (*itr)->daynumber, DAILY))
						{
							monthexpired = false;
							time_t activated = (*itr)->lastactivated = UNIXTIME;
							update_event_settings((*itr)->eventId, activated);
							continue;
						}
						if((*itr)->daynumber && !(*itr)->monthnumber && has_eventid_timeout_expired(&local_currenttime, (*itr)->daynumber, DAILY))
						{
							if(!SpawnEventId((*itr)->eventId))
								break;
							(*itr)->isactive = true;
							time_t activated = (*itr)->lastactivated = UNIXTIME;
							update_event_settings((*itr)->eventId, activated);
						}
					}
				}
				_firstrun[1] = false;
			}
		}
		if(m_dirty)
			update_settings();

		m_busy=false;
		if(!m_threadRunning)
			break;

#ifdef WIN32
		WaitForSingleObject(m_abortEvent, interv);
#else
		gettimeofday(&now, NULL);
		tv.tv_sec = now.tv_sec + 120;
		tv.tv_nsec = now.tv_usec * 1000;
		pthread_mutex_lock(&abortmutex);
		pthread_cond_timedwait(&abortcond, &abortmutex, &tv);
		pthread_mutex_unlock(&abortmutex);
#endif
		if(!m_threadRunning)
			break;
	}
#ifdef WIN32
	CloseHandle(m_abortEvent);
#else
	pthread_mutex_destroy(&abortmutex);
	pthread_cond_destroy(&abortcond);
#endif
	return true;
}