Beispiel #1
0
uint32_t fileWrite(const char *filename, uint8_t *buffer, uint32_t size )
{
	int file ;
	uint32_t result ;

    mode_t mode = S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH;

	file = open( filename, O_WRONLY | O_CREAT | O_TRUNC, mode );
	if( file == -1 )
	{
		LOG_BASIC("error: open file %s !\n", filename);
		return FILE_OPEN_ERROR ;
	}

	result = (uint32_t)write(file,  buffer, size);
	if( result != size )
	{
		LOG_BASIC("error: write (%d writed instead of %ld).\n",result,size);
		return FILE_IO_ERROR;
	}

	close( file );

	return FILE_OK ;
}
Beispiel #2
0
void ConsoleThread::terminate()
{
	m_killSwitch = true;
#ifdef WIN32
	/* write the return keydown/keyup event */
	DWORD dwTmp;
	INPUT_RECORD ir[2];
	ir[0].EventType = KEY_EVENT;
	ir[0].Event.KeyEvent.bKeyDown = TRUE;
	ir[0].Event.KeyEvent.dwControlKeyState = 288;
	ir[0].Event.KeyEvent.uChar.AsciiChar = 13;
	ir[0].Event.KeyEvent.wRepeatCount = 1;
	ir[0].Event.KeyEvent.wVirtualKeyCode = 13;
	ir[0].Event.KeyEvent.wVirtualScanCode = 28;
	ir[1].EventType = KEY_EVENT;
	ir[1].Event.KeyEvent.bKeyDown = FALSE;
	ir[1].Event.KeyEvent.dwControlKeyState = 288;
	ir[1].Event.KeyEvent.uChar.AsciiChar = 13;
	ir[1].Event.KeyEvent.wRepeatCount = 1;
	ir[1].Event.KeyEvent.wVirtualKeyCode = 13;
	ir[1].Event.KeyEvent.wVirtualScanCode = 28;
	WriteConsoleInput(GetStdHandle(STD_INPUT_HANDLE), ir, 2, & dwTmp);
#endif
	LOG_BASIC("Waiting for console thread to terminate....");
	while(m_isRunning)
	{
		Arcemu::Sleep(100);
	}
	LOG_BASIC("Console shut down.");
}
Beispiel #3
0
void LogonConsole::Kill()
{
	_thread->kill.SetVal(true);
#ifdef WIN32
	/* write the return keydown/keyup event */
	DWORD dwTmp;
	INPUT_RECORD ir[2];
	ir[0].EventType = KEY_EVENT;
	ir[0].Event.KeyEvent.bKeyDown = TRUE;
	ir[0].Event.KeyEvent.dwControlKeyState = 288;
	ir[0].Event.KeyEvent.uChar.AsciiChar = 13;
	ir[0].Event.KeyEvent.wRepeatCount = 1;
	ir[0].Event.KeyEvent.wVirtualKeyCode = 13;
	ir[0].Event.KeyEvent.wVirtualScanCode = 28;
	ir[1].EventType = KEY_EVENT;
	ir[1].Event.KeyEvent.bKeyDown = FALSE;
	ir[1].Event.KeyEvent.dwControlKeyState = 288;
	ir[1].Event.KeyEvent.uChar.AsciiChar = 13;
	ir[1].Event.KeyEvent.wRepeatCount = 1;
	ir[1].Event.KeyEvent.wVirtualKeyCode = 13;
	ir[1].Event.KeyEvent.wVirtualScanCode = 28;
	WriteConsoleInput(GetStdHandle(STD_INPUT_HANDLE), ir, 2, & dwTmp);
#endif
	LOG_BASIC("Waiting for console thread to terminate....");
	while(_thread != NULL)
	{
		arcpro::Sleep(100);
	}
	LOG_BASIC("Console shut down.");
}
Beispiel #4
0
void XAI::InitAI(IGlobalAICallback* gcb, int team) {
	xaiInstance = xaiInstances++;
	xaiHelper->Init(gcb);

	LOG_BASIC(
		xaiHelper->logger,
		"[XAI::InitAI]\n"      <<
		"\tteam:             " << team << "\n"
		"\tinstance:         " << xaiInstance << "\n"
		"\tactive instances: " << xaiInstances << "\n"
	);

	std::string initMsg =
		std::string(AI_VERSION) + " initialized succesfully!";
	std::string logMsg =
		"logging events to " + (xaiHelper->logger->GetLogName(NULL)) + "[log].txt";

	xaiHelper->rcb->SendTextMsg(initMsg.c_str(), 0);
	xaiHelper->rcb->SendTextMsg(logMsg.c_str(), 0);

	XAICScopedTimer t("[XAI::InitAI]", xaiHelper->timer);

	XAI_BEG_EXCEPTION
		XAIInitEvent e;
			e.type  = XAI_EVENT_INIT;
			e.frame = 0;
		xaiHelper->eventHandler->NotifyReceivers(&e);
	XAI_END_EXCEPTION(xaiHelper->logger, "[XAI::InitAI]")
}
Beispiel #5
0
uint8_t *fileMmapRead(const char *filename, uint32_t *len)
{
    uint8_t * ptr;
    int fileDescriptor;
    struct stat statInfo;

    // from apple docs
    
    ptr = NULL;
    *len = 0;
    
    // Open the file.
    fileDescriptor = open( filename, O_RDONLY, 0 );
    if( fileDescriptor < 0 )
    {
        LOG_BASIC("error: open file %s\n", filename );
        return NULL;
    }
    else
    {
        // We now know the file exists. Retrieve the file size.
        if( fstat( fileDescriptor, &statInfo ) != 0 )
        {
           return NULL;
        }
        else
        {
            // Map the file into a read-only memory region.
            ptr = (uint8_t *)mmap(NULL,statInfo.st_size,PROT_READ,MAP_SHARED,fileDescriptor,0);
            if( ptr == MAP_FAILED )
            {
                LOG_BASIC("error: mmap file %s\n", filename );
                return NULL;
            }
            else
            {
                // On success, return the size of the mapped file.
                *len = (uint32_t)statInfo.st_size;
            }
        }
        
        // Now close the file. The kernel doesn’t use our file descriptor.
        close( fileDescriptor );
    }
   
    return ptr;
}
Beispiel #6
0
int registryLogAces(PACL pDacl)
{
	int iReturnCode = EDT_OK;
	DWORD i = 0;
	LPVOID pAce = NULL;
	PACE_HEADER pAceheader=NULL;

	LOG_ENTER();
	for(;i<pDacl->AceCount;i++)
	{
		GetAce(pDacl,i,&pAce);
		pAceheader = (PACE_HEADER)pAce;
		pAceheader->AceType;
		pAceheader->AceSize;
		LOG(L"-------------------\n",pAceheader->AceFlags);
		LOG(L"AceFlags are 0x%.2x\n",pAceheader->AceFlags);
		RegistryLogAceFlags(pAceheader->AceFlags);
		LOG(L"AceSize  is  0x%.2x\n",pAceheader->AceSize);
		LOG(L"AceType  is  0x%.2x\n",pAceheader->AceType);
		switch(pAceheader->AceType)
		{
		case ACCESS_ALLOWED_ACE_TYPE:
		case ACCESS_DENIED_ACE_TYPE:
		case SYSTEM_AUDIT_ACE_TYPE:
		case SYSTEM_ALARM_ACE_TYPE:
			//case SYSTEM_MANDATORY_LABEL_ACE:
			{
				PACCESS_ALLOWED_ACE pAccessAllowedAce = (PACCESS_ALLOWED_ACE)pAce;
				LOG(L"AceMask  is 0x%.8x, this means access permissions are:\n",pAccessAllowedAce->Mask);
				RegistryLogAceMask(pAccessAllowedAce->Mask);
				LOG(L"The above access permissions are given to following SID'S:\n");
				RegistryLogAceSidStart( &(pAccessAllowedAce->SidStart));
			}
			break;
		case ACCESS_ALLOWED_OBJECT_ACE_TYPE:
		case ACCESS_DENIED_OBJECT_ACE_TYPE:
		case SYSTEM_AUDIT_OBJECT_ACE_TYPE:
		case SYSTEM_ALARM_OBJECT_ACE_TYPE:
			{
				PACCESS_ALLOWED_OBJECT_ACE pAccessAllowedAce = (PACCESS_ALLOWED_OBJECT_ACE)pAce;
				LOG(L"AceMask  is 0x%.8x, this means access permissions are:\n",pAccessAllowedAce->Mask);
				RegistryLogAceMask(pAccessAllowedAce->Mask);
				LOG(L"The above access permissions are given to following SID'S:\n");
				RegistryLogAceSidStart( &(pAccessAllowedAce->SidStart));
			}
			break;

		default:
			LOG_BASIC(L"AceType unknow\n");
			LOG(L"Don't know the ACE type, cannot parse the ACE");
			break;
		};
	}

	LOG_EXIT(iReturnCode);
	return iReturnCode;
}
Beispiel #7
0
uint8_t *fileReadAtIndex( const char *filename, uint32_t index, uint32_t *len_to_read )
{
	int f;
	uint8_t *buffer;
    int32_t size = 0 ;

	//open the file
	f = open( filename , O_RDONLY);
	if( f == -1 )
	{
		LOG_BASIC("error: open file %s!\n",filename);
		return NULL ;
	}

	buffer = (uint8_t *)malloc( *len_to_read);
	if( buffer == NULL )
	{
		LOG_ERR1("malloc");
		return NULL ;
	}

	if(lseek(f,index,SEEK_SET) == -1 )
	{
		LOG_ERR1("lseek");
		return NULL ;
	}

	//read the file and put the data in the target buffer
    if( (size = (int32_t)read( f, buffer, *len_to_read )) == -1 )
	{
		LOG_ERR1("read");
		return NULL ;
	}

	close(f);

    *len_to_read = (uint32_t)size ;

	return buffer ;
}
Beispiel #8
0
uint8_t *fileRead( const char *filename, uint32_t *len )
{
	uint32_t size ;
	uint8_t *buffer ;
	int file ;

	//open the file
	file = open(filename,O_RDONLY);
	if( file == -1 )
	{
		LOG_BASIC("error: open file %s\n", filename );
		return NULL ;
	}

	//get its size
	size=(uint32_t)getFileSize(file);

	//alloc the size to a target buffer
	buffer =(uint8_t*) malloc(size);
	if( buffer == NULL )
	{
		LOG_ERR1("malloc");
		return NULL ;
	}

	//read the file and put the data in the target buffer
	if( read( file, buffer, size ) == -1 )
	{
		LOG_ERR1("read");
		return NULL ;
	}

	//close the file
	close(file);

	*len = size ;
	return buffer;
}
Beispiel #9
0
void XAITaskListsParser::ParseTaskLists(XAIHelper* h) {
	const LuaTable* root = h->luaParser->GetRootTbl();

	std::stringstream xaiVersionStr(aiexport_getVersion());
	std::stringstream cfgVersionStr(root->GetStrVal("version", xaiVersionStr.str()));

	float xaiVersion = 0.0f; xaiVersionStr >> xaiVersion;
	float cfgVersion = 0.0f; cfgVersionStr >> cfgVersion;

	if (xaiVersion < cfgVersion) {
		LOG_BASIC(h->logger, "[XAITaskListsParser::ParseTaskLists] unknown config-file version (" << cfgVersionStr.str() << ")");
		return;
	}


	std::list<std::string> configNameKeys;
	root->GetStrTblKeys(&configNameKeys);

	// there must be at least one named configuration
	if (configNameKeys.empty()) {
		LOG_BASIC(h->logger, "[XAITaskListsParser::ParseTaskLists] no named configurations defined");
		h->SetConfig(false);
		return;
	}


	// we select the config randomly up-front from
	// the given (named) configurations, so that we
	// only have to read a single subtable
	float configWgtSum = 0.0f;
	float configPrbSum = 0.0f;

	int             rndConfigWgt = 0;
	const float     rndConfigPrb = (*h->frng)();
	const LuaTable* rndConfigTbl = 0;

	for (std::list<std::string>::const_iterator it = configNameKeys.begin(); it != configNameKeys.end(); it++) {
		rndConfigTbl = root->GetTblVal(*it);
		rndConfigWgt = rndConfigTbl->GetIntVal("weight", 0);

		if (rndConfigWgt > 0) {
			configWgtSum += rndConfigWgt;
		}
	}

	// there must be at least one named
	// configuration with non-zero weight
	if (configWgtSum <= 0) {
		LOG_BASIC(h->logger, "[XAITaskListsParser::ParseTaskLists] no configurations with positive weight defined");
		h->SetConfig(false);
		return;
	}

	for (std::list<std::string>::const_iterator it = configNameKeys.begin(); it != configNameKeys.end(); it++) {
		rndConfigTbl = root->GetTblVal(*it);
		configPrbSum += (rndConfigTbl->GetIntVal("weight", 0) / configWgtSum);

		if (configPrbSum >= rndConfigPrb) {
			LOG_BASIC(h->logger, "[XAITaskListsParser::ParseTaskLists] selected configuration \"" << (*it) << "\"");
			break;
		}
	}

	ParseConfigSections(rndConfigTbl, h);
}
Beispiel #10
0
void XAITaskListsParser::ParseAttackerConfigSection(const LuaTable* tbl, XAIHelper* h) {
	const LuaTable* attackerTaskListsTbl = tbl->GetTblVal("attackerlists");

	if (attackerTaskListsTbl == NULL) {
		LOG_BASIC(h->logger, "[XAITaskListsParser::ParseAttackerConfigSection] missing \"AttackerLists\" table");
		return;
	}

	std::list<std::string> attackers;
	std::list<std::string>::const_iterator lsit;

	attackerTaskListsTbl->GetStrTblKeys(&attackers);

	for (lsit = attackers.begin(); lsit != attackers.end(); lsit++) {
		// retrieve the item-lists for this attacker
		const LuaTable* attackerListsTbl = attackerTaskListsTbl->GetTblVal(lsit->c_str());

		if (attackerListsTbl == NULL)
			continue;

		// retrieve the index of each item-list
		std::list<int> listIndices;
		std::list<int>::const_iterator listIdxIt;
		attackerListsTbl->GetIntTblKeys(&listIndices);

		const std::string attackerDefName = *lsit;
		const UnitDef*    attackerDef     = h->rcb->GetUnitDef(attackerDefName.c_str());

		if (attackerDef == NULL)
			continue;

		attackerTaskListsMap[attackerDef->id] = std::list<XAITaskList*>();

		for (listIdxIt = listIndices.begin(); listIdxIt != listIndices.end(); listIdxIt++) {
			const LuaTable* attackList = attackerListsTbl->GetTblVal(*listIdxIt);

			if (attackList == NULL)
				continue;

			const LuaTable* listItems  = attackList->GetTblVal("items");
			const int       listWeight = attackList->GetIntVal("weight", 0);

			if (listItems == NULL)
				continue;
			if (listWeight <= 0)
				continue;

			std::list<int> itemIndices;
			listItems->GetIntTblKeys(&itemIndices);

			XAITaskList* taskList = new XAITaskList(*listIdxIt, listWeight);
			attackerTaskListsMap[attackerDef->id].push_back(taskList);

			for (std::list<int>::const_iterator itemIdxIt = itemIndices.begin(); itemIdxIt != itemIndices.end(); itemIdxIt++) {
				const LuaTable* item = listItems->GetTblVal(*itemIdxIt);

				if (item == NULL)
					continue;

				XAIAttackTaskListItem* taskListItem = new XAIAttackTaskListItem(*itemIdxIt);
					taskListItem->attackeeDefName = item->GetStrVal("attackeedef", "");

					taskListItem->repeatCount     = std::max(item->GetIntVal("repeatcount",        INT_MAX), INT_MAX);
					taskListItem->attackLimit     = std::min(item->GetIntVal("attacklimit",        INT_MAX), INT_MAX);

					taskListItem->minGroupSize    = std::max(item->GetIntVal("mingroupsize",             1),       1);
					taskListItem->maxGroupSize    = std::min(item->GetIntVal("maxgroupsize",       INT_MAX), INT_MAX);
					taskListItem->minGroupMtlCost = std::max(item->GetIntVal("mingroupmetalcost",        0),       0);
					taskListItem->maxGroupMtlCost = std::min(item->GetIntVal("maxgroupmetalcost",  INT_MAX), INT_MAX);
					taskListItem->minGroupNrgCost = std::max(item->GetIntVal("mingroupenergycost",       0),       0);
					taskListItem->maxGroupNrgCost = std::min(item->GetIntVal("maxgroupenergycost", INT_MAX), INT_MAX);

					taskListItem->minFrame        = std::max(item->GetIntVal("mingameframe",             0),       0);
					taskListItem->maxFrame        = std::min(item->GetIntVal("maxgameframe",       INT_MAX), INT_MAX);
					taskListItem->minFrameSpacing = std::max(item->GetIntVal("minframespacing",          0),       0);

				const UnitDef* attackeeDef   = h->rcb->GetUnitDef(taskListItem->attackeeDefName.c_str());
				const int      attackeeDefID = (attackeeDef != NULL)? attackeeDef->id: 0;

				taskListItem->attackeeDefID = attackeeDefID;
				taskList->AddItem(taskListItem);


				if (attackeeAttackerItems.find(attackeeDefID) == attackeeAttackerItems.end()) {
					attackeeAttackerItems[attackeeDefID] = std::set<int>();
				}

				attackeeAttackerItems[attackeeDefID].insert(attackerDef->id);
			}
		}
	}
}
Beispiel #11
0
void XAITaskListsParser::ParseBuilderConfigSection(const LuaTable* tbl, XAIHelper* h) {
	const LuaTable* builderTaskListsTbl = tbl->GetTblVal("builderlists");

	if (builderTaskListsTbl == NULL) {
		LOG_BASIC(h->logger, "[XAITaskListsParser::ParseBuilderConfigSection] missing \"BuilderLists\" table");
		return;
	}

	std::list<std::string> builders;
	std::list<std::string>::const_iterator lsit;

	builderTaskListsTbl->GetStrTblKeys(&builders);

	for (lsit = builders.begin(); lsit != builders.end(); lsit++) {
		// retrieve the item-lists for this builder
		const LuaTable* builderListsTbl = builderTaskListsTbl->GetTblVal(lsit->c_str());

		if (builderListsTbl == NULL)
			continue;

		// retrieve the index of each item-list
		std::list<int> listIndices;
		std::list<int>::const_iterator listIdxIt;
		builderListsTbl->GetIntTblKeys(&listIndices);

		const std::string builderDefName = *lsit;
		const UnitDef*    builderDef     = h->rcb->GetUnitDef(builderDefName.c_str());

		if (builderDef == NULL)
			continue;

		builderTaskListsMap[builderDef->id] = std::list<XAITaskList*>();

		for (listIdxIt = listIndices.begin(); listIdxIt != listIndices.end(); listIdxIt++) {
			const LuaTable* buildList = builderListsTbl->GetTblVal(*listIdxIt);

			if (buildList == NULL)
				continue;

			const LuaTable* listItems  = buildList->GetTblVal("items");
			const int       listWeight = buildList->GetIntVal("weight", 0);

			if (listItems == NULL)
				continue;
			if (listWeight <= 0)
				continue;

			std::list<int> itemIndices;
			listItems->GetIntTblKeys(&itemIndices);

			XAITaskList* taskList = new XAITaskList(*listIdxIt, listWeight);
			builderTaskListsMap[builderDef->id].push_back(taskList);

			for (std::list<int>::const_iterator itemIdxIt = itemIndices.begin(); itemIdxIt != itemIndices.end(); itemIdxIt++) {
				const LuaTable* item = listItems->GetTblVal(*itemIdxIt);

				if (item == NULL)
					continue;

				XAIBuildTaskListItem* taskListItem = new XAIBuildTaskListItem(*itemIdxIt);
					taskListItem->buildeeDefName = item->GetStrVal("buildeedef", "");

					// unsigned representation of -1 is ((1 << 32) - 1),
					// so such values act as positive infinity if given
					taskListItem->repeatCount     = std::max(item->GetIntVal("repeatcount",           1),       1);
					taskListItem->unitLimit       = std::min(item->GetIntVal("unitlimit",       INT_MAX), INT_MAX);
					taskListItem->buildLimit      = std::min(item->GetIntVal("buildlimit",      INT_MAX), INT_MAX);

					taskListItem->minNrgIncome    = std::max(item->GetIntVal("minenergyincome",       0),       0);
					taskListItem->maxNrgIncome    = std::min(item->GetIntVal("maxenergyincome", INT_MAX), INT_MAX);
					taskListItem->minMtlIncome    = std::max(item->GetIntVal("minmetalincome",        0),       0);
					taskListItem->maxMtlIncome    = std::min(item->GetIntVal("maxmetalincome",  INT_MAX), INT_MAX);

					taskListItem->minNrgUsage     = std::max(item->GetIntVal("minenergyusage",        0),       0);
					taskListItem->maxNrgUsage     = std::min(item->GetIntVal("maxenergyusage",  INT_MAX), INT_MAX);
					taskListItem->minMtlUsage     = std::max(item->GetIntVal("minmetalusage",         0),       0);
					taskListItem->maxMtlUsage     = std::min(item->GetIntVal("maxmetalusage",   INT_MAX), INT_MAX);

					taskListItem->minNrgLevel     = std::max(item->GetIntVal("minenergylevel",        0),       0);
					taskListItem->maxNrgLevel     = std::min(item->GetIntVal("maxenergylevel",  INT_MAX), INT_MAX);
					taskListItem->minMtlLevel     = std::max(item->GetIntVal("minmetallevel",         0),       0);
					taskListItem->maxMtlLevel     = std::min(item->GetIntVal("maxmetallevel",   INT_MAX), INT_MAX);

					taskListItem->minFrame        = std::max(item->GetIntVal("mingameframe",          0),       0);
					taskListItem->maxFrame        = std::min(item->GetIntVal("maxgameframe",    INT_MAX), INT_MAX);
					taskListItem->minFrameSpacing = std::max(item->GetIntVal("minframespacing",       0),       0);
					taskListItem->forceBuild      =          item->GetIntVal("forcestartbuild",       0);

				const UnitDef* buildeeDef   = h->rcb->GetUnitDef(taskListItem->buildeeDefName.c_str());
				const int      buildeeDefID = (buildeeDef != NULL)? buildeeDef->id: 0;

				taskListItem->buildeeDefID = buildeeDefID;
				taskList->AddItem(taskListItem);


				if (buildeeBuilderItems.find(buildeeDefID) == buildeeBuilderItems.end()) {
					buildeeBuilderItems[buildeeDefID] = std::set<int>();
				}

				buildeeBuilderItems[buildeeDefID].insert(builderDef->id);
			}
		}
	}
}
Beispiel #12
0
void ScriptMgr::DumpUnimplementedSpells()
{
	std::ofstream of;

	LOG_BASIC("Dumping IDs for spells with unimplemented dummy/script effect(s)");
	uint32 count = 0;

	of.open("unimplemented1.txt");

	for(DBCStorage< SpellEntry >::iterator itr = dbcSpell.begin(); itr != dbcSpell.end(); ++itr)
	{
		SpellEntry* sp = *itr;

		if(!sp->HasEffect(SPELL_EFFECT_DUMMY) && !sp->HasEffect(SPELL_EFFECT_SCRIPT_EFFECT) && !sp->HasEffect(SPELL_EFFECT_SEND_EVENT))
			continue;

		HandleDummySpellMap::iterator sitr = _spells.find(sp->Id);
		if(sitr != _spells.end())
			continue;

		HandleScriptEffectMap::iterator seitr = SpellScriptEffects.find(sp->Id);
		if(seitr != SpellScriptEffects.end())
			continue;

		std::stringstream ss;
		ss << sp->Id;
		ss << std::endl;

		of.write(ss.str().c_str(), ss.str().length());

		count++;
	}

	of.close();

	LOG_BASIC("Dumped %u IDs.", count);

	LOG_BASIC("Dumping IDs for spells with unimplemented dummy aura effect.");

	std::ofstream of2;
	of2.open("unimplemented2.txt");

	count = 0;

	for(DBCStorage< SpellEntry >::iterator itr = dbcSpell.begin(); itr != dbcSpell.end(); ++itr)
	{
		SpellEntry* sp = *itr;

		if(!sp->AppliesAura(SPELL_AURA_DUMMY))
			continue;

		HandleDummyAuraMap::iterator ditr = _auras.find(sp->Id);
		if(ditr != _auras.end())
			continue;

		std::stringstream ss;
		ss << sp->Id;
		ss << std::endl;

		of2.write(ss.str().c_str(), ss.str().length());

		count++;
	}

	of2.close();

	LOG_BASIC("Dumped %u IDs.", count);
}
Beispiel #13
0
void ScriptMgr::LoadScripts()
{
	if(HookInterface::getSingletonPtr() == NULL)
		new HookInterface;

	Log.Success("Server", "Loading External Script Libraries...");

	std::string Path;
	std::string FileMask;
	Path = PREFIX;
	Path += '/';
#ifdef WIN32
	/*Path = Config.MainConfig.GetStringDefault( "Script", "BinaryLocation", "script_bin" );
	Path += "\\";*/
	FileMask = ".dll";
#else
#ifndef __APPLE__
	FileMask = ".so";
#else
	FileMask = ".dylib";
#endif
#endif

	Arcpro::FindFilesResult findres;
	std::vector< ScriptingEngine_dl > Engines;

	Arcpro::FindFiles(Path.c_str(), FileMask.c_str(), findres);
	uint32 count = 0;

	while(findres.HasNext())
	{
		std::stringstream loadmessage;
		std::string fname = Path + findres.GetNext();
		Arcpro::DynLib* dl = new Arcpro::DynLib(fname.c_str());

		loadmessage << "  " << dl->GetName() << " : ";

		if(!dl->Load())
		{
			loadmessage << "ERROR: Cannot open library.";
			LOG_ERROR(loadmessage.str().c_str());
			delete dl;
			continue;

		}
		else
		{
			exp_get_version vcall     = reinterpret_cast< exp_get_version >(dl->GetAddressForSymbol("_exp_get_version"));
			exp_script_register rcall = reinterpret_cast< exp_script_register >(dl->GetAddressForSymbol("_exp_script_register"));
			exp_get_script_type scall = reinterpret_cast< exp_get_script_type >(dl->GetAddressForSymbol("_exp_get_script_type"));

			if((vcall == NULL) || (rcall == NULL) || (scall == NULL))
			{
				loadmessage << "ERROR: Cannot find version functions.";
				LOG_ERROR(loadmessage.str().c_str());
				delete dl;
				continue;
			}
			else
			{
				const char *version = vcall();
				uint32 stype = scall();

				if( strcmp( version, BUILD_HASH_STR ) != 0 )
				{
					loadmessage << "ERROR: Version mismatch.";
					LOG_ERROR(loadmessage.str().c_str());
					delete dl;
					continue;

				}
				else
				{
					loadmessage << ' ' << std::string( BUILD_HASH_STR ) << " : ";

					if((stype & SCRIPT_TYPE_SCRIPT_ENGINE) != 0)
					{
						ScriptingEngine_dl se;

						se.dl = dl;
						se.InitializeCall = rcall;
						se.Type = stype;

						Engines.push_back(se);

						loadmessage << "delayed load";

					}
					else
					{
						rcall(this);
						dynamiclibs.push_back(dl);

						loadmessage << "loaded";
					}
					LOG_BASIC(loadmessage.str().c_str());
					count++;
				}
			}
		}
	}

	if(count == 0)
	{
		LOG_ERROR("  No external scripts found! Server will continue to function with limited functionality.");
	}
	else
	{
		Log.Success("Server", "Loaded %u external libraries.", count);
		Log.Success("Server", "Loading optional scripting engine(s)...");

		for(std::vector< ScriptingEngine_dl >::iterator itr = Engines.begin(); itr != Engines.end(); ++itr)
		{
			itr->InitializeCall(this);
			dynamiclibs.push_back(itr->dl);
		}

		Log.Success("Server", "Done loading scripting engine(s)...");
	}
}
Beispiel #14
0
void AuthSocket::HandleChallenge()
{
	// No header
	if(readBuffer.GetContiguiousBytes() < 4){
		LOG_ERROR( "[AuthChallenge] Packet has no header. Refusing to handle." );
		return;
	}

	// Check the rest of the packet is complete.
	uint8 * ReceiveBuffer = (uint8*)readBuffer.GetBufferStart();

	uint16 full_size = *(uint16*)&ReceiveBuffer[2];


	LOG_DETAIL("[AuthChallenge] got header, body is %u bytes", full_size );

	if(readBuffer.GetSize() < uint32(full_size+4)){
		LOG_ERROR( "[AuthChallenge] Packet is smaller than expected, refusing to handle" );
		return;
	}

	// Copy the data into our cached challenge structure
	if(full_size > sizeof(sAuthLogonChallenge_C_BattleNet))
	{
		LOG_ERROR( "[AuthChallenge] Packet is larger than expected, refusing to handle!" );
		Disconnect();
		return;
	}

	LOG_DEBUG("[AuthChallenge] got a complete packet.");

	//memcpy(&m_challenge, ReceiveBuffer, full_size + 4);
	//RemoveReadBufferBytes(full_size + 4, true);
	readBuffer.Read(&m_challenge, full_size + 4);

	// Check client build.

	uint16 build = m_challenge.build;

	// Check client build.
	if(build > LogonServer::getSingleton().max_build)
	{
		// wtf?
		LOG_DETAIL( "[AuthChallenge] Client %s has wrong version. More up to date than server. Server: %u, Client: %u", GetRemoteIP().c_str(), LogonServer::getSingleton().max_build, m_challenge.build );
		SendChallengeError(CE_WRONG_BUILD_NUMBER);
		return;
	}

	if(build < LogonServer::getSingleton().min_build)
	{
		// can we patch?
		char flippedloc[5] = {0,0,0,0,0};
		flippedloc[0] = m_challenge.country[3];
		flippedloc[1] = m_challenge.country[2];
		flippedloc[2] = m_challenge.country[1];
		flippedloc[3] = m_challenge.country[0];

		m_patch = PatchMgr::getSingleton().FindPatchForClient(build, flippedloc);
		if(m_patch == NULL)
		{
			// could not find a valid patch
			LOG_DETAIL( "[AuthChallenge] Client %s has wrong version. More up to date than server. Server: %u, Client: %u", GetRemoteIP().c_str(), LogonServer::getSingleton().min_build, m_challenge.build );
			SendChallengeError(CE_WRONG_BUILD_NUMBER);
			return;
		}

		Log.Debug("Patch", "Selected patch %u%s for client.", m_patch->Version,m_patch->Locality);


		uint8 response[119] = {
			0x00, 0x00, 0x00, 0x72, 0x50, 0xa7, 0xc9, 0x27, 0x4a, 0xfa, 0xb8, 0x77, 0x80, 0x70, 0x22,
			0xda, 0xb8, 0x3b, 0x06, 0x50, 0x53, 0x4a, 0x16, 0xe2, 0x65, 0xba, 0xe4, 0x43, 0x6f, 0xe3,
			0x29, 0x36, 0x18, 0xe3, 0x45, 0x01, 0x07, 0x20, 0x89, 0x4b, 0x64, 0x5e, 0x89, 0xe1, 0x53,
			0x5b, 0xbd, 0xad, 0x5b, 0x8b, 0x29, 0x06, 0x50, 0x53, 0x08, 0x01, 0xb1, 0x8e, 0xbf, 0xbf,
			0x5e, 0x8f, 0xab, 0x3c, 0x82, 0x87, 0x2a, 0x3e, 0x9b, 0xb7, 0x00, 0x00, 0x00, 0x00, 0x00,
			0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
			0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe1, 0x32, 0xa3,
			0x49, 0x76, 0x5c, 0x5b, 0x35, 0x9a, 0x93, 0x3c, 0x6f, 0x3c, 0x63, 0x6d, 0xc0, 0x00
		};
		Send(response, 119);
		return;
	}

	// Check for a possible IP ban on this client.
	BAN_STATUS ipb = IPBanner::getSingleton().CalculateBanStatus(GetRemoteAddress());

	if( ipb != BAN_STATUS_NOT_BANNED )
		LOG_DETAIL( "[AuthChallenge] Client %s is banned, refusing to continue.", GetRemoteIP().c_str() );

	switch(ipb)
	{
		case BAN_STATUS_PERMANENT_BAN:
			SendChallengeError(CE_ACCOUNT_CLOSED);
			return;

		case BAN_STATUS_TIME_LEFT_ON_BAN:
			SendChallengeError(CE_ACCOUNT_FREEZED);
			return;

		default:
			break;
	}

	// Null-terminate the account string
	if(m_challenge.I_len >= 50) { Disconnect(); return; }
	m_challenge.I[m_challenge.I_len] = 0;

	// Clear the shitty hash (for server)
	string AccountName = (char*)&m_challenge.I;
	if (AccountName.substr(0, 1) == "?")
	{
		if (AccountName.find_first_not_of("ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789?") != string::npos)
		{
			LOG_ERROR("[AuthChallenge]: Tried to create account with illegal characters.");
			SendChallengeError(CE_NO_ACCOUNT); //Well f**k you for editing the files!
			return;
		}

		int pass_start = AccountName.find("?", 1) + 1;
		if (pass_start < 4) //No username
		{
			LOG_ERROR("[AuthChallenge] Tried to create account with no account name.");
			SendChallengeError(CE_NO_ACCOUNT);
			return;
		}

		int pass_end = AccountName.rfind("?");
		if (pass_end <= pass_start) //No password
		{
			LOG_ERROR("[AuthChallenge] Tried to create account with no password.");
			SendChallengeError(CE_NO_ACCOUNT);
			return;
		}

		int name_len = pass_start - 2;
		int pass_len = pass_end - pass_start;
		string username = AccountName.substr(1, name_len);
		string password = AccountName.substr(pass_start, pass_len);

		m_account = AccountMgr::getSingleton().GetAccount(username);
		if (m_account != 0)
		{
			LOG_ERROR("[AuthChallenge] Account creation failed: account name already taken.");
			SendChallengeError(CE_ACCOUNT_IN_USE);
			return;
		}

		string cmd = username + " " + password + " NULL"; //Prepare command for CreateAccount
		char acct[50];

		memcpy(acct, cmd.c_str(), 50); //CreateAccount doesn't take const char*
		LogonConsole::getSingleton().CreateAccount(acct);
		SendChallengeError(CE_SERVER_FULL); //Success!
		LOG_BASIC("[AuthChallenge] Client %s has created an account with name: \"%s\"", GetRemoteIP().c_str(), username.c_str());
		return;
	}

	if (AccountName.substr(0, 1) == "&")
	{
		if (AccountName.find_first_not_of("ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789?.~&_-") != string::npos)
		{
			LOG_ERROR("[AuthChallenge]: Tried to update account with illegal chars. %s", AccountName.c_str());
			SendChallengeError(CE_NO_ACCOUNT); //Well f**k you for editing the files!
			return;
		}

		int pass_start = AccountName.find("&", 1) + 1;
		if (pass_start < 4) //No username
		{
			LOG_ERROR("[AuthChallenge] Tried to update account with no account name.");
			SendChallengeError(CE_NO_ACCOUNT);
			return;
		}

		int pass_end = AccountName.rfind("&");
		if (pass_end <= pass_start) //No password
		{
			LOG_ERROR("[AuthChallenge] Tried to update account with no email.");
			SendChallengeError(CE_NO_ACCOUNT);
			return;
		}

		int name_len = pass_start - 2;
		int pass_len = pass_end - pass_start;
		string username = AccountName.substr(1, name_len);
		string email = AccountName.substr(pass_start, pass_len);

		for (uint8 i = 0; i < email.length(); i++)
		{
			if (email[i] == '~')
			{
				email[i] = '@';
				break;
			}
		}

		m_account = AccountMgr::getSingleton().GetAccount(username);
		if (m_account == 0)
		{
			LOG_ERROR("[AuthChallenge] Account update failed: account does not exist.");
			SendChallengeError(CE_ACCOUNT_IN_USE);
			return;
		}

		std::stringstream query;
		query << "UPDATE `accounts` SET `email` = '" << email << "' WHERE `login` = '" << username << "' AND `email` = 'NULL';";

		sLogonSQL->WaitExecuteNA(query.str().c_str());

		SendChallengeError(CE_SERVER_FULL); //Success!
		return;
	}

	string::size_type i = AccountName.rfind("#");
	if( i != string::npos )
	{
		LOG_ERROR("# ACCOUNTNAME!");
		return;
		//AccountName.erase( i );
	}

	// Look up the account information
	LOG_DEBUG("[AuthChallenge] Account Name: \"%s\"", AccountName.c_str());

	m_account = AccountMgr::getSingleton().GetAccount(AccountName);
	if(m_account == 0)
	{
		LOG_DEBUG("[AuthChallenge] Invalid account.");

		// Non-existant account
		SendChallengeError(CE_NO_ACCOUNT);
		return;
	}

	LOG_DEBUG("[AuthChallenge] Account banned state = %u", m_account->Banned);

	// Check that the account isn't banned.
	if(m_account->Banned == 1)
	{
		SendChallengeError(CE_ACCOUNT_CLOSED);
		return;
	}
	else if(m_account->Banned > 0)
	{
		SendChallengeError(CE_ACCOUNT_FREEZED);
		return;
	}

	// update cached locale
	if(!m_account->forcedLocale)
	{
		char temp[4];
		temp[0] = m_challenge.country[3];
		temp[1] = m_challenge.country[2];
		temp[2] = m_challenge.country[1];
		temp[3] = m_challenge.country[0];

		*(uint32*)&m_account->Locale[0] = *(uint32*)temp;
	}

	//////////////////////////////////////////////// SRP6 Challenge ////////////////////////////////////////////////
	//
	//
	// First we will generate the Verifier value using the following formulas
	//
	// x = SHA1(s | SHA1(I | ":" | P))
	// v = g^x % N
	//
	// The SHA1(I | ":" | P) part for x we have in the account database, this is the encrypted password, reversed
	// N is a safe prime
	// g is the generator
	// | means concatenation in this contect
	//
	//

	Sha1Hash sha;
	sha.UpdateData( s.AsByteArray(), 32 );
	sha.UpdateData( m_account->SrpHash, 20 );
	sha.Finalize();

	BigNumber x;
	x.SetBinary( sha.GetDigest(), sha.GetLength() );
	v = g.ModExp(x, N);

	// Next we generate b, and B which are the public and private values of the server
	// 
	// b = random()
	// B = k*v + g^b % N
	//
	// in our case the multiplier parameters, k = 3
	
	b.SetRand(152);
	uint8 k = 3;

	BigNumber gmod = g.ModExp(b, N);
	B = ( ( v * k ) + gmod ) % N;
	ASSERT(gmod.GetNumBytes() <= 32);

	BigNumber unk;
	unk.SetRand(128);


	// Now we send B, g, N and s to the client as a challenge, asking the client for the proof
	sAuthLogonChallenge_S challenge;
	challenge.cmd = 0;
	challenge.error = 0;
	challenge.unk2 = CE_SUCCESS;
	memcpy( challenge.B, B.AsByteArray(), 32 );
	challenge.g_len = 1;
	challenge.g = ( g.AsByteArray() )[ 0 ];
	challenge.N_len = 32;
	memcpy( challenge.N, N.AsByteArray(), 32 );
	memcpy( challenge.s, s.AsByteArray(), 32 );
	memcpy( challenge.unk3, unk.AsByteArray(), 16 );
	challenge.unk4 = 0;

	Send( reinterpret_cast< uint8* >( &challenge ), sizeof( sAuthLogonChallenge_S ) );
}
Beispiel #15
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();
}
Beispiel #16
0
void LogonServer::Run(int argc, char** argv)
{
	m_stopEvent = false;
	UNIXTIME = time(NULL);
	g_localTime = *localtime(&UNIXTIME);
	int file_log_level = DEF_VALUE_NOT_SET;
	int screen_log_level = DEF_VALUE_NOT_SET;
	int do_check_conf = 0;

	sLog.Init(0, LOGON_LOG);
	sLog.outBasic(BANNER, BUILD_TAG, BUILD_HASH_STR, CONFIG, PLATFORM_TEXT, ARCH);
	sLog.outError(BANNER, BUILD_TAG, BUILD_HASH_STR, CONFIG, PLATFORM_TEXT, ARCH);
	/* set new log levels */
	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...");
	
	/** @brief 初始化配置 */
	char* config_file = (char*)CONFDIR "/logon.conf";
	if(!Config.SetSource(config_file))
	{
		LOG_ERROR("Config file could not be rehashed.");
		return;
	}
	/** @brief 加载配置 */ 
	string host = Config.Value("Listen", "Host", "0.0.0.0");
	int cport = Config.Value("Listen", "Port", 8093);

	Log.Success("线程管理", "开始启动...");
	/** @brief 启动线程池 */
	ThreadPool.Startup();
	ThreadPool.ShowStats();

//	// Spawn periodic function caller thread for account reload every 10mins
//	// 线程周期函数每10钟重新加载用户进内存
//	int atime = Config.MainConfig.GetIntDefault("Rates", "AccountRefresh", 600);
//	atime *= 1000;
//	PeriodicFunctionCaller<AccountMgr> * pfc = new PeriodicFunctionCaller<AccountMgr>(AccountMgr::getSingletonPtr(), &AccountMgr::ReloadAccountsCallback, atime,"AccountMgr");
//	ThreadPool.ExecuteTask(pfc);//线程池执行这个任务

	min_build = LOGON_MINBUILD;
	max_build = LOGON_MAXBUILD;

	SocketMgr* socketObject = NULL;
	Macro_NewClass(socketObject,SocketMgr);
	SocketGarbageCollector* socketGCObject = NULL;
	Macro_NewClass(socketGCObject,SocketGarbageCollector);/**< 垃圾回收  */
	
	IntranetManager* intranetObject = NULL;
	Macro_NewClass(intranetObject,IntranetManager);
	InitSelfInfo();
	AddCacheServer();
	sIntranetMgr.Startup();

	ListenSocket<AuthSocket> * cl = new ListenSocket<AuthSocket>(host.c_str(), cport,"AuthSocket");
	ListenSocket<LogonCommServerSocket> * sl = new ListenSocket<LogonCommServerSocket>(host.c_str(), cport,"LogonCommServerSocket");
	/** @brief 生成套接字工作线程 */
	sSocketMgr.SpawnWorkerThreads();

	/** @brief 生成验证的网络监听者 */
	bool authsockcreated = cl->IsOpen();
	bool intersockcreated = sl->IsOpen();
	if(authsockcreated && intersockcreated)
	{
#ifdef WIN32
		ThreadPool.ExecuteTask(cl);
		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

		/** @brief 当前进程ID存到文本文件 */
		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! 等待连接...");
		while(mrunning.GetVal() && !m_stopEvent)
		{
			if(!(++loop_counter % 20))	 /**<  20 seconds */ 
				CheckForDeadSockets();   /**<  检查AuthSocket死掉的连接 */

			if(!(loop_counter % 300))	/**< 5mins  */ 
				ThreadPool.IntegrityCheck();/**< 线程池线程数和压力检查  */

			if(!(loop_counter % 5))
			{
				//sInfoCore.TimeoutSockets();/**< 检查LogonCommServerSocket超时的连接  */
				sSocketGarbageCollector.Update();
				CheckForDeadSockets();			  /**<  Flood Protection */ 
				UNIXTIME = time(NULL);
				g_localTime = *localtime(&UNIXTIME);
			}

			MCodeNet::Sleep(1000);
		}

		sLog.outString("开始关闭清空...");
		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...");
	}
/////////////////////////////////开始回收///////////////////////////////////////////

	cl->Close();
	sl->Close();
	sSocketMgr.CloseAll();
#ifdef WIN32
	sSocketMgr.ShutdownThreads();
#endif

	ThreadPool.Shutdown();

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

	Macro_DeleteClass(IntranetManager::getSingletonPtr(),IntranetManager);
	Macro_DeleteClass(SocketMgr::getSingletonPtr(),SocketMgr);
	Macro_DeleteClass(SocketGarbageCollector::getSingletonPtr(),SocketGarbageCollector);
	delete cl;
	delete sl;
	LOG_BASIC("关闭清空...完成.");
	sLog.Close();
}