context: using System;
  using System.Collections;
  using Server;
  using Server.Network;
  using Server.Accounting;
  using Server.Items;
  using Server.Mobiles;
  
  namespace Server.RemoteAdmin
  {
  	public class RemoteAdminHandlers
  	{
  		public enum AcctSearchType : byte
  		{
  			Username = 0,
  			IP = 1,
  		}
  
  		private static OnPacketReceive[] m_Handlers = new OnPacketReceive[256];
  
  		static RemoteAdminHandlers()
  		{
  			//0x02 = login request, handled by AdminNetwork
  			Register( 0x04, new OnPacketReceive( ServerInfoRequest ) );
  			Register( 0x05, new OnPacketReceive( AccountSearch ) );
  			Register( 0x06, new OnPacketReceive( RemoveAccount ) );
  			Register( 0x07, new OnPacketReceive( UpdateAccount ) );
  		}
  
  		public static void Register( byte command, OnPacketReceive handler )
  		{
  			m_Handlers[command] = handler;
  		}
  
  		public static bool Handle( byte command, NetState state, PacketReader pvSrc )
  		{
  			if ( m_Handlers[command] == null )
  			{
  				Console.WriteLine( "ADMIN: Invalid packet 0x{0:X2} from {1}, disconnecting", command, state );
  				return false;
  			}
  			else
  			{
  				m_Handlers[command]( state, pvSrc );
  				return true;
  			}
  		}
  
  		private static void ServerInfoRequest( NetState state, PacketReader pvSrc )
  		{
  			state.Send( AdminNetwork.Compress( new ServerInfo() ) );
  		}
  
  		private static void AccountSearch( NetState state, PacketReader pvSrc )
  		{
  			AcctSearchType type = (AcctSearchType)pvSrc.ReadByte();
  			string term = pvSrc.ReadString();
  
  			if ( type == AcctSearchType.IP && !Utility.IsValidIP( term ) )
  			{
  				state.Send( new MessageBoxMessage( "Invalid search term.\nThe IP sent was not valid.", "Invalid IP" ) );
  				return;
  			}
  			else
  			{
  				term = term.ToUpper();
  			}
  
  			ArrayList list = new ArrayList();
  
  			foreach ( Account a in Accounts.GetAccounts() )
  			{
  				if ( !CanAccessAccount( state.Account, a ) ) continue;
  
  				switch ( type )
  				{
  					case AcctSearchType.Username:
  					{
  						if ( a.Username.ToUpper().IndexOf( term ) != -1 )
  							list.Add( a );
  						break;
  					}
  					case AcctSearchType.IP:
  					{
  						for( int i=0;i<a.LoginIPs.Length;i++ )
  						{
  							if ( Utility.IPMatch( term, a.LoginIPs[i] ) )
  							{
  								list.Add( a );
  								break;
  							}
  						}
  						break;
  					}
  				}
  			}
  
  			if ( list.Count > 0 )
  			{
  				if ( list.Count <= 25 )
  					state.Send( AdminNetwork.Compress( new AccountSearchResults( list ) ) );
  				else
  					state.Send( new MessageBoxMessage( "There were more than 25 matches to your search.\nNarrow the search parameters and try again.", "Too Many Results" ) );
  			}
  			else
  			{
  				state.Send( new MessageBoxMessage( "There were no results to your search.\nPlease try again.", "No Matches" ) );
  			}
  		}
  
  		static bool CanAccessAccount( IAccount beholder, IAccount beheld )
  		{
  			return beholder.AccessLevel == AccessLevel.Owner || beheld.AccessLevel < beholder.AccessLevel;  // Cannot see accounts of equal or greater access level unless Owner
  		}
  
  		private static void RemoveAccount( NetState state, PacketReader pvSrc )
  		{
  			if ( state.Account.AccessLevel < AccessLevel.Administrator )
  			{
  				state.Send( new MessageBoxMessage( "You do not have permission to delete accounts.", "Account Access Exception" ) );
  				return;
  			}
  
  			IAccount a = Accounts.GetAccount( pvSrc.ReadString() );
  
  			if ( a == null )
  			{
  				state.Send( new MessageBoxMessage( "The account could not be found (and thus was not deleted).", "Account Not Found" ) );
  			}
  			else if ( !CanAccessAccount( state.Account, a ) )
  			{
  				state.Send( new MessageBoxMessage( "You cannot delete an account with an access level greater than or equal to your own.", "Account Access Exception" ) );
  			}
  			else if ( a == state.Account )
  			{
  				state.Send( new MessageBoxMessage( "You may not delete your own account.", "Not Allowed" ) );
  			}
  			else
  			{
  				RemoteAdminLogging.WriteLine( state, "Deleted Account {0}", a );
  				a.Delete();
  				state.Send( new MessageBoxMessage( "The requested account (and all it's characters) has been deleted.", "Account Deleted" ) );
  			}
  		}
  
  		private static void UpdateAccount( NetState state, PacketReader pvSrc )
  		{ 
  			if ( state.Account.AccessLevel < AccessLevel.Administrator )
  			{
  				state.Send( new MessageBoxMessage( "You do not have permission to edit accounts.", "Account Access Exception" ) );
  				return;
  			}
  
  			string username = pvSrc.ReadString();
  			string pass = pvSrc.ReadString();
  
  			Account a = Accounts.GetAccount( username ) as Account;
  
  			if ( a != null && !CanAccessAccount( state.Account, a ) )
  			{
  				state.Send( new MessageBoxMessage( "You cannot edit an account with an access level greater than or equal to your own.", "Account Access Exception" ) );
  			}
  			else
  			{
  				bool CreatedAccount = false;
  				bool UpdatedPass = false;
  				bool oldbanned = a == null ? false : a.Banned;
  				AccessLevel oldAcessLevel = a == null ? 0 : a.AccessLevel;
  
  				if ( a == null )
  				{
  					a = new Account( username, pass );
  					CreatedAccount = true;
  				}
  				else if ( pass != "(hidden)" )
  				{
  					a.SetPassword( pass );
  					UpdatedPass = true;
  				}
  
  				if ( a != state.Account )
  				{
  					AccessLevel newAccessLevel = (AccessLevel)pvSrc.ReadByte();
  					if ( a.AccessLevel != newAccessLevel )
  					{
  						if ( newAccessLevel >= state.Account.AccessLevel )
  							state.Send( new MessageBoxMessage( "Warning: You may not set an access level greater than or equal to your own.", "Account Access Level update denied." ) );
  						else
  							a.AccessLevel = newAccessLevel;
  					}
  					bool newBanned = pvSrc.ReadBoolean();
  					if ( newBanned != a.Banned )
  					{
  						oldbanned = a.Banned;
  						a.Banned = newBanned;
  						a.Comments.Add( new AccountComment( state.Account.Username, newBanned ? "Banned via Remote Admin" : "Unbanned via Remote Admin" ) );
  					}
  				}
  				else
  				{
  					pvSrc.ReadInt16();//skip both
  					state.Send( new MessageBoxMessage( "Warning: When editing your own account, Account Status and Access Level cannot be changed.", "Editing Own Account" ) );
  				}
  
  
gt: 				ArrayList list = new ArrayList();