Пример #1
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;
		}
	}
}