Ejemplo n.º 1
0
//monitor the submitted tasks
// by polling each server for its load information. If a server is idle then it will return load = -4 (queue length - num of idle cores)
// so if every server returns load = -4 it implies that all submitted tasks are complete
void *monitor_function(void* args) {

	ZHTClient *clientRet = (ZHTClient*)args;
	
	Package loadPackage, loadhpcPackage, shutdownPackage;	
	string loadmessage("Monitoring Information!");
	loadPackage.set_virtualpath(loadmessage);
	loadPackage.set_operation(15);
	string loadstr = loadPackage.SerializeAsString();

	string loadhpcmessage("Monitoring HPC Information!");
        loadhpcPackage.set_virtualpath(loadhpcmessage);
        loadhpcPackage.set_operation(24);
        string loadhpcstr = loadhpcPackage.SerializeAsString();

	string endmessage("Shutdown!");
	loadPackage.set_virtualpath(endmessage);
	loadPackage.set_operation(98);
	string endstr = loadPackage.SerializeAsString();

	//int num_worker = clientRet.memberList.size();
	int num_worker = clientRet->memberList.size();
	int num_cores = 2;
	int index = 0;
	long termination_value = num_worker * num_cores * -1;

	int total_avail_cores = num_cores * num_worker;

	int32_t total_queued = 0;
	int32_t total_idle = 0;
	int32_t queued_busy = 0;

	int32_t queued_idle = 0;
	int32_t queued = 0;
	int32_t num_idle = 0;
	int32_t num_busy = 0;
	int32_t load = 0;
	int32_t total_busy = 0;
	//int32_t status = 0;
	int32_t finished = 0;

	int32_t total_msg_count = 0;
	int32_t ret = 0;
	//sleep(60);

	int min_lines = num_worker;
	int num = num_worker - 1;
	cout << "The Number is " << num << endl;
	stringstream num_ss;
	num_ss << num;
	//min_lines++;


	string filename(shared);
        filename = filename + "startinfo" + num_ss.str();
	cout << "The filename is " << filename << endl;
        string cmd("cat ");
        cmd = cmd + filename + " | wc -l";

	cout << "The command is " << cmd << endl;
        string result = executeShell(cmd);
	//cout << cmd << " " << result << endl;
	//cout << "client: minlines = " << min_lines << " cmd = " << cmd << " result = " << result << endl;
	/*string filename(shared);
	filename = filename + "start_info";
	string cmd("wc -l ");
	cmd = cmd + filename + " | awk {\'print $1\'}";
	string result = executeShell(cmd);*/
	
	while(atoi(result.c_str()) < 1) {
		sleep(5);
		result = executeShell(cmd); cout << " temp result = " << result << endl;
	} 
	cout << "client: minlines = 1 " << " cmd = " << cmd << " result = " << result << endl;
	//cout << "starting to monitor" << endl;
	cout << "TIME START: " << start_tasks.tv_sec << "  SECONDS  " << start_tasks.tv_nsec << "  NANOSECONDS" << endl;
	while(1) {

	//If mtc task or only complete queue values are taken 
	if(NUM_OF_CORES == 1)
	{
		total_queued = 0;
		total_idle = 0;
		queued_busy = 0;

		stringstream worker_load;
		for(index = 0; index < num_worker; index++) {
                        //int32_t queued_idle = clientRet.svrtosvr(loadstr, loadstr.length(), index);
			queued_idle = clientRet->svrtosvr(loadstr, loadstr.length(), index);
                        queued  = queued_idle/10;  // summation of the lengths of the three queues
                        num_idle = queued_idle%10;   // number of idle cores
                        total_queued = total_queued + queued;
                        total_idle   = total_idle + num_idle;
			num_busy = num_cores - num_idle;
			load = queued + num_busy;
			worker_load << load << " ";                 
                }
		loadfile << worker_load.str() << endl;
		total_busy = total_avail_cores - total_idle;
		queued_busy = total_queued + total_busy;
		finished = total_num_tasks - queued_busy;
		clock_gettime(CLOCK_REALTIME, &end_tasks);
		cout << "Total busy cores " << total_busy << " Total Load on all workers = " << queued_busy << " No. of tasks finished = " << finished << " Total tasks submitted = " << total_num_tasks << endl;//" time = " << end_tasks.tv_sec << " " << end_tasks.tv_nsec << endl;
		if (client_logfile.is_open() && cl_LOGGING) {
			client_logfile << "Total busy cores " << total_busy << "  Total Load on all workers = " << queued_busy << " No. of tasks finished = " << finished << " Total tasks submitted = " << total_num_tasks << endl;
		}
                if(finished == total_num_tasks) {

                        clock_gettime(CLOCK_REALTIME, &end_tasks);
                        cout << "\n\n\n\n==============================All tasks finished===========================\n\n\n\n";
                        break;
                }

		usleep(200000);
	}
	else
	{
		finished = 0;
		for(index = 0; index < num_worker; index++) 
		{
			finished += clientRet->svrtosvr(loadhpcstr, loadhpcstr.length(), index);
		}
		cout << "The number of finished tasks = " << finished << endl;
		if(finished >= total_num_tasks-50) {

                        clock_gettime(CLOCK_REALTIME, &end_tasks);
                        cout << "\n\n\n\n==============================All tasks finished===========================\n\n\n\n";
                        break;
                }

                usleep(200000);
	}
	}

	total_msg_count = 0;
	for(index = 0; index < num_worker; index++) {
		//clientRet.svrtosvr(endstr, endstr.length(), index);
		ret = clientRet->svrtosvr(endstr, endstr.length(), index);
		total_msg_count += ret;
	}

	cout << "TIME START: " << start_tasks.tv_sec << "  SECONDS  " << start_tasks.tv_nsec << "  NANOSECONDS" << "\n";
	cout << "TIME END: " << end_tasks.tv_sec << "  SECONDS  " << end_tasks.tv_nsec << "  NANOSECONDS" << "\n";
	timespec diff = timediff(start_tasks, end_tasks);
	cout << "TIME TAKEN: " << diff.tv_sec << "  SECONDS  " << diff.tv_nsec << "  NANOSECONDS" << "\n";
	cout << "Total messages between all servers = " << total_msg_count << endl;
	if (client_logfile.is_open() && cl_LOGGING) {		

		client_logfile << "\n\n\n\n==============================All tasks finished===========================\n\n\n\n";
		client_logfile << "TIME START: " << start_tasks.tv_sec << "  SECONDS  " << start_tasks.tv_nsec << "  NANOSECONDS" << "\n";
		client_logfile << "TIME END: " << end_tasks.tv_sec << "  SECONDS  " << end_tasks.tv_nsec << "  NANOSECONDS" << "\n";
		client_logfile << "TIME TAKEN: " << diff.tv_sec << "  SECONDS  " << diff.tv_nsec << "  NANOSECONDS" << endl;
		client_logfile << "Total messages between all servers = " << total_msg_count << endl;

		client_logfile.close();
		//return 1;
	}
	pthread_exit(NULL);
}
Ejemplo n.º 2
0
//monitor the submitted tasks
// by polling each server for its load information. If a server is idle then it will return load = -4 (queue length - num of idle cores)
// so if every server returns load = -4 it implies that all submitted tasks are complete
void *monitor_function(void* args) {

	ZHTClient *clientRet = (ZHTClient*)args;
	
	Package loadPackage, shutdownPackage;	
	string loadmessage("Monitoring Information!");
	loadPackage.set_virtualpath(loadmessage);
	loadPackage.set_operation(15);
	string loadstr = loadPackage.SerializeAsString();

	string endmessage("Shutdown!");
	loadPackage.set_virtualpath(endmessage);
	loadPackage.set_operation(98);
	string endstr = loadPackage.SerializeAsString();

	//int num_worker = clientRet.memberList.size();
	int num_worker = clientRet->memberList.size();
	int num_cores = ncores;
	int index = 0;
	long termination_value = num_worker * num_cores * -1;

	int total_avail_cores = num_cores * num_worker;

	int32_t total_queued = 0;
	int32_t total_idle = 0;
	int32_t queued_busy = 0;

	int32_t queued_idle = 0;
	int32_t queued = 0;
	int32_t num_idle = 0;
	int32_t num_busy = 0;
	int32_t load = 0;
	int32_t total_busy = 0;
	//int32_t status = 0;
	int32_t finished = 0;

	int32_t total_msg_count = 0;
	int32_t ret = 0;
	//sleep(60);

	int min_lines = num_worker;
	int num = num_worker - 1;
	stringstream num_ss;
	num_ss << num;

	long num_monitor = 0;
	//min_lines++;

	// not sure why we need this
	string filename(shared);
        filename = filename + "startinfo" + num_ss.str();
        string cmd("cat ");
        cmd = cmd + filename + " | wc -l";
        string result = executeShell(cmd);
	cout << cmd << " " << result << endl;
	//cout << "client: minlines = " << min_lines << " cmd = " << cmd << " result = " << result << endl;
	/*string filename(shared);
	filename = filename + "start_info";
	string cmd("wc -l ");
	cmd = cmd + filename + " | awk {\'print $1\'}";
	string result = executeShell(cmd);*/
	
	while(atoi(result.c_str()) < 1) {
		usleep(minterval);
		result = executeShell(cmd); cout << " temp result = " << result << endl;
	}
	cout << "client: minlines = 1 " << " cmd = " << cmd << " result = " << result << endl;
	//cout << "starting to monitor" << endl;
	cout << "TIME START: " << start_tasks.tv_sec << "  SECONDS  " << start_tasks.tv_nsec << "  NANOSECONDS" << endl;
	timespec local_start, local_diff;
	clock_gettime(CLOCK_REALTIME, &local_start);
	local_diff = timediff(start_tasks, local_start);
	if (client_logfile.is_open() && cl_LOGGING) {
			client_logfile << "Submission time: " << start_tasks.tv_sec << "  SECONDS  " << start_tasks.tv_nsec << "  NANOSECONDS" << endl;
			client_logfile << "Monitoring time: " << local_start.tv_sec << "  SECONDS  " << local_start.tv_nsec << "  NANOSECONDS" << endl;
			client_logfile << "TIME TAKEN: " << local_diff.tv_sec << "  SECONDS  " << local_diff.tv_nsec << "  NANOSECONDS" << endl;
		}
	int total_fin = 0;
	while(1) {

//		total_queued = 0;
//		total_idle = 0;
//		queued_busy = 0;
		total_fin = 0;
		stringstream worker_load;
		for(index = 0; index < num_worker; index++) {
                        //int32_t queued_idle = clientRet.svrtosvr(loadstr, loadstr.length(), index);
			queued_idle = clientRet->svrtosvr(loadstr, loadstr.length(), index);
//                        queued  = queued_idle/10;  // summation of the lengths of the three queues
//                        num_idle = queued_idle%10;   // number of idle cores
//                        total_queued = total_queued + queued;
//                        total_idle   = total_idle + num_idle;
//			num_busy = num_cores - num_idle;
//			load = queued + num_busy;
			total_fin += queued_idle;
//			worker_load << load << " ";
			worker_load << queued_idle << " ";
                }
//		loadfile << worker_load.str() << endl;
//		total_busy = total_avail_cores - total_idle;
//		queued_busy = total_queued + total_busy;
//		finished = total_num_tasks - queued_busy;
		num_monitor++;
		clock_gettime(CLOCK_REALTIME, &end_tasks);
		//cout << "Total busy cores " << total_busy << " Total Load on all workers = " << queued_busy << " No. of tasks finished = " << finished << " Total tasks submitted = " << total_num_tasks << endl;//" time = " << end_tasks.tv_sec << " " << end_tasks.tv_nsec << endl;
		if (client_logfile.is_open() && cl_LOGGING) {
//			client_logfile << "Total busy cores " << total_busy << "  Total Load on all workers = " << queued_busy << " No. of tasks finished = " << finished << " Total tasks submitted = " << total_num_tasks << endl;
			//client_logfile << "No. of tasks finished is:" << total_fin <<", No. of tasks submitted is:" << total_num_tasks << endl;
		}
//                if(finished == total_num_tasks)
                if (total_fin == total_num_tasks)
                {

                        clock_gettime(CLOCK_REALTIME, &end_tasks);
                        cout << "\n\n\n\n==============================All tasks finished===========================\n\n\n\n";
                        break;
                }

		usleep(minterval);
	}

	total_msg_count = 0;
	for(index = 0; index < num_worker; index++) {
		//clientRet.svrtosvr(endstr, endstr.length(), index);
		ret = clientRet->svrtosvr(endstr, endstr.length(), index);
		total_msg_count += ret;
	}

	cout << "TIME START: " << start_tasks.tv_sec << "  SECONDS  " << start_tasks.tv_nsec << "  NANOSECONDS" << "\n";
	cout << "TIME END: " << end_tasks.tv_sec << "  SECONDS  " << end_tasks.tv_nsec << "  NANOSECONDS" << "\n";
	timespec diff = timediff(start_tasks, end_tasks);
	cout << "TIME TAKEN: " << diff.tv_sec << "  SECONDS  " << diff.tv_nsec << "  NANOSECONDS" << "\n";
	cout << "Total messages between all servers = " << total_msg_count << endl;
	if (client_logfile.is_open() && cl_LOGGING) {		

		client_logfile << "\n\n\n\n==============================All tasks finished===========================\n\n\n\n";
		client_logfile << "TIME START: " << start_tasks.tv_sec << "  SECONDS  " << start_tasks.tv_nsec << "  NANOSECONDS" << "\n";
		client_logfile << "TIME END: " << end_tasks.tv_sec << "  SECONDS  " << end_tasks.tv_nsec << "  NANOSECONDS" << "\n";
		client_logfile << "TIME TAKEN: " << diff.tv_sec << "  SECONDS  " << diff.tv_nsec << "  NANOSECONDS" << endl;
		client_logfile << "Total messages between all servers = " << total_msg_count << endl;
		client_logfile << "Total monitoring times is = " << num_monitor << endl;
		client_logfile.flush();
		client_logfile.close();
		if (loadfile.is_open())
		{
			loadfile.flush();
			loadfile.close();
		}
		//return 1;
	}
	pthread_exit(NULL);
}
Ejemplo n.º 3
0
void CConsole::Process( int c )
{
	char outputline[128], temp[1024];
	bool kill		= false;
	int indexcount	= 0;
	int j;
	int keyresp;
	CSocket *tSock	= NULL;

	if( c == '*' )
	{
		if( cwmWorldState->GetSecure() )
			messageLoop << "Secure mode disabled. Press ? for a commands list";
		else
			messageLoop << "Secure mode re-enabled";
		cwmWorldState->SetSecure( !cwmWorldState->GetSecure() );
		return;
	} 
	else 
	{
		if( cwmWorldState->GetSecure() )
		{
			messageLoop << "Secure mode prevents keyboard commands! Press '*' to disable";
			return;
		}
		
		JSCONSOLEKEYMAP_ITERATOR toFind = JSKeyHandler.find( c );
		if( toFind != JSKeyHandler.end() )
		{
			if( toFind->second.isEnabled )
			{
				cScript *toExecute = JSMapping->GetScript( toFind->second.scriptID );
				if( toExecute != NULL )
				{	// All commands that execute are of the form: command_commandname (to avoid possible clashes)
	#if defined( UOX_DEBUG_MODE )
					Print( "Executing JS keystroke %c %s\n", c, toFind->second.cmdName.c_str() );
	#endif
					toExecute->CallParticularEvent( toFind->second.cmdName.c_str(), NULL, 0 );
				}
				return;
			}
		}
		switch( c )
		{
			case '!':
				// Force server to save accounts file
				messageLoop << "CMD: Saving Accounts... ";
				Accounts->Save();
				messageLoop << MSG_PRINTDONE;
				break;
			case '@':
				// Force server to save all files.(Manual save)
				messageLoop << MSG_WORLDSAVE;
				break;
		case 'Y':
			std::cout << "System: ";
			while( !kill )
			{
				keyresp = cl_getch();
				switch( keyresp )
				{
					case -1:	// no key pressed
					case 0:
						break;
					case 0x1B:
						memset( outputline, 0x00, sizeof( outputline ) );
						indexcount = 0;
						kill = true;
						std::cout << std::endl;
						messageLoop << "CMD: System broadcast canceled.";
						break;
					case 0x08:
						--indexcount;
						if( indexcount < 0 )	
							indexcount = 0;
						else
							std::cout << "\b \b";
						break;
					case 0x0A:
					case 0x0D:
						outputline[indexcount] = 0;
						messageLoop.NewMessage( MSG_CONSOLEBCAST, outputline );
						indexcount = 0;
						kill = true;
						std::cout << std::endl;
						sprintf( temp, "CMD: System broadcast sent message \"%s\"", outputline );
						memset( outputline, 0x00, sizeof( outputline ) );
						messageLoop << temp;
						break;
					default:
						if( static_cast<size_t>(indexcount) < sizeof( outputline ) )
						{
							outputline[indexcount++] = (UI08)(keyresp);
							std::cout << (char)keyresp;
						}
						break;
				}
				keyresp = 0x00;
			}
			break;
			case '[':
			{
				// We want to group all the contents of the multimap container numerically by group. We rely on the self ordering in the multimap implementation to do this.
				messageLoop << "  ";
				messageLoop << "Auto-AddMenu Statistics";
				messageLoop << "  ";
				char szBuffer[128];
				// We need to get an iteration into the map first of all the top level ULONGs then we can get an equal range.
				std::map< UI32, UI08 > localMap;
				localMap.clear();
				for( ADDMENUMAP_CITERATOR CJ = g_mmapAddMenuMap.begin(); CJ != g_mmapAddMenuMap.end(); CJ++ )
				{
					// check to see if the group id has been checked already
					if( localMap.find( CJ->first ) == localMap.end() )
					{
						localMap.insert( std::make_pair( CJ->first, 0 ) );
						memset( szBuffer, 0x00, sizeof( szBuffer ) );
						sprintf( szBuffer, "AddMenuGroup %lu:", CJ->first );
						messageLoop << szBuffer;
						std::pair< ADDMENUMAP_CITERATOR, ADDMENUMAP_CITERATOR > pairRange = g_mmapAddMenuMap.equal_range( CJ->first );
						int count = 0;
						for( ADDMENUMAP_CITERATOR CI=pairRange.first;CI != pairRange.second; CI++ )
						{
							count++;
						}
						memset( szBuffer, 0x00, sizeof( szBuffer ) );
						sprintf( szBuffer, "   Found %i Auto-AddMenu Item(s).", count );
						messageLoop << szBuffer;
					}
				}
				messageLoop << MSG_SECTIONBEGIN;
				break;
			}
			case '<':
				messageLoop << "Function not implemented.";
				break;
			case '>':
				messageLoop << "Function not implemented.";
				break;
			case 0x1B:
			case 'Q':
				messageLoop << MSG_SECTIONBEGIN;
				messageLoop << "CMD: Immediate Shutdown initialized!";
				messageLoop << MSG_SHUTDOWN;
				break;
			case '0':
				if( !cwmWorldState->GetReloadingScripts() )
				{
					cwmWorldState->SetReloadingScripts( true );
					// Reload all the files. If there are issues with these files change the order reloaded from here first.
					cwmWorldState->ServerData()->Load();
					messageLoop << "CMD: Loading All";
					messageLoop << "     Server INI... ";
					// Reload accounts, and update Access.adm if new accounts available.
					messageLoop << "     Loading Accounts... ";
					Accounts->Load();
					messageLoop << MSG_PRINTDONE;
					// Reload Region Files
					messageLoop << "     Loading Regions... ";
					UnloadRegions();
					LoadRegions();
					messageLoop << MSG_PRINTDONE;
					// Reload the serve spawn regions
					messageLoop << "     Loading Spawn Regions... ";
					UnloadSpawnRegions();
					LoadSpawnRegions();
					messageLoop << MSG_PRINTDONE;
					// Reload the server command list
					messageLoop << "     Loading commands... ";
					Commands->Load();
					messageLoop << MSG_PRINTDONE;
					// Reload DFN's
					messageLoop << "     Loading Server DFN... ";
					FileLookup->Reload();
					LoadTeleportLocations();
					messageLoop << MSG_PRINTDONE;
					// messageLoop access is REQUIRED, as this function is executing in a different thread, so we need thread safety
					messageLoop << "     Loading JSE Scripts... ";
					
					// Reload the current Spells 
					messageLoop << "     Loading spells... ";
					Magic->LoadScript();
					messageLoop << MSG_PRINTDONE;
					// Reload the HTML output templates
					messageLoop << "     Loading HTML Templates... ";
					HTMLTemplates->Unload();
					HTMLTemplates->Load();
					cwmWorldState->SetReloadingScripts( false );
					messageLoop << MSG_PRINTDONE;
				}
				else
					messageLoop << "Server can only load one script at a time";
				break;
			case 'T':
				// Timed shut down(10 minutes)
				messageLoop << "CMD: 10 Minute Server Shutdown Announced(Timed)";
				cwmWorldState->SetEndTime( BuildTimeValue( 600 ) );
				endmessage(0);
				break;
			case  'D':    
				// Disconnect account 0 (useful when client crashes)
				for( tSock = Network->LastSocket(); tSock != NULL; tSock = Network->PrevSocket() )
				{
					if( tSock->AcctNo() == 0 )
						Network->Disconnect( tSock );
				}
				messageLoop << "CMD: Socket Disconnected(Account 0).";
				break;
			case 'K':
			{
				for( tSock = Network->FirstSocket(); !Network->FinishedSockets(); tSock = Network->NextSocket() )
				{
					Network->Disconnect( tSock );
				}
				messageLoop << "CMD: All Connections Closed.";
			}
				break;
			case 'P':
				{
				UI32 networkTimeCount	= cwmWorldState->ServerProfile()->NetworkTimeCount();
				UI32 timerTimeCount		= cwmWorldState->ServerProfile()->TimerTimeCount();
				UI32 autoTimeCount		= cwmWorldState->ServerProfile()->AutoTimeCount();
				UI32 loopTimeCount		= cwmWorldState->ServerProfile()->LoopTimeCount();
				// 1/13/2003 - Dreoth - Log Performance Information enhancements
				LogEcho( true );
				Log( "--- Starting Performance Dump ---", "performance.log");
				Log( "\tPerformace Dump:", "performance.log");
				Log( "\tNetwork code: %.2fmsec [%i samples]", "performance.log", (R32)((R32)cwmWorldState->ServerProfile()->NetworkTime()/(R32)networkTimeCount), networkTimeCount);
				Log( "\tTimer code: %.2fmsec [%i samples]", "performance.log", (R32)((R32)cwmWorldState->ServerProfile()->TimerTime()/(R32)timerTimeCount), timerTimeCount);
				Log( "\tAuto code: %.2fmsec [%i samples]", "performance.log", (R32)((R32)cwmWorldState->ServerProfile()->AutoTime()/(R32)autoTimeCount), autoTimeCount);
				Log( "\tLoop Time: %.2fmsec [%i samples]", "performance.log", (R32)((R32)cwmWorldState->ServerProfile()->LoopTime()/(R32)loopTimeCount), loopTimeCount);
				ObjectFactory *ourFac = ObjectFactory::getSingletonPtr();
				Log( "\tCharacters: %i/%i - Items: %i/%i (Dynamic)", "performance.log", ourFac->CountOfObjects( OT_CHAR ), ourFac->SizeOfObjects( OT_CHAR ), ourFac->CountOfObjects( OT_ITEM ), ourFac->SizeOfObjects( OT_ITEM ) );
				Log( "\tSimulation Cycles: %f per sec", "performance.log", (1000.0*(1.0/(R32)((R32)cwmWorldState->ServerProfile()->LoopTime()/(R32)loopTimeCount))));
				Log( "\tBytes sent: %i", "performance.log", cwmWorldState->ServerProfile()->GlobalSent());
				Log( "\tBytes Received: %i", "performance.log", cwmWorldState->ServerProfile()->GlobalReceived());
				Log( "--- Performance Dump Complete ---", "performance.log");
				LogEcho( false );
				break;
				}
			case 'W':                
				// Display logged in chars
				messageLoop << "CMD: Current Users in the World:";
				j = 0;
				CSocket *iSock;
				Network->PushConn();
				for( iSock = Network->FirstSocket(); !Network->FinishedSockets(); iSock = Network->NextSocket() )
				{
					++j;
					CChar *mChar = iSock->CurrcharObj();
					sprintf( temp, "     %i) %s [%x %x %x %x]", j - 1, mChar->GetName().c_str(), mChar->GetSerial( 1 ), mChar->GetSerial( 2 ), mChar->GetSerial( 3 ), mChar->GetSerial( 4 ) );
					messageLoop << temp;
				}
				Network->PopConn();
				sprintf( temp, "     Total users online: %i", j );
				messageLoop << temp;
				break;
			case 'M':
				size_t tmp, total;
				total = 0;
				tmp = 0;
				messageLoop << "CMD: UOX Memory Information:";
				messageLoop << "     Cache:";
				sprintf( temp, "        Tiles: %u bytes", Map->GetTileMem() );
				messageLoop << temp;
				sprintf( temp, "        Multis: %u bytes", Map->GetMultisMem() );
				messageLoop << temp;
				size_t m, n;
				m = ObjectFactory::getSingleton().SizeOfObjects( OT_CHAR );
				total += tmp = m + m*sizeof( CTEffect ) + m*sizeof(char) + m*sizeof(int)*5;
				sprintf( temp, "     Characters: %u bytes [%u chars ( %u allocated )]", tmp, ObjectFactory::getSingleton().CountOfObjects( OT_CHAR ), m );
				messageLoop << temp;
				n = ObjectFactory::getSingleton().SizeOfObjects( OT_ITEM );
				total += tmp = n + n * sizeof( int ) * 4;
				sprintf( temp, "     Items: %u bytes [%u items ( %u allocated )]", tmp, ObjectFactory::getSingleton().CountOfObjects( OT_ITEM ), n );
				messageLoop << temp;
				sprintf( temp, "        You save I: %i & C: %i bytes!", m * sizeof(CItem) - ObjectFactory::getSingleton().CountOfObjects( OT_ITEM ), m * sizeof( CChar ) - ObjectFactory::getSingleton().CountOfObjects( OT_CHAR ) );
				total += tmp = 69 * sizeof( SpellInfo );
				sprintf( temp, "     Spells: %i bytes", tmp );
				messageLoop << "     Sizes:";
				sprintf( temp, "        CItem  : %i bytes", sizeof( CItem ) );
				messageLoop << temp;
				sprintf( temp, "        CChar  : %i bytes", sizeof( CChar ) );
				messageLoop << temp;
				sprintf( temp, "        TEffect: %i bytes (%i total)", sizeof( CTEffect ), sizeof( CTEffect ) * cwmWorldState->tempEffects.Num() );
				messageLoop << temp;
				total += tmp = Map->GetTileMem() + Map->GetMultisMem();
				sprintf( temp, "        Approximate Total: %i bytes", total );
				messageLoop << temp;
				break;
			case '?':
				messageLoop << MSG_SECTIONBEGIN;
				messageLoop << "Console commands:";
				messageLoop << MSG_SECTIONBEGIN;
				messageLoop << " ShardOP:";
				messageLoop << "    * - Lock/Unlock Console ? - Commands list(this)";
				messageLoop << "    C - Configuration       H - Unused";
				messageLoop << "    Y - Console Broadcast   Q - Quit/Exit           ";
				messageLoop << " Load Commands:";
				messageLoop << "    1 - Ini                 2 - Accounts";
				messageLoop << "    3 - Regions             4 - Spawn Regions";
				messageLoop << "    5 - Spells              6 - Commands";
				messageLoop << "    7 - Dfn's               8 - JavaScript";
				messageLoop << "    9 - HTML Templates      0 - ALL(1-9)";
				messageLoop << " Save Commands:";
				messageLoop << "    ! - Accounts            @ - World(w/AccountImport)";
				messageLoop << "    # - Unused              $ - Unused";
				messageLoop << "    % - Unused              ^ - Unused";
				messageLoop << "    & - Unused              ( - Unused";
				messageLoop << "    ) - Unused";
				messageLoop << " Server Maintenence:";
				messageLoop << "    P - Performance         W - Characters Online";
				messageLoop << "    M - Memory Information  T - 10 Minute Shutdown";
				messageLoop << "    V - Dump Lookups(Devs)  F - Display Priority Maps";
				messageLoop << " Network Maintenence:";
				messageLoop << "    D - Disconnect Acct0    K - Disconnect All";
				messageLoop << "    Z - Socket Logging      ";
				messageLoop << MSG_SECTIONBEGIN;
				break;
			case 'v':
			case 'V':
				// Dump look up data to files so developers working with extending the ini will have a table to use
				messageLoop << "| CMD: Creating Server.scp and Uox3.ini Tag Lookup files(For Developers)....";
				cwmWorldState->ServerData()->dumpLookup( 0 );
				cwmWorldState->ServerData()->save( "./uox.tst.ini" );
				messageLoop << MSG_PRINTDONE;
				break;
			case 'z':
			case 'Z':
			{
				// Log socket activity
				Network->PushConn();
				bool loggingEnabled	= false;
				CSocket *snSock		= Network->FirstSocket();
				if( snSock != NULL )
					loggingEnabled = !snSock->Logging();
				for( ; !Network->FinishedSockets(); snSock = Network->NextSocket() )
				{
					if( snSock != NULL )
						snSock->Logging( !snSock->Logging() );
				}
				Network->PopConn();
				if( loggingEnabled )
					messageLoop << "CMD: Network Logging Enabled.";
				else
					messageLoop << "CMD: Network Logging Disabled.";
				break;
			}
			case 'c':
			case 'C':
				// Shows a configuration header
				DisplaySettings();
				break;
			case 'f':
			case 'F':
				FileLookup->DisplayPriorityMap();
				break;
			default:
				sprintf( temp, "Key \'%c\' [%i] does not perform a function", (char)c, c );
				messageLoop << temp;
				break;
		}
	}
}