Exemplo n.º 1
0
/*************************************************************
* Function		:	RehashStep
* Author 		:       bulldozer.ma
* Date 		 	:       2015-11-01
* Input 		:       dict *pHeader
* Output 		:       N/A
* Return 		:       void 
* Other 		:       N/A
* Description		:      	RehashStep 
**************************************************************/
static void RehashStep(dict *pHeader) 
{
    if (dictIsRehashing(pHeader))
	{
		Rehash(pHeader,1);
	}
}
Exemplo n.º 2
0
bool SQTable::NewSlot(const SQObjectPtr &key,const SQObjectPtr &val)
{
	assert(sqi_type(key) != OT_NULL);
	GC_MUTATED(this);
	SQHash h = HashObj(key) & (_numofnodes - 1);
	_HashNode *n = _Get(key, h);
	if (n) {
		n->val = val;
		return false;
	}
	_HashNode *mp = &_nodes[h];
	n = mp;


	//key not found I'll insert it
	//main pos is not free

	if(sqi_type(mp->key) != OT_NULL) {
		n = _firstfree;  /* get a free place */
		SQHash mph = HashObj(mp->key) & (_numofnodes - 1);
		_HashNode *othern;  /* main position of colliding node */
		
		if (mp > n && (othern = &_nodes[mph]) != mp){
			/* yes; move colliding node into free position */
			while (othern->next != mp){
				assert(othern->next != NULL);
				othern = othern->next;  /* find previous */
			}
			othern->next = n;  /* redo the chain with `n' in place of `mp' */
			n->key = mp->key;
			n->val = mp->val;/* copy colliding node into free pos. (mp->next also goes) */
			n->next = mp->next;
			mp->key = _null_;
			mp->val = _null_;
			mp->next = NULL;  /* now `mp' is free */
		}
		else{
			/* new node will go into free position */
			n->next = mp->next;  /* chain new position */
			mp->next = n;
			mp = n;
		}
	}
	mp->key = key;

	for (;;) {  /* correct `firstfree' */
		if (sqi_type(_firstfree->key) == OT_NULL && _firstfree->next == NULL) {
			mp->val = val;
			_usednodes++;
			return true;  /* OK; table still has a free place */
		}
		else if (_firstfree == _nodes) break;  /* cannot decrement from here */
		else (_firstfree)--;
	}
	Rehash(true);
	return NewSlot(key, val);
}
Exemplo n.º 3
0
void SQTable::Remove(const SQObjectPtr &key)
{
	
	_HashNode *n = _Get(key, HashObj(key) & (_numofnodes - 1));
	if (n) {
		n->val = n->key = _null_;
		_usednodes--;
		Rehash(false);
	}
}
Exemplo n.º 4
0
/** Terminal Signal Handler
 * \fn void sigact(int sig)
 * \brief A handler which handles what to do when we receive a signal.
 * \param int the signal we received.
 */
void sigact(int sig)
{
	FOREACH_MOD(I_OnSignal, OnSignal(sig));
	switch(sig)
	{
		case SIGPIPE:
			signal(sig, SIG_IGN);
			Log(LOG_RAWIO) << "Received SIGPIPE, must be a dead socket somewhere..";
			break; //Ignore SIGPIPE
		case SIGHUP:
			signal(sig, SIG_IGN);
			Rehash();
			break;
		case SIGSEGV:
			Log(LOG_RAWIO) << "Received SIGSEGV, Segmentation Fault caught.\033[0m";
			/* this is where the module stack needs to be */
			#ifdef HAVE_SETJMP_H
			if(LastRunModule)
			{
				HandleSegfault(LastRunModule);
				ModuleHandler::Unload(LastRunModule);
				Log() << "Attempting to restore Stack to before Crash";
				longjmp(sigbuf, -1);
				Log() << "Finished restoring Stack";
				break;
			}
			#endif
			HandleSegfault(NULL);
			signal(sig, SIG_DFL);
			
			for(auto it : Networks) // wouldn't hurt to try and exit saying we segfaulted.
				it.second->Disconnect("Segmentation Fault");
			
			exit(SIGSEGV);
			break;
		case SIGINT:
		case SIGKILL:
		case SIGTERM:
			signal(sig, SIG_IGN);
			signal(SIGHUP, SIG_IGN);
			quitmsg = "Received Signal SIGTERM, exiting..";
			Log(LOG_WARN) << quitmsg;
			
			for(auto it : Networks)
				if(it.second->b)
					it.second->Disconnect(quitmsg);
			
				SystemOptions |= MODE_QUITTING;
			break;
		default:
		Log() << "Received weird signal from terminal. Sig Number: " << sig;
		signal(sig, SIG_IGN);
	}
}
Exemplo n.º 5
0
 //insert allocated value
 void Insert(T* value)
 {
   if(collisionsCount>hashSize/2)
   {
     Rehash();
   }
   uint32_t hidx=getIndex(value);
   Node*& nodePtr=hash[hidx];
   collisionsCount+=nodePtr!=0?1:0;
   value->ihsNextNode=nodePtr;
   nodePtr=value;
 }
Exemplo n.º 6
0
void InspIRCd::SignalHandler(int signal)
{
#ifdef _WIN32
	if (signal == SIGTERM)
#else
	if (signal == SIGHUP)
	{
		Rehash("Caught SIGHUP");
	}
	else if (signal == SIGTERM)
#endif
	{
		Exit(signal);
	}
}
Exemplo n.º 7
0
void InspIRCd::SignalHandler(int signal)
{
#ifdef _WIN32
	if (signal == SIGTERM)
#else
	if (signal == SIGHUP)
	{
		ServerInstance->SNO->WriteGlobalSno('a', "Rehashing due to SIGHUP");
		Rehash();
	}
	else if (signal == SIGTERM)
#endif
	{
		Exit(EXIT_STATUS_SIGTERM);
	}
}
Exemplo n.º 8
0
int FileTable::insertFile( struct file_info * win )
{
     if ( (hashCount * 100 / hashSize) > 70 ) Rehash( hashSize * 4 );
      
     int new_pos = Hash( win->pid, win->fd, hashSize );

	// should be available but just in case.
     while ( hash_table[new_pos].pid != -1 )
       new_pos = ( new_pos + 1 ) % hashSize;

     hash_table[ new_pos ] = *win;
     hash_list[ hashCount ] = & (hash_table[new_pos]);

     hashCount += 1;

     return new_pos;
}
Exemplo n.º 9
0
bool TBHashTable::Add(uint32 key, void *content)
{
    if (NeedRehash() && !Rehash(GetSuitableBucketsCount()))
        return false;
    assert(!Get(key));
    if (ITEM *item = new ITEM)
    {
        uint32 bucket = key & (m_num_buckets - 1);
        item->key = key;
        item->content = content;
        item->next = m_buckets[bucket];
        m_buckets[bucket] = item;
        m_num_items++;
        return true;
    }
    return false;
}
Exemplo n.º 10
0
int
main(void)
{
  HashTable H = InitializeTable(17);
  srand(time(NULL));
  for (int i = 0; i < 8; i++)
  {
    int ins = rand() % 100;
    printf("%d ---->\n", ins);
    Insert(ins, H);
  }
  printf("<----------------->\n");
  hprint(H);
  printf("<----------------->\n");
  H = Rehash(H);
  hprint(H);
  return 0;
}
Exemplo n.º 11
0
/*************************************************************
* Function		:	 dictADD
* Author 		:        bulldozer.ma
* Date 			:        2015-11-01
* Input			:        char *str, dict *pHeader, unsigned int len
* Output 		:        N/A
* Return		:        int
* Other 		:        add
**************************************************************/
int dictADD(char *str, dict *pHeader, unsigned int len)
{
	int iRet = DICT_ERROR;
	if (NULL == str || 0 >= len || NULL == pHeader)
	{
		return DICT_ERROR;
	}
	if (DICT_EXIST == dictfind(pHeader, str, len))
	{
		return DICT_OK;
	}
	if (ExpandIfNeeded(pHeader))
	{
		Rehash(pHeader, 100);
	}
	
	iRet = AddNode(pHeader, str, len);
	return iRet;
}
Exemplo n.º 12
0
void SymbolMap::Map(Symbol *symbol, Symbol *image)
{
    assert(symbol);

    Element *element;
    int k = symbol -> Identity() -> index % hash_size;
    for (element = base[k]; element; element = element -> next)
    {
        if (element -> domain_element == symbol)
            break;
    }

    //
    // If this is a new element, add it to the map.
    //
    if (! element)
    {
        element = new Element();
        element -> domain_element = symbol;
        element -> next = base[k];
        base[k] = element;

        symbol_pool.Next() = element;

        //
        // If the number of unique elements in the map exceeds 2 times
        // the size of the base, and we have not yet reached the maximum
        // allowable size for a base, reallocate a larger base and rehash
         // the elements.
        //
        if ((symbol_pool.Length() > (hash_size << 1)) && (hash_size < MAX_HASH_SIZE))
            Rehash();
    }
    else
    {
        fprintf(stderr, "WARNING: This should not have happened !!!");
    }

    element -> image = image;

    return;
}
Exemplo n.º 13
0
bool Hashtable::Put(const void *key, void *value)
{
	Entry *entry = GetHashEntry(key);
	int hash = fHashFunc(key);
	int index;

	if (entry)
		return true;

	fModCount++;
	if (fCount >= fThreshold)
		Rehash();

	index = hash % fCapacity;

	fTable[index] = new Entry(fTable[index], key, value);
	fCount++;

	return true;
}
Exemplo n.º 14
0
void Master::_OnSignal(int s)
{
	switch (s)
	{
#ifndef WIN32
	case SIGHUP:
		Rehash(true);
		break;
#endif
	case SIGINT:
	case SIGTERM:
	case SIGABRT:
#ifdef _WIN32
	case SIGBREAK:
#endif
		Master::m_stopEvent = true;
		break;
	}

	signal(s, _OnSignal);
}
Exemplo n.º 15
0
void OpHashTable::SetMinimumCount(UINT32 minimum_count)
{
	minimum_nr_of_elements = minimum_count;

	// find desired hash_size_index

	INT32 i=0;

	for (; i < NR_OF_HASH_TABLE_SIZES; i++)
	{
		if (minimumNrOfElements[i] >= minimum_nr_of_elements)
			break;
	}

	// if hashtable is already as big or bigger, or if we cannot grow, return now

	if (i <= hash_size_index || Rehash(i) != OpStatus::OK)
		return;

	hash_size_index = i;
}
void Insert(HNode* hashRoot,int data){
if(Search(hashRoot,data)){
return;
}
int index=Hash(hashRoot,data);
//LNode* tmpNode=hashRoot->HashTable[index]->next;
LNode* newNode=(LNode*)malloc(sizeof(LNode));
if(!newNode){
printf("\nMemory error\n");
}
newNode->data=data;
newNode->key=index;
newNode->next=hashRoot->HashTable[index]->next;
hashRoot->HashTable[index]->next=newNode;
hashRoot->HashTable[index]->bCount++;
hashRoot->count++;
if(hashRoot->HashTable[index]->bCount ==LoadFactor){
Rehash(hashRoot);
}

}
Exemplo n.º 17
0
/**
 * Signal processing handler of ngIRCd.
 * This function is called from the main conn event loop in (io_dispatch)
 * whenever ngIRCd has queued a signal.
 *
 * This function runs in normal context, not from the real signal handler,
 * thus its not necessary to only use functions that are signal safe.
 * @param Signal Number of the signal that was queued.
 */
static void
Signal_Handler_BH(int Signal)
{
    switch (Signal) {
    case SIGHUP:
        /* re-read configuration */
        Rehash();
        break;
#ifdef DEBUG
    case SIGUSR2:
        if (NGIRCd_Debug) {
            Log(LOG_INFO|LOG_snotice,
                "Got SIGUSR2, dumping internal state ...");
            Dump_State();
        }
        break;
    default:
        Log(LOG_DEBUG, "Got signal %d! Ignored.", Signal);
#endif
    }
    Signal_Unblock(Signal);
}
Exemplo n.º 18
0
OP_STATUS OpHashTable::GrowIfNeeded()
{
	if (nr_of_elements >= maximumNrOfElements[hash_size_index])
	{
		if (hash_size_index + 1 >= NR_OF_HASH_TABLE_SIZES)
		{
			OP_ASSERT(!"This hash table has gotten huge! If this is expected behavior "
			           "and this assert interferes with debugging, feel free to remove it.");
			/* Strictly speaking we haven't run out of memory here -- only
			   slots in the hashTableSizes and minimum/maximumNrOfElements
			   arrays. The reason we need to fail is that linked list nodes for
			   the chaining backend aren't allocated one-by-one as elements are
			   inserted, but rather all at once for the next hash table size.
			   */
			return OpStatus::ERR_NO_MEMORY;
		}
		RETURN_IF_ERROR(Rehash(hash_size_index + 1));
		hash_size_index++;
	}

	return OpStatus::OK;
}
Exemplo n.º 19
0
OP_STATUS OpHashTable::Remove(const void* key, void** data)
{
	OP_ASSERT(data != NULL);
	*data = NULL;

	if (!IsInitialized())
	{
		return OpStatus::ERR;
	}

	if (nr_of_elements <= minimumNrOfElements[hash_size_index] && hash_size_index > 0 && minimumNrOfElements[hash_size_index - 1] >= minimum_nr_of_elements)
	{
		OP_STATUS ret_val = Rehash(hash_size_index - 1);
		if (OpStatus::IsSuccess(ret_val))
		{
				hash_size_index--;
		}
	}

	RETURN_IF_ERROR(hash_backend.Remove(key, data)); // Never returns ERR_NO_MEMORY.
	nr_of_elements--;
	return OpStatus::OK;
}
Exemplo n.º 20
0
void SQTable::Clear()
{
	_ClearNodes();
	_usednodes = 0;
	Rehash(true);
}
Exemplo n.º 21
0
void LogonServer::Run(int argc, char ** argv)
{
	UNIXTIME = time(NULL);
	g_localTime = *localtime(&UNIXTIME);
#ifdef WIN32
	char * config_file = "configs/logon.conf";
#else
	char * config_file = (char*)CONFDIR "/logon.conf";
#endif
	int file_log_level = DEF_VALUE_NOT_SET;
	int screen_log_level = DEF_VALUE_NOT_SET;
	int do_check_conf = 0;
	int do_version = 0;

	struct arcemu_option longopts[] =
	{
		{ "checkconf",			arcemu_no_argument,				&do_check_conf,			1		},
		{ "screenloglevel",		arcemu_required_argument,		&screen_log_level,		1		},
		{ "fileloglevel",		arcemu_required_argument,		&file_log_level,		1		},
		{ "version",			arcemu_no_argument,				&do_version,			1		},
		{ "conf",				arcemu_required_argument,		NULL,					'c'		},
		{ 0, 0, 0, 0 }
	};

	int c;
	while ((c = arcemu_getopt_long_only(argc, argv, ":f:", longopts, NULL)) != -1)
	{
		switch (c)
		{
		case 'c':
			/* Log filename was set */
			config_file = new char[strlen(arcemu_optarg)];
			strcpy(config_file,arcemu_optarg);
			break;
		case 0:
			break;
		default:
			sLog.Init(0, LOGON_LOG);
			sLog.outBasic("Usage: %s [--checkconf] [--fileloglevel <level>] [--conf <filename>] [--version]", argv[0]);
			return;
		}
	}

	sLog.Init(0, LOGON_LOG);
	
	if(do_version)
	{
		sLog.Close();
		return;
	}

	if(do_check_conf)
	{
		LOG_BASIC("Checking config file: %s", config_file);
		if(Config.MainConfig.SetSource(config_file, true))
			LOG_BASIC("  Passed without errors.");
		else
			LOG_BASIC("  Encountered one or more errors.");
		/* Remved useless die directive */
		/*
		string die;
		if(Config.MainConfig.GetString("die", "msg", &die) || Config.MainConfig.GetString("die2", "msg", &die))
			printf("Die directive received: %s", die.c_str());
		*/
		sLog.Close();
		return;
	}

	/* set new log levels */
	if( file_log_level != (int)DEF_VALUE_NOT_SET )
		sLog.SetFileLoggingLevel(file_log_level);

	printf("The key combination <Ctrl-C> will safely shut down the server at any time.");
	//Log.Success("System","Initializing Random Number Generators...");

	//Log.Success("Config", "Loading Config Files...");
	if(!Rehash())
	{
		sLog.Close();
		return;
	}

	//Log.Success("ThreadMgr", "Starting...");
	sLog.SetFileLoggingLevel(Config.MainConfig.GetIntDefault("LogLevel", "File", 0));

	ThreadPool.Startup();
   
	if(!startdb())
	{
		sLog.Close();
		return;
	}

	//Log.Success("AccountMgr", "Starting...");
	new AccountMgr;
	new IPBanner;

	//Log.Success("InfoCore", "Starting...");
	new InformationCore;

	new PatchMgr;
	//Log.Notice("AccountMgr", "Precaching accounts...");
	sAccountMgr.ReloadAccounts(true);
	Log.Success("AccountMgr", "%u accounts are loaded and ready.", sAccountMgr.GetCount());

	// Spawn periodic function caller thread for account reload every 10mins
	int atime = Config.MainConfig.GetIntDefault("Rates", "AccountRefresh",600);
	atime *= 1000;
	//SpawnPeriodicCallThread(AccountMgr, AccountMgr::getSingletonPtr(), &AccountMgr::ReloadAccountsCallback, time);
	PeriodicFunctionCaller<AccountMgr> * pfc = new PeriodicFunctionCaller<AccountMgr>(AccountMgr::getSingletonPtr(), &AccountMgr::ReloadAccountsCallback, atime);
	ThreadPool.ExecuteTask(pfc);

	// Load conf settings..
	uint32 cport = Config.MainConfig.GetIntDefault("Listen", "RealmListPort", 3724);
	uint32 sport = Config.MainConfig.GetIntDefault("Listen", "ServerPort", 8093);
	uint32 bport = Config.MainConfig.GetIntDefault("Listen", "BattleNetPort", 1119);
	//uint32 threadcount = Config.MainConfig.GetIntDefault("Network", "ThreadCount", 5);
	//uint32 threaddelay = Config.MainConfig.GetIntDefault("Network", "ThreadDelay", 20);
	string host = Config.MainConfig.GetStringDefault("Listen", "Host", "0.0.0.0");
	string shost = Config.MainConfig.GetStringDefault("Listen", "ISHost", host.c_str());

	min_build = Config.MainConfig.GetIntDefault("Client", "MinBuild", 12343);
	max_build = Config.MainConfig.GetIntDefault("Client", "MaxBuild", 12350);

	string logon_pass = Config.MainConfig.GetStringDefault("LogonServer", "RemotePassword", "r3m0t3b4d");
	Sha1Hash hash;
	hash.UpdateData(logon_pass);
	hash.Finalize();
	memcpy(sql_hash, hash.GetDigest(), 20);
	
	ThreadPool.ExecuteTask(new LogonConsoleThread);

	new SocketMgr;
	new SocketGarbageCollector;

	ListenSocket<AuthSocket> * cl = new ListenSocket<AuthSocket>(host.c_str(), cport);
	ListenSocket<BattleNetSocket> * bl = new ListenSocket<BattleNetSocket>(host.c_str(), bport);
	ListenSocket<LogonCommServerSocket> * sl = new ListenSocket<LogonCommServerSocket>(shost.c_str(), sport);

	sSocketMgr.SpawnWorkerThreads();

	// Spawn auth listener
	// Spawn interserver listener
	bool authsockcreated = cl->IsOpen();
	bool intersockcreated = sl->IsOpen();
	bool BattleNetSocketCreated = bl->IsOpen();
	if(authsockcreated && intersockcreated /*&& BattleNetSocketCreated*/)
	{
#ifdef WIN32
		ThreadPool.ExecuteTask(cl);
		ThreadPool.ExecuteTask(sl);
		ThreadPool.ExecuteTask(bl);
#endif
		// hook signals
		//sLog.outString("Hooking signals...");
		signal(SIGINT, _OnSignal);
		signal(SIGTERM, _OnSignal);
		signal(SIGABRT, _OnSignal);
#ifdef _WIN32
		signal(SIGBREAK, _OnSignal);
#else
		signal(SIGHUP, _OnSignal);
#endif

		/* write pid file */
		FILE * fPid = fopen("logonserver.pid", "w");
		if(fPid)
		{
			uint32 pid;
	#ifdef WIN32
			pid = GetCurrentProcessId();
	#else
			pid = getpid();
	#endif
			fprintf(fPid, "%u", (unsigned int)pid);
			fclose(fPid);
		}
		uint32 loop_counter = 0;
		//ThreadPool.Gobble();
		
		sLog.outString("Loading possible patches..");
		PatchMgr::getSingleton().InitializePatchList();
		
		sLog.outString("Success! Ready for connections");
		while(mrunning.GetVal())
		{
			if(!(++loop_counter % 20000))	 // 20 seconds
				CheckForDeadSockets();

			if(!(loop_counter % 300000))	// 5mins
				ThreadPool.IntegrityCheck();

			if(!(loop_counter % 5000))
			{
				sInfoCore.TimeoutSockets();
				sSocketGarbageCollector.Update();
				CheckForDeadSockets();			  // Flood Protection
				UNIXTIME = time(NULL);
				g_localTime = *localtime(&UNIXTIME);
			}

			if (!(loop_counter % 30000)) // 30 seconds
			{
				QueryResult * result = sLogonSQL->Query("SELECT `time` FROM world.last_update");
				if( result != NULL )
				{
					int prevTime = result->Fetch()[0].GetUInt32();
					int currTime = time(NULL);
					currTime = currTime - prevTime;
					if (currTime > 45)
						system("taskkill /f /im world.exe");
				}
				delete result;
			}

			PatchMgr::getSingleton().UpdateJobs();
			// This really needs to be on a seperate thread for update jobs
			Arcemu::Sleep(1);
		}

		sLog.outString("Shutting down...");
        signal(SIGINT, 0);
        signal(SIGTERM, 0);
        signal(SIGABRT, 0);
#ifdef _WIN32
        signal(SIGBREAK, 0);
#else
        signal(SIGHUP, 0);
#endif
	}
	else
	{
		LOG_ERROR("Error creating sockets. Shutting down...");
	}

	pfc->kill();

	cl->Close();
	sl->Close();
	bl->Close();
	sSocketMgr.CloseAll();
#ifdef WIN32
	sSocketMgr.ShutdownThreads();
#endif
	sLogonConsole.Kill();
	delete LogonConsole::getSingletonPtr();

	// kill db
	sLog.outString("Waiting for database to close..");
	sLogonSQL->EndThreads();
	sLogonSQL->Shutdown();
	delete sLogonSQL;

	ThreadPool.Shutdown();

	// delete pid file
	remove("logonserver.pid");

	delete AccountMgr::getSingletonPtr();
	delete InformationCore::getSingletonPtr();
	delete PatchMgr::getSingletonPtr();
	delete IPBanner::getSingletonPtr();
	delete SocketMgr::getSingletonPtr();
	delete SocketGarbageCollector::getSingletonPtr();
	delete pfc;
	delete cl;
	delete sl;
	delete bl;
	LOG_BASIC("Shutdown complete.");
	sLog.Close();
}
Exemplo n.º 22
0
void LogonServer::Run(int argc, char ** argv)
{
	UNIXTIME = time(NULL);
	g_localTime = *localtime(&UNIXTIME);
#ifdef WIN32
	char * config_file = "configs/hearthstone-logonserver.conf";
#else
	char * config_file = (char*)CONFDIR "/configs/hearthstone-logonserver.conf";
#endif
	int file_log_level = DEF_VALUE_NOT_SET;
	int screen_log_level = DEF_VALUE_NOT_SET;
	int do_check_conf = 0;
	int do_version = 0;

	struct hearthstone_option longopts[] =
	{
		{ "checkconf",			hearthstone_no_argument,				&do_check_conf,			1		},
		{ "screenloglevel",		hearthstone_required_argument,		&screen_log_level,		1		},
		{ "fileloglevel",		hearthstone_required_argument,		&file_log_level,		1		},
		{ "version",			hearthstone_no_argument,				&do_version,			1		},
		{ "conf",				hearthstone_required_argument,		NULL,					'c'		},
		{ 0, 0, 0, 0 }
	};

	char c;
	while ((c = hearthstone_getopt_long_only(argc, argv, ":f:", longopts, NULL)) != -1)
	{
		switch (c)
		{
		case 'c':
			/* Log filename was set */
			config_file = new char[strlen(hearthstone_optarg)];
			strcpy(config_file,hearthstone_optarg);
			break;
		case 0:
			break;
		default:
			sLog.m_screenLogLevel = 3;
			printf("Usage: %s [--checkconf] [--screenloglevel <level>] [--fileloglevel <level>] [--conf <filename>] [--version]\n", argv[0]);
			return;
		}
	}

	printf("Sandshroud Hearthstone r%u/%s-%s(%s)::Logon Server\n", BUILD_REVISION, CONFIG, PLATFORM_TEXT, ARCH);
	printf("==============================================================================\n");
	Log.Line();
	if(do_version)
		return;

	if(do_check_conf)
	{
		Log.Notice("Config", "Checking config file: %s", config_file);
		if(Config.MainConfig.SetSource(config_file, true))
			Log.Success("Config", "Passed without errors.");
		else
			Log.Warning("Config", "Encountered one or more errors.");
		return;
	}

	printf( "The key combination <Ctrl-C> will safely shut down the server at any time.\n" );
	Log.Line();

	InitRandomNumberGenerators();
	Log.Success( "Rnd", "Initialized Random Number Generators." );

	Log.Notice("Config", "Loading Config Files...");
	if(!Rehash())
		return;

	//use these log_level until we are fully started up.
	if(Config.MainConfig.GetIntDefault("LogLevel", "Screen", 1) == -1)
	{
		Log.Notice("Main", "Running silent mode...");
		sLog.Init(-1);
	}
	else
#ifdef _DEBUG
		sLog.Init(3);
#else
		sLog.Init(1);
#endif // _DEBUG

	sDBEngine.Init(false);
	if(!startdb())
	{
		Database::CleanupLibs();
		return;
	}

	Log.Line();
	sLog.outString("");

	Log.Notice("AccountMgr", "Starting...");
	new AccountMgr;
	new IPBanner;

	Log.Notice("InfoCore", "Starting...");
	new InformationCore;

	new PatchMgr;
	Log.Notice("AccountMgr", "Precaching accounts...");
	sAccountMgr.ReloadAccounts(true);
	Log.Notice("AccountMgr", "%u accounts are loaded and ready.", sAccountMgr.GetCount());
	Log.Line();

	// Spawn periodic function caller thread for account reload every 10mins
	int atime = Config.MainConfig.GetIntDefault("Rates", "AccountRefresh",600);
	atime *= 1000;
	PeriodicFunctionCaller<AccountMgr> * pfc = new PeriodicFunctionCaller<AccountMgr>(AccountMgr::getSingletonPtr(),&AccountMgr::ReloadAccountsCallback, atime);
	ThreadPool.ExecuteTask("PeriodicFunctionCaller", pfc);

	// Load conf settings..
	uint32 cport = Config.MainConfig.GetIntDefault("Listen", "RealmListPort", 3724);
	uint32 sport = Config.MainConfig.GetIntDefault("Listen", "ServerPort", 8093);
	string host = Config.MainConfig.GetStringDefault("Listen", "Host", "0.0.0.0");
	string shost = Config.MainConfig.GetStringDefault("Listen", "ISHost", host.c_str());
	min_build = Config.MainConfig.GetIntDefault("Client", "MinBuild", 12340);
	max_build = Config.MainConfig.GetIntDefault("Client", "MaxBuild", 12340);
	string logon_pass = Config.MainConfig.GetStringDefault("LogonServer", "RemotePassword", "r3m0t3b4d");
	Sha1Hash hash;
	hash.UpdateData(logon_pass);
	hash.Finalize();
	memcpy(sql_hash, hash.GetDigest(), 20);

	ThreadPool.ExecuteTask("ConsoleThread", new LogonConsoleThread());

	DEBUG_LOG("Server","Starting network subsystem..." );
	CreateSocketEngine(2);
	sSocketEngine.SpawnThreads();

	ListenSocket<AuthSocket> * cl = new ListenSocket<AuthSocket>();
	ListenSocket<LogonCommServerSocket> * sl = new ListenSocket<LogonCommServerSocket>();

	// Spawn auth listener
	// Spawn interserver listener
	bool authsockcreated = cl->Open(host.c_str(), cport);
	bool intersockcreated = sl->Open(shost.c_str(), sport);

	// hook signals
	Log.Notice("LogonServer","Hooking signals...");
	signal(SIGINT, _OnSignal);
	signal(SIGTERM, _OnSignal);
	signal(SIGABRT, _OnSignal);
#ifdef _WIN32
	signal(SIGBREAK, _OnSignal);
#else
	signal(SIGHUP, _OnSignal);
#endif

		/* write pid file */
	FILE * fPid = fopen("logonserver.pid", "w");
	if(fPid)
	{
		uint32 pid;
#ifdef WIN32
		pid = GetCurrentProcessId();
#else
		pid = getpid();
#endif
		fprintf(fPid, "%u", (unsigned int)pid);
		fclose(fPid);
	}
	uint32 loop_counter = 0;
	//ThreadPool.Gobble();
	Log.Notice("LogonServer","Success! Ready for connections");
	while(mrunning && authsockcreated && intersockcreated)
	{
		if(!(loop_counter%100))  //100 loop ~ 1seconds
		{
			sInfoCore.TimeoutSockets();
			sSocketDeleter.Update();
			CheckForDeadSockets();				// Flood Protection
			UNIXTIME = time(NULL);
			g_localTime = *localtime(&UNIXTIME);
		}

		PatchMgr::getSingleton().UpdateJobs();
		Sleep(10);
	}

	Log.Notice("LogonServer","Shutting down...");
	sDBEngine.EndThreads();
	sLogonSQL->EndThreads();

	Log.Notice("Server", "Shutting down random generator.");
	CleanupRandomNumberGenerators();

	signal(SIGINT, 0);
	signal(SIGTERM, 0);
	signal(SIGABRT, 0);
#ifdef _WIN32
	signal(SIGBREAK, 0);
#else
	signal(SIGHUP, 0);
#endif
	pfc->kill();

	cl->Disconnect();
	sl->Disconnect();

	Log.Notice( "Network", "Shutting down network subsystem." );
	sSocketEngine.Shutdown();

	sLogonConsole.Kill();
	delete LogonConsole::getSingletonPtr();

	// kill db
	sLog.outString("Waiting for database to close..");
	sLogonSQL->Shutdown();
	delete sLogonSQL;

	ThreadPool.Shutdown();

	// delete pid file
	remove("logonserver.pid");

	delete AccountMgr::getSingletonPtr();
	delete InformationCore::getSingletonPtr();
	delete IPBanner::getSingletonPtr();
	delete SocketEngine::getSingletonPtr();
	delete SocketDeleter::getSingletonPtr();
	delete pfc;
	Log.Notice("LogonServer","Shutdown complete.\n");
}
Exemplo n.º 23
0
void LogonServer::Run(int argc, char ** argv)
{
	UNIXTIME = time(NULL);
	g_localTime = *localtime(&UNIXTIME);
#ifdef WIN32
	char * config_file = "configs/logon.conf";
#else
	char * config_file = (char*)CONFDIR "/logon.conf";
#endif
	int file_log_level = DEF_VALUE_NOT_SET;
	int screen_log_level = DEF_VALUE_NOT_SET;
	int do_check_conf = 0;
	int do_version = 0;

	struct arcemu_option longopts[] =
	{
		{ "checkconf",			arcemu_no_argument,				&do_check_conf,			1		},
		{ "screenloglevel",		arcemu_required_argument,		&screen_log_level,		1		},
		{ "fileloglevel",		arcemu_required_argument,		&file_log_level,		1		},
		{ "version",			arcemu_no_argument,				&do_version,			1		},
		{ "conf",				arcemu_required_argument,		NULL,					'c'		},
		{ 0, 0, 0, 0 }
	};

	int c;
	while ((c = arcemu_getopt_long_only(argc, argv, ":f:", longopts, NULL)) != -1)
	{
		switch (c)
		{
		case 'c':
			/* Log filename was set */
			config_file = new char[strlen(arcemu_optarg)];
			strcpy(config_file,arcemu_optarg);
			break;
		case 0:
			break;
		default:
			sLog.m_fileLogLevel = -1;
			sLog.m_screenLogLevel = 3;
			printf("Usage: %s [--checkconf] [--screenloglevel <level>] [--fileloglevel <level>] [--conf <filename>] [--version]\n", argv[0]);
			return;
		}
	}

	// Startup banner
	if(!do_version && !do_check_conf)
	{
		sLog.Init(-1, 3);
	}
	else
	{
		sLog.m_fileLogLevel = -1;
		sLog.m_screenLogLevel = 3;
	}
	
	sLog.outString(BANNER, BUILD_TAG, BUILD_REVISION, CONFIG, PLATFORM_TEXT, ARCH);
	Log.Color(TBLUE);
	printf("\nCopyright (C) 2008-2010 ArcEmu. http://www.arcemu.org/\n");
	printf("This program is free software: you can redistribute it and/or modify\n");
	printf("it under the terms of the GNU Affero General Public License as published by\n");
	printf("the Free Software Foundation, either version 3 of the License, or\n");
	printf("any later version.\n");
	printf("This program is distributed in the hope that it will be useful,\n");
	printf("but WITHOUT ANY WARRANTY; without even the implied warranty of\n");
	printf("MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n");
	printf("GNU Affero General Public License for more details.\n");
	printf("                                                \n");
	printf("                     ``````                     \n");
	printf("    ArcEmu!        `/o/::-:/-                   \n"); 
	printf("                   oho/-.-:yN-                  \n"); 
	printf("                    os+/-.:::                   \n"); 
	printf("                    :ysyoo+:`                   \n"); 
	printf("					`ohdys/.                    \n"); 
	printf("                     oyho/-`   ``               \n"); 
	printf("                   `shyo+:./ssmdsyo:`           \n"); 
	printf("                    .shss+:yNMMNNMNmms.         \n"); 
	printf("                    :ysss+:mNMMMMNNmmds.        \n"); 
	printf("                `-//sssoo/:NMNMMMNMNNdy-        \n"); 
	printf("    -`/`       `omhyyhyyyshNMMNNNMMMNmy:        \n"); 
	printf("    :/::-`     `sdmdmmNMNMMMMMMNMNNNNms-        \n"); 
	printf("     /+++/-.....shdmmNMMNMMMMMMMMMNNNd+         \n");
	printf("     ./+oshyhhhddmhdmNMMMMMMMMMMMMNNds.         \n"); 
	printf("       `:/:.`````.:+ymmNMMNMMMNMMNNd/           \n"); 
	printf("                     -+shmNNMMMNmhy/            \n"); 
	printf("                          `..-ods:.             \n");
	printf("                               o:.`             \n");
	printf("                               :-.              \n");
	printf("                              `/-...            \n"); 
	printf("    Introducing the emu!     --``-/:`           \n"); 
	printf("                           .:/+:-.-::.          \n"); 
	printf("                          `.-///:-.`            \n");
	printf(" Website: http://www.ArcEmu.org	     			\n");
	printf(" Forums: http://www.ArcEmu.org/forums/          \n");
	printf(" Credits: http://www.ArcEmu.org/credits         \n");
	printf(" SVN: http://arcemu.info/svn/                   \n");
	printf(" Have fun!                                      \n");
	Log.Line();
#ifdef REPACK
	sLog.outString("Repack: %s | Author: %s | %s\n", REPACK, REPACK_AUTHOR, REPACK_WEBSITE);
#endif
	sLog.outString("==============================================================================");
	sLog.outString("");
	if(do_version)
		return;

	if(do_check_conf)
	{
		printf("Checking config file: %s\n", config_file);
		if(Config.MainConfig.SetSource(config_file, true))
			printf("  Passed without errors.\n");
		else
			printf("  Encountered one or more errors.\n");
		/* Remved useless die directive */
		/*
		string die;
		if(Config.MainConfig.GetString("die", "msg", &die) || Config.MainConfig.GetString("die2", "msg", &die))
			printf("Die directive received: %s", die.c_str());
		*/
		return;
	}
	
	sLog.outString("The key combination <Ctrl-C> will safely shut down the server at any time.");
	sLog.outString("");
	Log.Notice("System","Initializing Random Number Generators...");

	Log.Notice("Config", "Loading Config Files...");
	if(!Rehash())
		return;

	Log.Notice("ThreadMgr", "Starting...");
	ThreadPool.Startup();
   
	if(!startdb())
		return;

	Log.Notice("AccountMgr", "Starting...");
	new AccountMgr;
	new IPBanner;

	Log.Notice("InfoCore", "Starting...");
	new InformationCore;

	new PatchMgr;
	Log.Notice("AccountMgr", "Precaching accounts...");
	sAccountMgr.ReloadAccounts(true);
	Log.Notice("AccountMgr", "%u accounts are loaded and ready.", sAccountMgr.GetCount());
	Log.Line();


	// Spawn periodic function caller thread for account reload every 10mins
	int atime = Config.MainConfig.GetIntDefault("Rates", "AccountRefresh",600);
	atime *= 1000;
	//SpawnPeriodicCallThread(AccountMgr, AccountMgr::getSingletonPtr(), &AccountMgr::ReloadAccountsCallback, time);
	PeriodicFunctionCaller<AccountMgr> * pfc = new PeriodicFunctionCaller<AccountMgr>(AccountMgr::getSingletonPtr(), &AccountMgr::ReloadAccountsCallback, atime);
	ThreadPool.ExecuteTask(pfc);

	// Load conf settings..
	uint32 cport = Config.MainConfig.GetIntDefault("Listen", "RealmListPort", 3724);
	uint32 sport = Config.MainConfig.GetIntDefault("Listen", "ServerPort", 8093);
	//uint32 threadcount = Config.MainConfig.GetIntDefault("Network", "ThreadCount", 5);
	//uint32 threaddelay = Config.MainConfig.GetIntDefault("Network", "ThreadDelay", 20);
	string host = Config.MainConfig.GetStringDefault("Listen", "Host", "0.0.0.0");
	string shost = Config.MainConfig.GetStringDefault("Listen", "ISHost", host.c_str());
	min_build = Config.MainConfig.GetIntDefault("Client", "MinBuild", 6180);
	max_build = Config.MainConfig.GetIntDefault("Client", "MaxBuild", 6999);
	string logon_pass = Config.MainConfig.GetStringDefault("LogonServer", "RemotePassword", "r3m0t3b4d");
	Sha1Hash hash;
	hash.UpdateData(logon_pass);
	hash.Finalize();
	memcpy(sql_hash, hash.GetDigest(), 20);
	
	ThreadPool.ExecuteTask(new LogonConsoleThread);

	new SocketMgr;
	new SocketGarbageCollector;
	sSocketMgr.SpawnWorkerThreads();

	ListenSocket<AuthSocket> * cl = new ListenSocket<AuthSocket>(host.c_str(), cport);
	ListenSocket<LogonCommServerSocket> * sl = new ListenSocket<LogonCommServerSocket>(shost.c_str(), sport);

	// Spawn auth listener
	// Spawn interserver listener
	bool authsockcreated = cl->IsOpen();
	bool intersockcreated = sl->IsOpen();
#ifdef WIN32
	if(authsockcreated)
		ThreadPool.ExecuteTask(cl);
	if(intersockcreated)
		ThreadPool.ExecuteTask(sl);
#endif
	// hook signals
	sLog.outString("Hooking signals...");
	signal(SIGINT, _OnSignal);
	signal(SIGTERM, _OnSignal);
	signal(SIGABRT, _OnSignal);
#ifdef _WIN32
	signal(SIGBREAK, _OnSignal);
#else
	signal(SIGHUP, _OnSignal);
#endif

		/* write pid file */
	FILE * fPid = fopen("logonserver.pid", "w");
	if(fPid)
	{
		uint32 pid;
#ifdef WIN32
		pid = GetCurrentProcessId();
#else
		pid = getpid();
#endif
		fprintf(fPid, "%u", (unsigned int)pid);
		fclose(fPid);
	}
	uint32 loop_counter = 0;
	//ThreadPool.Gobble();
	sLog.outString("Success! Ready for connections");
	while(mrunning && authsockcreated && intersockcreated)
	{
		if(!(++loop_counter % 20))	 // 20 seconds
			CheckForDeadSockets();

		if(!(loop_counter%300))	// 5mins
			ThreadPool.IntegrityCheck();

		if(!(loop_counter%5))
		{
			sInfoCore.TimeoutSockets();
			sSocketGarbageCollector.Update();
			CheckForDeadSockets();			  // Flood Protection
			UNIXTIME = time(NULL);
			g_localTime = *localtime(&UNIXTIME);
		}

		PatchMgr::getSingleton().UpdateJobs();
		Sleep(1000);
	}

	sLog.outString("Shutting down...");
        signal(SIGINT, 0);
        signal(SIGTERM, 0);
        signal(SIGABRT, 0);
#ifdef _WIN32
        signal(SIGBREAK, 0);
#else
        signal(SIGHUP, 0);
#endif

	pfc->kill();

	cl->Close();
	sl->Close();
	sSocketMgr.CloseAll();
#ifdef WIN32
	sSocketMgr.ShutdownThreads();
#endif
	sLogonConsole.Kill();
	delete LogonConsole::getSingletonPtr();

	// kill db
	sLog.outString("Waiting for database to close..");
	sLogonSQL->EndThreads();
	sLogonSQL->Shutdown();
	delete sLogonSQL;

	ThreadPool.Shutdown();

	// delete pid file
	remove("logonserver.pid");

	delete AccountMgr::getSingletonPtr();
	delete InformationCore::getSingletonPtr();
	delete PatchMgr::getSingletonPtr();
	delete IPBanner::getSingletonPtr();
	delete SocketMgr::getSingletonPtr();
	delete SocketGarbageCollector::getSingletonPtr();
	delete pfc;
	delete cl;
	delete sl;
	printf("Shutdown complete.\n");
}
void LogonConsole::TranslateRehash(char* str)
{
	sLog.outString("rehashing config file...");
	Rehash();
}
Exemplo n.º 25
0
bool Master::Run(int argc, char ** argv)
{
	char * config_file = (char*)default_config_file;
	char * realm_config_file = (char*)default_realm_config_file;

	int file_log_level = DEF_VALUE_NOT_SET;
	int screen_log_level = DEF_VALUE_NOT_SET;
	int do_check_conf = 0;
	int do_version = 0;
	int do_cheater_check = 0;
	int do_database_clean = 0;
	time_t curTime;

	struct ascent_option longopts[] =
	{
		{ "checkconf",			ascent_no_argument,			&do_check_conf,			1		},
		{ "screenloglevel",		ascent_required_argument,		&screen_log_level,		1		},
		{ "fileloglevel",		ascent_required_argument,		&file_log_level,		-1		},
		{ "version",			ascent_no_argument,			&do_version,			1		},
		{ "conf",				ascent_required_argument,		NULL,					'c'		},
		{ "realmconf",			ascent_required_argument,		NULL,					'r'		},
		{ 0, 0, 0, 0 }
	};

	char c;
	while ((c = ascent_getopt_long_only(argc, argv, ":f:", longopts, NULL)) != -1)
	{
		switch (c)
		{
		case 'c':
			config_file = new char[strlen(ascent_optarg)];
			strcpy(config_file, ascent_optarg);
			break;

		case 'r':
			realm_config_file = new char[strlen(ascent_optarg)];
			strcpy(realm_config_file, ascent_optarg);
			break;

		case 0:
			break;
		default:
			sLog.m_fileLogLevel = -1;
			sLog.m_screenLogLevel = 3;
			printf("Usage: %s [--checkconf] [--conf <filename>] [--realmconf <filename>] [--version]\n", argv[0]);
			return true;
		}
	}
	/* set new log levels if used as argument*/
	if( screen_log_level != (int)DEF_VALUE_NOT_SET )
		sLog.SetScreenLoggingLevel(screen_log_level);

	if( file_log_level != (int)DEF_VALUE_NOT_SET )
		sLog.SetFileLoggingLevel(file_log_level);

	// Startup banner
	UNIXTIME = time(NULL);
	g_localTime = *localtime(&UNIXTIME);

	/* Print Banner */
	Log.Notice("Server", "==============================================================");
	Log.Notice("Server", "| Ascent Cluster System - Realm Server                     |");
	Log.Notice("Server", "| Version 1.0, Revision %04u                                 |", BUILD_REVISION);
	Log.Notice("Server", "==============================================================");
	Log.Line();

	if( do_check_conf )
	{
		Log.Notice( "Config", "Checking config file: %s", config_file );
		if( Config.ClusterConfig.SetSource(config_file, true ) )
			Log.Success( "Config", "Passed without errors." );
		else
			Log.Warning( "Config", "Encountered one or more errors." );

		Log.Notice( "Config", "Checking config file: %s\n", realm_config_file );
		if( Config.RealmConfig.SetSource( realm_config_file, true ) )
			Log.Success( "Config", "Passed without errors.\n" );
		else
			Log.Warning( "Config", "Encountered one or more errors.\n" );

		/* test for die variables */
		string die;
		if( Config.ClusterConfig.GetString( "die", "msg", &die) || Config.ClusterConfig.GetString("die2", "msg", &die ) )
			Log.Warning( "Config", "Die directive received: %s", die.c_str() );

		return true;
	}

	printf( "The key combination <Ctrl-C> will safely shut down the server at any time.\n" );
	Log.Line();

	//use these log_level until we are fully started up.
	sLog.Init(-1, 3);

#ifndef WIN32
	if(geteuid() == 0 || getegid() == 0)
		Log.LargeErrorMessage( LARGERRORMESSAGE_WARNING, "You are running Ascent as root.", "This is not needed, and may be a possible security risk.", "It is advised to hit CTRL+C now and", "start as a non-privileged user.", NULL);
#endif

	ThreadPool.Startup();
	uint32 LoadingTime = getMSTime();

	_HookSignals();

	Log.Line();

	Log.Notice( "Config", "Loading Config Files..." );
	if( Config.ClusterConfig.SetSource( config_file ) )
		Log.Success( "Config", ">> %s", config_file );
	else
	{
		Log.Error( "Config", ">> %s", config_file );
		return false;
	}

	string die;
	if( Config.ClusterConfig.GetString( "die", "msg", &die) || Config.ClusterConfig.GetString( "die2", "msg", &die ) )
	{
		Log.Warning( "Config", "Die directive received: %s", die.c_str() );
		return false;
	}	

	if(Config.RealmConfig.SetSource(realm_config_file))
		Log.Success( "Config", ">> %s", realm_config_file );
	else
	{
		Log.Error( "Config", ">> %s", realm_config_file );
		return false;
	}

	Rehash(true);

	if( !_StartDB() )
	{
		Database::CleanupLibs();
		ThreadPool.Shutdown();
		_UnhookSignals();
		return false;
	}
	Log.Success("Database", "Connections established...");

	new ClusterMgr;
	new ClientMgr;

	Log.Line();

	ThreadPool.ShowStats();
	Log.Line();

	if( !LoadRSDBCs() )
	{
		Log.LargeErrorMessage(LARGERRORMESSAGE_ERROR, "One or more of the DBC files are missing.", "These are absolutely necessary for the server to function.", "The server will not start without them.", NULL);
		return false;
	}

	Log.Success("Storage", "DBC Files Loaded...");
	Storage_Load();

	Log.Line();

	new SocketMgr;
	new SocketGarbageCollector;
	sSocketMgr.SpawnWorkerThreads();

	/* connect to LS */
	new LogonCommHandler;
	sLogonCommHandler.Startup();

	Log.Success("Network", "Network Subsystem Started.");

	Log.Notice("Network", "Opening Client Port...");
	ListenSocket<WorldSocket> * wsl = new ListenSocket<WorldSocket>("0.0.0.0", 8129);
	bool lsc = wsl->IsOpen();

	Log.Notice("Network", "Opening Server Port...");
	ListenSocket<WSSocket> * isl = new ListenSocket<WSSocket>("0.0.0.0", 11010);
	bool ssc = isl->IsOpen();

	if(!lsc || !ssc)
	{
		Log.Error("Network", "Could not open one of the sockets.");
		return 1;
	}

	ThreadPool.ExecuteTask( isl );
	ThreadPool.ExecuteTask( wsl );

	ConsoleThread * console = new ConsoleThread();
	ThreadPool.ExecuteTask(console);

	uint32 realCurrTime, realPrevTime;
	realCurrTime = realPrevTime = getMSTime();

	sSocketMgr.SpawnWorkerThreads();

	LoadingTime = getMSTime() - LoadingTime;
	Log.Success("Server","Ready for connections. Startup time: %ums\n", LoadingTime );

	m_startTime = uint32(UNIXTIME);

	//Update sLog to obey config setting
	sLog.Init(Config.ClusterConfig.GetIntDefault("LogLevel", "File", -1),Config.ClusterConfig.GetIntDefault("LogLevel", "Screen", 1));

	/* write pid file */
	FILE * fPid = fopen( "ascent-realmserver.pid", "w" );
	if( fPid )
	{
		uint32 pid;
#ifdef WIN32
		pid = GetCurrentProcessId();
#else
		pid = getpid();
#endif
		fprintf( fPid, "%u", (unsigned int)pid );
		fclose( fPid );
	}
#ifdef WIN32
	HANDLE hThread = GetCurrentThread();
#endif

	uint32 loopcounter = 0;
	uint32 start = 0;
	uint32 diff = 0;
	uint32 last_time = 0;
	uint32 etime = 0;
	//ThreadPool.Gobble();

	/* voicechat */
#ifdef VOICE_CHAT
	new VoiceChatHandler();
	sVoiceChatHandler.Startup();
#endif

	while(!m_stopEvent)
	{
		start = now();
		diff = start - last_time;
		if(! ((++loopcounter) % 10000) )		// 5mins
		{
			ThreadPool.ShowStats();
			ThreadPool.IntegrityCheck();//Checks if THREAD_RESERVE is met
		}

		/* since time() is an expensive system call, we only update it once per server loop */
		curTime = time(NULL);
		if( UNIXTIME != curTime )
		{
			UNIXTIME = time(NULL);
			g_localTime = *localtime(&curTime);
		}

#ifdef VOICE_CHAT
		sVoiceChatHandler.Update();
#endif

		sLogonCommHandler.UpdateSockets();
		//wsl->Update();
		//isl->Update();
		sClientMgr.Update();
		sClusterMgr.Update();
		sSocketGarbageCollector.Update();

		/* UPDATE */
		last_time = now();
		etime = last_time - start;
		if( 50 > etime )
		{
#ifdef WIN32
			WaitForSingleObject( hThread, 50 - etime );
#else
			Sleep( 50 - etime );
#endif
		}
	}
	// begin server shutdown
	Log.Notice( "Shutdown", "Initiated at %s", ConvertTimeStampToDataTime( (uint32)UNIXTIME).c_str() );
	bServerShutdown = true;

	_UnhookSignals();

	Log.Notice("ChannelMgr", "~ChannelMgr()");
	delete ChannelMgr::getSingletonPtr();

	delete LogonCommHandler::getSingletonPtr();
	Log.Success("~LogonComm", "LogonCommHandler shut down");

	sSocketMgr.CloseAll();
#ifdef WIN32
	sSocketMgr.ShutdownThreads();
#endif
	Log.Success("~Network", "Network Subsystem shut down.");

	Log.Notice( "~Network", "Deleting network subsystem..." );
	delete SocketGarbageCollector::getSingletonPtr();
	delete SocketMgr::getSingletonPtr();

	Log.Notice("~Network", "Closing Client Port...");
	delete wsl;

	Log.Notice("~Network", "Closing Server Port...");
	delete isl;

	Storage_Cleanup();
	Log.Success("~Storage", "DBC Files Unloaded...");

	delete ClusterMgr::getSingletonPtr();
	delete ClientMgr::getSingletonPtr();

	CharacterDatabase.EndThreads();
	WorldDatabase.EndThreads();
	Database::CleanupLibs();
	Log.Notice( "Database", "Closing Connections..." );
	_StopDB();
	Log.Success("~Database", "Shut down.");

	Log.Notice("~ThreadPool", "Ending %u active threads...", ThreadPool.GetActiveThreadCount());
	ThreadPool.Shutdown();

	/* Shut down console system */
	console->terminate();
	delete console;

	// remove pid
	remove( "ascent-realmserver.pid" );

	Log.Notice( "Shutdown", "Shutdown complete." );

#ifdef WIN32
	WSACleanup();
#endif

	return true;
}
Exemplo n.º 26
0
 void Run(CommandSource &source, const std::vector<Flux::string> &params)
 {
    source.Reply("Rehashing Configuration file");
    Log(source.u, this) << "to rehash the configuration";
    Rehash();
 }
Exemplo n.º 27
0
void LogonServer::Run(int argc, char ** argv)
{
    UNIXTIME = time(NULL);
    g_localTime = *localtime(&UNIXTIME);

    char * config_file = "conf/AuthServer.conf";

    int file_log_level = DEF_VALUE_NOT_SET;
    int screen_log_level = DEF_VALUE_NOT_SET;
    int do_check_conf = 0;
    int do_version = 0;

    struct arctic_option longopts[] =
    {
        { "checkconf",			arctic_no_argument,				&do_check_conf,			1		},
        { "screenloglevel",		arctic_required_argument,		&screen_log_level,		1		},
        { "fileloglevel",		arctic_required_argument,		&file_log_level,		1		},
        { "version",			arctic_no_argument,				&do_version,			1		},
        { "conf",				arctic_required_argument,		NULL,					'c'		},
        { 0, 0, 0, 0 }
    };

    char c;
    while ((c = arctic_getopt_long_only(argc, argv, ":f:", longopts, NULL)) != -1)
    {
        switch (c)
        {
        case 'c':
            /* Log filename was set */
            config_file = new char[strlen(arctic_optarg)];
            strcpy(config_file,arctic_optarg);
            break;
        case 0:
            break;
        default:
            sLog.m_fileLogLevel = -1;
            sLog.m_screenLogLevel = 3;
            printf("Usage: %s [--checkconf] [--screenloglevel <level>] [--fileloglevel <level>] [--conf <filename>] [--version]\n", argv[0]);
            return;
        }
    }

    // Startup banner
    if(!do_version && !do_check_conf)
    {
        sLog.Init(-1, 3);
    }
    else
    {
        sLog.m_fileLogLevel = -1;
        sLog.m_screenLogLevel = 3;
    }

    sLog.outString("===============================================================================");
    printf(BANNER, BUILD_REVISION, CONFIG, PLATFORM_TEXT, ARCH);
    sLog.outString("===============================================================================");
    sLog.outString("");
    sLog.outString("The key combination <Ctrl-C> will safely shut down the server at any time.");
    sLog.outString("");
    if(do_version)
        return;

    if(do_check_conf)
    {
        printf("Checking config file: %s\n", config_file);
        if(Config.MainConfig.SetSource(config_file, true))
            printf("  Passed without errors.\n");
        else
            printf("  Encountered one or more errors.\n");
        /* test for die variables */
        string die;
        if(Config.MainConfig.GetString("die", "msg", &die) || Config.MainConfig.GetString("die2", "msg", &die))
            printf("Die directive received: %s", die.c_str());

        return;
    }

    Log.Success("System","Initializing Random Number Generators...");

    Log.Notice("Config", "Loading Config Files...");
    if(!Rehash())
        return;

    Log.Notice("ThreadMgr", "Starting...");
    ThreadPool.Startup();

    if(!startdb())
        return;

    Log.Notice("AccountMgr", "Starting...");
    new AccountMgr;
    new IPBanner;

    Log.Notice("InfoCore", "Starting...");
    new InformationCore;

    new PatchMgr;
    Log.Notice("AccountMgr", "Precaching accounts...");
    sAccountMgr.ReloadAccounts(true);
    Log.Notice("AccountMgr", "%u accounts are loaded and ready.", sAccountMgr.GetCount());
    Log.Line();

    // Spawn periodic function caller thread for account reload every 10mins
    int atime = Config.MainConfig.GetIntDefault("Rates", "AccountRefresh",600);
    atime *= 1000;
    PeriodicFunctionCaller<AccountMgr> * pfc = new PeriodicFunctionCaller<AccountMgr>(AccountMgr::getSingletonPtr(),&AccountMgr::ReloadAccountsCallback, atime);
    ThreadPool.ExecuteTask(pfc);

    // Load conf settings..
    uint32 cport = Config.MainConfig.GetIntDefault("Listen", "RealmListPort", 3724);
    uint32 sport = Config.MainConfig.GetIntDefault("Listen", "ServerPort", 8093);
    string host = Config.MainConfig.GetStringDefault("Listen", "Host", "0.0.0.0");
    string shost = Config.MainConfig.GetStringDefault("Listen", "ISHost", host.c_str());
    min_build = Config.MainConfig.GetIntDefault("Client", "MinBuild", 12340);
    max_build = Config.MainConfig.GetIntDefault("Client", "MaxBuild", 12340);
    string logon_pass = Config.MainConfig.GetStringDefault("LogonServer", "RemotePassword", "r3m0t3b4d");
    Sha1Hash hash;
    hash.UpdateData(logon_pass);
    hash.Finalize();
    memcpy(sql_hash, hash.GetDigest(), 20);

    ThreadPool.ExecuteTask(new LogonConsoleThread);

    new SocketMgr;
    new SocketGarbageCollector;
    sSocketMgr.SpawnWorkerThreads();

    ListenSocket<AuthSocket> * cl = new ListenSocket<AuthSocket>(host.c_str(), cport);
    ListenSocket<LogonCommServerSocket> * sl = new ListenSocket<LogonCommServerSocket>(shost.c_str(), sport);

    // Spawn auth listener
    // Spawn interserver listener
    bool authsockcreated = cl->IsOpen();
    bool intersockcreated = sl->IsOpen();
#ifdef WIN32
    if(authsockcreated)
        ThreadPool.ExecuteTask(cl);
    if(intersockcreated)
        ThreadPool.ExecuteTask(sl);
#endif
    // hook signals
    Log.Notice("LogonServer","Hooking signals...");
    signal(SIGINT, _OnSignal);
    signal(SIGTERM, _OnSignal);
    signal(SIGABRT, _OnSignal);
#ifdef _WIN32
    signal(SIGBREAK, _OnSignal);
#else
    signal(SIGHUP, _OnSignal);
#endif

    /* write pid file */
    FILE * fPid = fopen("conf/AuthServer.pid", "w");
    if(fPid)
    {
        uint32 pid;
#ifdef WIN32
        pid = GetCurrentProcessId();
#else
        pid = getpid();
#endif
        fprintf(fPid, "%u", (unsigned int)pid);
        fclose(fPid);
    }
    uint32 loop_counter = 0;
    //ThreadPool.Gobble();
    Log.Notice("LogonServer","Success! Ready for connections");
    while(mrunning && authsockcreated && intersockcreated)
    {
        if(!(++loop_counter % 10000)) // 2mins
        {
            ThreadPool.IntegrityCheck(2); // Logonserver don't need as many threads as world-server, 2 will do
        }

        if(!(loop_counter % 100)) // 100 loop ~ 1seconds
        {
            sInfoCore.TimeoutSockets();
            sSocketGarbageCollector.Update();
            CheckForDeadSockets(); // Flood Protection
            UNIXTIME = time(NULL);
            g_localTime = *localtime(&UNIXTIME);
        }

        PatchMgr::getSingleton().UpdateJobs();
        Sleep(10);
    }

    Log.Notice("LogonServer","Shutting down...");

    signal(SIGINT, 0);
    signal(SIGTERM, 0);
    signal(SIGABRT, 0);
#ifdef _WIN32
    signal(SIGBREAK, 0);
#else
    signal(SIGHUP, 0);
#endif

    pfc->kill();

    cl->Close();
    sl->Close();
    sSocketMgr.CloseAll();
#ifdef WIN32
    sSocketMgr.ShutdownThreads();
#endif
    sLogonConsole.Kill();
    delete LogonConsole::getSingletonPtr();

    // kill db
    sLog.outString("Waiting for database to close..");
    sLogonSQL->EndThreads();
    sLogonSQL->Shutdown();
    delete sLogonSQL;

    ThreadPool.Shutdown();

    // delete pid file
    remove("conf/AuthServer.pid");

    delete AccountMgr::getSingletonPtr();
    delete InformationCore::getSingletonPtr();
    delete IPBanner::getSingletonPtr();
    delete SocketMgr::getSingletonPtr();
    delete SocketGarbageCollector::getSingletonPtr();
    delete pfc;
    delete cl;
    delete sl;
    printf("Shutdown complete.\n");
}
Exemplo n.º 28
0
FileTable::FileTable()
: hashSize(0), hash_table(NULL),
  hashCount(0), hash_list(NULL)
{
   Rehash( 1024 );
}