context: using System;
  using System.Collections.Generic;
  using System.IO;
  using System.Net;
  using Server;
  using Server.Accounting;
  using Server.Commands;
  using Server.Engines.Help;
  using Server.Network;
  using Server.Regions;
  
  namespace Server.Misc
  {
  	public enum PasswordProtection
  	{
  		None,
  		Crypt,
  		NewCrypt
  	}
  
  	public class AccountHandler
  	{
  		private static int MaxAccountsPerIP = 1;
  		private static bool AutoAccountCreation = true;
  		private static bool RestrictDeletion = !TestCenter.Enabled;
  		private static TimeSpan DeleteDelay = TimeSpan.FromDays( 7.0 );
  
  		public static PasswordProtection ProtectPasswords = PasswordProtection.NewCrypt;
  
  		private static AccessLevel m_LockdownLevel;
  
  		public static AccessLevel LockdownLevel
  		{
  			get{ return m_LockdownLevel; }
  			set{ m_LockdownLevel = value; }
  		}
  		
  		private static CityInfo[] StartingCities = new CityInfo[]
  			{
  				new CityInfo( "Yew",		"The Empath Abbey",1075072,			633,	858,	0	,CurrentExpansion.IncludeTrammel ? Map.Trammel : Map.Felucca ),
  				new CityInfo( "Minoc",		"The Barnacle",1075073,				2476,	413,	15	,CurrentExpansion.IncludeTrammel ? Map.Trammel : Map.Felucca ),
  				new CityInfo( "Britain",	"Sweet Dreams Inn",1075074,			1496,	1628,	10	,CurrentExpansion.IncludeTrammel ? Map.Trammel : Map.Felucca ),
  				new CityInfo( "Moonglow",	"The Scholars Inn",1075075,			4408,	1168,	0	,CurrentExpansion.IncludeTrammel ? Map.Trammel : Map.Felucca ),
  				new CityInfo( "Trinsic",	"The Traveler's Inn",1075076,		1845,	2745,	0	,CurrentExpansion.IncludeTrammel ? Map.Trammel : Map.Felucca ),
  				new CityInfo( "Magincia",	"The Great Horns Tavern",1075077,	3734,	2222,	20	,CurrentExpansion.IncludeTrammel ? Map.Trammel : Map.Felucca ),
  				new CityInfo( "Jhelom",		"The Mercenary Inn",1075078,		1374,	3826,	0	,CurrentExpansion.IncludeTrammel ? Map.Trammel : Map.Felucca ),
  				new CityInfo( "Skara Brae",	"The Falconer's Inn",1075079,		618,	2234,	0   ,CurrentExpansion.IncludeTrammel ? Map.Trammel : Map.Felucca ),
  				new CityInfo( "Vesper",		"The Ironwood Inn",	1075080,		2771,	976,	0   ,CurrentExpansion.IncludeTrammel ? Map.Trammel : Map.Felucca ),
  				new CityInfo( "Occlo",		"Buckler's Hideaway",1150168,		3667,	2625,	0   ,CurrentExpansion.IncludeTrammel ? Map.Trammel : Map.Felucca )
  			};		
  		
  		/* Old Haven/Magincia Locations
  			new CityInfo( "Britain", "Sweet Dreams Inn", 1496, 1628, 10 );
  			// ..
  			// Trinsic
  			new CityInfo( "Magincia", "The Great Horns Tavern", 3734, 2222, 20 ),
  			// Jhelom
  			// ..
  			new CityInfo( "Haven", "Buckler's Hideaway", 3667, 2625, 0 )
  
  			if ( Core.AOS )
  			{
  				//CityInfo haven = new CityInfo( "Haven", "Uzeraan's Mansion", 3618, 2591, 0 );
  				CityInfo haven = new CityInfo( "Haven", "Uzeraan's Mansion", 3503, 2574, 14 );
  				StartingCities[StartingCities.Length - 1] = haven;
  			}
  		*/
  
  		private static bool PasswordCommandEnabled = false;
  
  		public static void Initialize()
  		{
  			EventSink.DeleteRequest += new DeleteRequestEventHandler( EventSink_DeleteRequest );
  			EventSink.AccountLogin += new AccountLoginEventHandler( EventSink_AccountLogin );
  			EventSink.GameLogin += new GameLoginEventHandler( EventSink_GameLogin );
  
  			if ( PasswordCommandEnabled )
  				CommandSystem.Register( "Password", AccessLevel.Player, new CommandEventHandler( Password_OnCommand ) );
  		}
  
  		[Usage( "Password <newPassword> <repeatPassword>" )]
  		[Description( "Changes the password of the commanding players account. Requires the same C-class IP address as the account's creator." )]
  		public static void Password_OnCommand( CommandEventArgs e )
  		{
  			Mobile from = e.Mobile;
  			Account acct = from.Account as Account;
  
  			if ( acct == null )
  				return;
  
  			IPAddress[] accessList = acct.LoginIPs;
  
  			if ( accessList.Length == 0 )
  				return;
  
  			NetState ns = from.NetState;
  
  			if ( ns == null )
  				return;
  
  			if ( e.Length == 0 )
  			{
  				from.SendMessage( "You must specify the new password." );
  				return;
  			}
  			else if ( e.Length == 1 )
  			{
  				from.SendMessage( "To prevent potential typing mistakes, you must type the password twice. Use the format:" );
  				from.SendMessage( "Password \"(newPassword)\" \"(repeated)\"" );
  				return;
  			}
  
  			string pass = e.GetString( 0 );
  			string pass2 = e.GetString( 1 );
  
  			if ( pass != pass2 )
  			{
  				from.SendMessage( "The passwords do not match." );
  				return;
  			}
  
  			bool isSafe = true;
  
  			for ( int i = 0; isSafe && i < pass.Length; ++i )
  				isSafe = ( pass[i] >= 0x20 && pass[i] < 0x7F );
  
  			if ( !isSafe )
  			{
  				from.SendMessage( "That is not a valid password." );
  				return;
  			}
  
  			try
  			{
  				IPAddress ipAddress = ns.Address;
  
  				if ( Utility.IPMatchClassC( accessList[0], ipAddress ) )
  				{
  					acct.SetPassword( pass );
  					from.SendMessage( "The password to your account has changed." );
  				}
  				else
  				{
  					PageEntry entry = PageQueue.GetEntry( from );
  
  					if ( entry != null )
  					{
  						if ( entry.Message.StartsWith( "[Automated: Change Password]" ) )
  							from.SendMessage( "You already have a password change request in the help system queue." );
  						else
  							from.SendMessage( "Your IP address does not match that which created this account." );
  					}
  					else if ( PageQueue.CheckAllowedToPage( from ) )
  					{
  						from.SendMessage( "Your IP address does not match that which created this account.  A page has been entered into the help system on your behalf." );
  
  						from.SendLocalizedMessage( 501234, "", 0x35 ); /* The next available Counselor/Game Master will respond as soon as possible.
  																	    * Please check your Journal for messages every few minutes.
  																	    */
  
  						PageQueue.Enqueue( new PageEntry( from, String.Format( "[Automated: Change Password]<br>Desired password: {0}<br>Current IP address: {1}<br>Account IP address: {2}", pass, ipAddress, accessList[0] ), PageType.Account ) );
  					}
  
  				}
  			}
  			catch
  			{
  			}
  		}
  
  		private static void EventSink_DeleteRequest( DeleteRequestEventArgs e )
  		{
  			NetState state = e.State;
  			int index = e.Index;
  
  			Account acct = state.Account as Account;
  
  			if ( acct == null )
  			{
  				state.Dispose();
  			}
  			else if ( index < 0 || index >= acct.Length )
  			{
  				state.Send( new DeleteResult( DeleteResultType.BadRequest ) );
  				state.Send( new CharacterListUpdate( acct ) );
  			}
  			else
  			{
  				Mobile m = acct[index];
  
  				if ( m == null )
  				{
  					state.Send( new DeleteResult( DeleteResultType.CharNotExist ) );
  					state.Send( new CharacterListUpdate( acct ) );
  				}
  				else if ( m.NetState != null )
  				{
  					state.Send( new DeleteResult( DeleteResultType.CharBeingPlayed ) );
  					state.Send( new CharacterListUpdate( acct ) );
  				}
  				else if ( RestrictDeletion && DateTime.UtcNow < (m.CreationTime + DeleteDelay) )
  				{
  					state.Send( new DeleteResult( DeleteResultType.CharTooYoung ) );
  
gt: 					state.Send( new CharacterListUpdate( acct ) );