RunUO Community

This is a sample guest message. Register a free account today to become a member! Once signed in, you'll be able to participate on this site by adding your own topics and posts, as well as connect with other members through your own private inbox!

[RUO 2.0 F+] Complete Automated Web-Accounting Service V2.0.1

Vorspire

Knight
Here's an insider's sneak peek at the new Synchronize algorithm, you can see the changes including Update Modes, save after sync, the new Connection class, etc... :)

Code:
public static void SynchronizeDatabase()
        {
            if (Synchronizing || !WAConfig.Enabled)
                return;

            Connection.Connect();
            Connection.Open();

            Synchronizing = true;

            CreateAccountsFromDB();
            CreateAccountsFromUO();

            UpdateAccountsFromDB(UpdateMode.All);
            UpdateAccountsFromUO(UpdateMode.All);

            Console.WriteLine(String.Format("[WebAccounting] Executed {0} Database Queries.", Connection.QueryCount));

            Connection.Close();
            QueryCount = 0;

            if (WAConfig.SaveAfterSync) //I like cheese.
                World.Save();

            Synchronizing = false;
        }

Code:
public enum UpdateMode
        {
            All,
            Passwords,
            Emails,
            AccessLevels,
            Delete
        }
 

Admin Flames

Wanderer
Nodio;756571 said:
Errors:
+ Accounting/Account.cs:
CS0029: Line 45: Não é possível converter implicitamente o tipo 'System.Collections.Generic.List<Server.Multis.BaseHouse>' em 'System.Collections.Arra
List'
CS0117: Line 933: 'Server.Misc.AccountHandler' não contém uma definição para 'IPTables'
CS0117: Line 934: 'Server.Misc.AccountHandler' não contém uma definição para 'IPTables'
CS0117: Line 936: 'Server.Misc.AccountHandler' não contém uma definição para 'IPTables'
CS0117: Line 936: 'Server.Misc.AccountHandler' não contém uma definição para 'IPTables'


try updating your account.sc file to this

Code:
using System;
using System.Collections;
using System.Collections.Generic;
using System.Net;
using System.Security;
using System.Security.Cryptography;
using System.Text;
using System.Xml;
using Server;
using Server.Misc;
using Server.Mobiles;
using Server.Multis;
using Server.Network;

namespace Server.Accounting
{
	public class Account : IAccount, IComparable, IComparable<Account>
	{
		public static readonly TimeSpan YoungDuration = TimeSpan.FromHours( 40.0 );

		private string m_Username, m_PlainPassword, m_CryptPassword, m_NewCryptPassword, m_Email;
		private AccessLevel m_AccessLevel;
		private int m_Flags;
		private DateTime m_Created, m_LastLogin;
		private TimeSpan m_TotalGameTime;
		private List<AccountComment> m_Comments;
		private List<AccountTag> m_Tags;
		private Mobile[] m_Mobiles;
		private string[] m_IPRestrictions;
		private IPAddress[] m_LoginIPs;
		private HardwareInfo m_HardwareInfo;
		private bool m_Deleted;

		/// <summary>
		/// Deletes the account, all characters of the account, and all houses of those characters
		/// </summary>
		public void Delete()
		{
			for ( int i = 0; i < this.Length; ++i )
			{
				Mobile m = this[i];

				if ( m == null )
					continue;

				List<BaseHouse> list = BaseHouse.GetHouses( m );

				for ( int j = 0; j < list.Count; ++j )
					( (Item) list[j] ).Delete();

				m.Delete();

				m.Account = null;
				m_Mobiles[i] = null;
			}

			m_Deleted = true;
			Accounts.UnregisterEmail( m_Email );
			Accounts.Remove( m_Username );
		}

		public bool Deleted
		{
			get { return m_Deleted; }
		}

		/// <summary>
		/// Object detailing information about the hardware of the last person to log into this account
		/// </summary>
		public HardwareInfo HardwareInfo
		{
			get { return m_HardwareInfo; }
			set { m_HardwareInfo = value; }
		}

		/// <summary>
		/// List of IP addresses for restricted access. '*' wildcard supported. If the array contains zero entries, all IP addresses are allowed.
		/// </summary>
		public string[] IPRestrictions
		{
			get { return m_IPRestrictions; }
			set { m_IPRestrictions = value; }
		}

		/// <summary>
		/// List of IP addresses which have successfully logged into this account.
		/// </summary>
		public IPAddress[] LoginIPs
		{
			get { return m_LoginIPs; }
			set { m_LoginIPs = value; }
		}

		/// <summary>
		/// List of account comments. Type of contained objects is AccountComment.
		/// </summary>
		public List<AccountComment> Comments
		{
			get { if ( m_Comments == null ) m_Comments = new List<AccountComment>(); return m_Comments; }
		}

		/// <summary>
		/// List of account tags. Type of contained objects is AccountTag.
		/// </summary>
		public List<AccountTag> Tags
		{
			get { if ( m_Tags == null ) m_Tags = new List<AccountTag>(); return m_Tags; }
		}

		/// <summary>
		/// Account username. Case insensitive validation.
		/// </summary>
		public string Username
		{
			get { return m_Username; }
			set { m_Username = value; }
		}

		/// <summary>
		/// Account password. Plain text. Case sensitive validation. May be null.
		/// </summary>
		public string PlainPassword
		{
			get { return m_PlainPassword; }
			set { m_PlainPassword = value; }
		}

		/// <summary>
		/// Account password. Hashed with MD5. May be null.
		/// </summary>
		public string CryptPassword
		{
			get { return m_CryptPassword; }
			set { m_CryptPassword = value; }
		}

		/// <summary>
		/// Account username and password hashed with MD5. May be null.
		/// </summary>
		public string NewCryptPassword
		{
			get { return m_CryptPassword; }
			set { m_CryptPassword = value; }
		}

		/// <summary>
		/// Account E-Mail. May be "".
		/// </summary>
		public string Email
		{
			get { return m_Email; }
			set
			{
				if( Accounts.RegisterEmail( this, value ) )
					m_Email = value;
			}
		}

		/// <summary>
		/// Initial AccessLevel for new characters created on this account.
		/// </summary>
		public AccessLevel AccessLevel
		{
			get { return m_AccessLevel; }
			set { m_AccessLevel = value; }
		}

		/// <summary>
		/// Internal bitfield of account flags. Consider using direct access properties (Banned, Young), or GetFlag/SetFlag methods
		/// </summary>
		public int Flags
		{
			get { return m_Flags; }
			set { m_Flags = value; }
		}

		/// <summary>
		/// Gets or sets a flag indiciating if this account is banned.
		/// </summary>
		public bool Banned
		{
			get
			{
				bool isBanned = GetFlag( 0 );

				if ( !isBanned )
					return false;

				DateTime banTime;
				TimeSpan banDuration;

				if ( GetBanTags( out banTime, out banDuration ) )
				{
					if ( banDuration != TimeSpan.MaxValue && DateTime.Now >= ( banTime + banDuration ) )
					{
						SetUnspecifiedBan( null ); // clear
						Banned = false;
						return false;
					}
				}

				return true;
			}
			set { SetFlag( 0, value ); }
		}

		/// <summary>
		/// Gets or sets a flag indicating if the characters created on this account will have the young status.
		/// </summary>
		public bool Young
		{
			get { return !GetFlag( 1 ); }
			set
			{
				SetFlag( 1, !value );

				if ( m_YoungTimer != null )
				{
					m_YoungTimer.Stop();
					m_YoungTimer = null;
				}
			}
		}

		/// <summary>
		/// The date and time of when this account was created.
		/// </summary>
		public DateTime Created
		{
			get { return m_Created; }
		}

		/// <summary>
		/// Gets or sets the date and time when this account was last accessed.
		/// </summary>
		public DateTime LastLogin
		{
			get { return m_LastLogin; }
			set { m_LastLogin = value; }
		}

		/// <summary>
		/// Gets the total game time of this account, also considering the game time of characters
		/// that have been deleted.
		/// </summary>
		public TimeSpan TotalGameTime
		{
			get
			{
				for ( int i = 0; i < m_Mobiles.Length; i++ )
				{
					PlayerMobile m = m_Mobiles[i] as PlayerMobile;

					if ( m != null && m.NetState != null )
						return m_TotalGameTime + ( DateTime.Now - m.SessionStart );
				}

				return m_TotalGameTime;
			}
		}

		/// <summary>
		/// Gets the value of a specific flag in the Flags bitfield.
		/// </summary>
		/// <param name="index">The zero-based flag index.</param>
		public bool GetFlag( int index )
		{
			return ( m_Flags & ( 1 << index ) ) != 0;
		}

		/// <summary>
		/// Sets the value of a specific flag in the Flags bitfield.
		/// </summary>
		/// <param name="index">The zero-based flag index.</param>
		/// <param name="value">The value to set.</param>
		public void SetFlag( int index, bool value )
		{
			if ( value )
				m_Flags |= ( 1 << index );
			else
				m_Flags &= ~( 1 << index );
		}

		/// <summary>
		/// Adds a new tag to this account. This method does not check for duplicate names.
		/// </summary>
		/// <param name="name">New tag name.</param>
		/// <param name="value">New tag value.</param>
		public void AddTag( string name, string value )
		{
			Tags.Add( new AccountTag( name, value ) );
		}

		/// <summary>
		/// Removes all tags with the specified name from this account.
		/// </summary>
		/// <param name="name">Tag name to remove.</param>
		public void RemoveTag( string name )
		{
			for ( int i = Tags.Count - 1; i >= 0; --i )
			{
				if ( i >= Tags.Count )
					continue;

				AccountTag tag = Tags[i];

				if ( tag.Name == name )
					Tags.RemoveAt( i );
			}
		}

		/// <summary>
		/// Modifies an existing tag or adds a new tag if no tag exists.
		/// </summary>
		/// <param name="name">Tag name.</param>
		/// <param name="value">Tag value.</param>
		public void SetTag( string name, string value )
		{
			for ( int i = 0; i < Tags.Count; ++i )
			{
				AccountTag tag = Tags[i];

				if ( tag.Name == name )
				{
					tag.Value = value;
					return;
				}
			}

			AddTag( name, value );
		}

		/// <summary>
		/// Gets the value of a tag -or- null if there are no tags with the specified name.
		/// </summary>
		/// <param name="name">Name of the desired tag value.</param>
		public string GetTag( string name )
		{
			for ( int i = 0; i < Tags.Count; ++i )
			{
				AccountTag tag = Tags[i];

				if ( tag.Name == name )
					return tag.Value;
			}

			return null;
		}

		public void SetUnspecifiedBan( Mobile from )
		{
			SetBanTags( from, DateTime.MinValue, TimeSpan.Zero );
		}

		public void SetBanTags( Mobile from, DateTime banTime, TimeSpan banDuration )
		{
			if ( from == null )
				RemoveTag( "BanDealer" );
			else
				SetTag( "BanDealer", from.ToString() );

			if ( banTime == DateTime.MinValue )
				RemoveTag( "BanTime" );
			else
				SetTag( "BanTime", XmlConvert.ToString( banTime, XmlDateTimeSerializationMode.Local ) );

			if ( banDuration == TimeSpan.Zero )
				RemoveTag( "BanDuration" );
			else
				SetTag( "BanDuration", banDuration.ToString() );
		}

		public bool GetBanTags( out DateTime banTime, out TimeSpan banDuration )
		{
			string tagTime = GetTag( "BanTime" );
			string tagDuration = GetTag( "BanDuration" );

			if ( tagTime != null )
				banTime = Utility.GetDateTime( tagTime, DateTime.MinValue );
			else
				banTime = DateTime.MinValue;

			if ( tagDuration == "Infinite" )
			{
				banDuration = TimeSpan.MaxValue;
			}
			else if ( tagDuration != null )
			{
				banDuration = Utility.ToTimeSpan( tagDuration );
			}
			else
			{
				banDuration = TimeSpan.Zero;
			}

			return ( banTime != DateTime.MinValue && banDuration != TimeSpan.Zero );
		}

		private static MD5CryptoServiceProvider m_MD5HashProvider;
		private static SHA1CryptoServiceProvider m_SHA1HashProvider;
		private static byte[] m_HashBuffer;

		public static string HashMD5( string phrase )
		{
			if ( m_MD5HashProvider == null )
				m_MD5HashProvider = new MD5CryptoServiceProvider();

			if ( m_HashBuffer == null )
				m_HashBuffer = new byte[256];

			int length = Encoding.ASCII.GetBytes( phrase, 0, phrase.Length > 256 ? 256 : phrase.Length, m_HashBuffer, 0 );
			byte[] hashed = m_MD5HashProvider.ComputeHash( m_HashBuffer, 0, length );

			return BitConverter.ToString( hashed );
		}

		public static string HashSHA1( string phrase )
		{
			if ( m_SHA1HashProvider == null )
				m_SHA1HashProvider = new SHA1CryptoServiceProvider();

			if ( m_HashBuffer == null )
				m_HashBuffer = new byte[256];

			int length = Encoding.ASCII.GetBytes( phrase, 0, phrase.Length > 256 ? 256 : phrase.Length, m_HashBuffer, 0 );
			byte[] hashed = m_SHA1HashProvider.ComputeHash( m_HashBuffer, 0, length );

			return BitConverter.ToString( hashed );
		}

		public void SetPassword( string plainPassword )
		{
			switch ( AccountHandler.ProtectPasswords )
			{
				case PasswordProtection.None:
					{
						m_PlainPassword = plainPassword;
						m_CryptPassword = null;
						m_NewCryptPassword = null;

						break;
					}
				case PasswordProtection.Crypt:
					{
						m_PlainPassword = null;
						m_CryptPassword = HashMD5( plainPassword );
						m_NewCryptPassword = null;

						break;
					}
				default: // PasswordProtection.NewCrypt
					{
						m_PlainPassword = null;
						m_CryptPassword = null;
						m_NewCryptPassword = HashSHA1( m_Username + plainPassword );

						break;
					}
			}
		}

		public bool CheckPassword( string plainPassword )
		{
			bool ok;
			PasswordProtection curProt;

			if ( m_PlainPassword != null )
			{
				ok = ( m_PlainPassword == plainPassword );
				curProt = PasswordProtection.None;
			}
			else if ( m_CryptPassword != null )
			{
				ok = ( m_CryptPassword == HashMD5( plainPassword ) );
				curProt = PasswordProtection.Crypt;
			}
			else
			{
				ok = ( m_NewCryptPassword == HashSHA1( m_Username + plainPassword ) );
				curProt = PasswordProtection.NewCrypt;
			}

			if ( ok && curProt != AccountHandler.ProtectPasswords )
				SetPassword( plainPassword );

			return ok;
		}

		private Timer m_YoungTimer;

		public static void Initialize()
		{
			EventSink.Connected += new ConnectedEventHandler( EventSink_Connected );
			EventSink.Disconnected += new DisconnectedEventHandler( EventSink_Disconnected );
			EventSink.Login += new LoginEventHandler( EventSing_Login );
		}

		private static void EventSink_Connected( ConnectedEventArgs e )
		{
			Account acc = e.Mobile.Account as Account;

			if ( acc == null )
				return;

			if ( acc.Young && acc.m_YoungTimer == null )
			{
				acc.m_YoungTimer = new YoungTimer( acc );
				acc.m_YoungTimer.Start();
			}
		}

		private static void EventSink_Disconnected( DisconnectedEventArgs e )
		{
			Account acc = e.Mobile.Account as Account;

			if ( acc == null )
				return;

			if ( acc.m_YoungTimer != null )
			{
				acc.m_YoungTimer.Stop();
				acc.m_YoungTimer = null;
			}

			PlayerMobile m = e.Mobile as PlayerMobile;
			if ( m == null )
				return;

			acc.m_TotalGameTime += DateTime.Now - m.SessionStart;
		}

		private static void EventSing_Login( LoginEventArgs e )
		{
			PlayerMobile m = e.Mobile as PlayerMobile;

			if ( m == null )
				return;

			Account acc = m.Account as Account;

			if ( acc == null )
				return;

			if ( m.Young && acc.Young )
			{
				TimeSpan ts = YoungDuration - acc.TotalGameTime;
				int hours = Math.Max( (int) ts.TotalHours, 0 );

				m.SendAsciiMessage( "You will enjoy the benefits and relatively safe status of a young player for {0} more hour{1}.", hours, hours != 1 ? "s" : "" );
			}
		}

		public void RemoveYoungStatus( int message )
		{
			this.Young = false;

			for ( int i = 0; i < m_Mobiles.Length; i++ )
			{
				PlayerMobile m = m_Mobiles[i] as PlayerMobile;

				if ( m != null && m.Young )
				{
					m.Young = false;

					if ( m.NetState != null )
					{
						if ( message > 0 )
							m.SendLocalizedMessage( message );

						m.SendLocalizedMessage( 1019039 ); // You are no longer considered a young player of Ultima Online, and are no longer subject to the limitations and benefits of being in that caste.
					}
				}
			}
		}

		public void CheckYoung()
		{
			if ( TotalGameTime >= YoungDuration )
				RemoveYoungStatus( 1019038 ); // You are old enough to be considered an adult, and have outgrown your status as a young player!
		}

		private class YoungTimer : Timer
		{
			private Account m_Account;

			public YoungTimer( Account account )
				: base( TimeSpan.FromMinutes( 1.0 ), TimeSpan.FromMinutes( 1.0 ) )
			{
				m_Account = account;

				Priority = TimerPriority.FiveSeconds;
			}

			protected override void OnTick()
			{
				m_Account.CheckYoung();
			}
		}

		public Account( string username, string password )
		{
			m_Username = username;
			
			SetPassword( password );

			m_AccessLevel = AccessLevel.Player;

			m_Created = m_LastLogin = DateTime.Now;
			m_TotalGameTime = TimeSpan.Zero;

			m_Mobiles = new Mobile[6];

			m_IPRestrictions = new string[0];
			m_LoginIPs = new IPAddress[0];

			Accounts.Add( this );
		}

		public Account( XmlElement node )
		{
			m_Username = Utility.GetText( node["username"], "empty" );

			string plainPassword = Utility.GetText( node["password"], null );
			string cryptPassword = Utility.GetText( node["cryptPassword"], null );
			string newCryptPassword = Utility.GetText( node["newCryptPassword"], null );

			switch ( AccountHandler.ProtectPasswords )
			{
				case PasswordProtection.None:
					{
						if ( plainPassword != null )
							SetPassword( plainPassword );
						else if ( newCryptPassword != null )
							m_NewCryptPassword = newCryptPassword;
						else if ( cryptPassword != null )
							m_CryptPassword = cryptPassword;
						else
							SetPassword( "empty" );

						break;
					}
				case PasswordProtection.Crypt:
					{
						if ( cryptPassword != null )
							m_CryptPassword = cryptPassword;
						else if ( plainPassword != null )
							SetPassword( plainPassword );
						else if ( newCryptPassword != null )
							m_NewCryptPassword = newCryptPassword;
						else
							SetPassword( "empty" );

						break;
					}
				default: // PasswordProtection.NewCrypt
					{
						if ( newCryptPassword != null )
							m_NewCryptPassword = newCryptPassword;
						else if ( plainPassword != null )
							SetPassword( plainPassword );
						else if ( cryptPassword != null )
							m_CryptPassword = cryptPassword;
						else
							SetPassword( "empty" );

						break;
					}
			}

			m_AccessLevel = (AccessLevel)Enum.Parse( typeof( AccessLevel ), Utility.GetText( node["accessLevel"], "Player" ), true );
			m_Flags = Utility.GetInt32( Utility.GetText( node["flags"], "0" ), 0 );
			m_Created = Utility.GetDateTime( Utility.GetText( node["created"], null ), DateTime.Now );
			m_LastLogin = Utility.GetDateTime( Utility.GetText( node["lastLogin"], null ), DateTime.Now );

			m_Mobiles = LoadMobiles( node );
			m_Comments = LoadComments( node );
			m_Tags = LoadTags( node );
			m_LoginIPs = LoadAddressList( node );
			m_IPRestrictions = LoadAccessCheck( node );

			for ( int i = 0; i < m_Mobiles.Length; ++i )
			{
				if ( m_Mobiles[i] != null )
					m_Mobiles[i].Account = this;
			}

			TimeSpan totalGameTime = Utility.GetTimeSpan( Utility.GetText( node["totalGameTime"], null ), TimeSpan.Zero );
			if ( totalGameTime == TimeSpan.Zero )
			{
				for ( int i = 0; i < m_Mobiles.Length; i++ )
				{
					PlayerMobile m = m_Mobiles[i] as PlayerMobile;

					if ( m != null )
						totalGameTime += m.GameTime;
				}
			}
			m_TotalGameTime = totalGameTime;

			if ( this.Young )
				CheckYoung();

			Accounts.Add( this );
		}

		/// <summary>
		/// Deserializes a list of string values from an xml element. Null values are not added to the list.
		/// </summary>
		/// <param name="node">The XmlElement from which to deserialize.</param>
		/// <returns>String list. Value will never be null.</returns>
		public static string[] LoadAccessCheck( XmlElement node )
		{
			string[] stringList;
			XmlElement accessCheck = node["accessCheck"];

			if ( accessCheck != null )
			{
				List<string> list = new List<string>();

				foreach ( XmlElement ip in accessCheck.GetElementsByTagName( "ip" ) )
				{
					string text = Utility.GetText( ip, null );

					if ( text != null )
						list.Add( text );
				}

				stringList = list.ToArray();
			}
			else
			{
				stringList = new string[0];
			}

			return stringList;
		}

		/// <summary>
		/// Deserializes a list of IPAddress values from an xml element.
		/// </summary>
		/// <param name="node">The XmlElement from which to deserialize.</param>
		/// <returns>Address list. Value will never be null.</returns>
		public static IPAddress[] LoadAddressList( XmlElement node )
		{
			IPAddress[] list;
			XmlElement addressList = node["addressList"];

			if ( addressList != null )
			{
				int count = Utility.GetInt32( Utility.GetAttribute( addressList, "count", "0" ), 0 );

				list = new IPAddress[count];

				count = 0;

				foreach ( XmlElement ip in addressList.GetElementsByTagName( "ip" ) )
				{
					if ( count < list.Length )
					{
						IPAddress address;

						if( IPAddress.TryParse( Utility.GetText( ip, null ), out address ) )
						{
							list[count] = address;
							count++;
						}
					}
				}

				if ( count != list.Length )
				{
					IPAddress[] old = list;
					list = new IPAddress[count];

					for ( int i = 0; i < count && i < old.Length; ++i )
						list[i] = old[i];
				}
			}
			else
			{
				list = new IPAddress[0];
			}

			return list;
		}

		/// <summary>
		/// Deserializes a list of Mobile instances from an xml element.
		/// </summary>
		/// <param name="node">The XmlElement instance from which to deserialize.</param>
		/// <returns>Mobile list. Value will never be null.</returns>
		public static Mobile[] LoadMobiles( XmlElement node )
		{
			Mobile[] list = new Mobile[6];
			XmlElement chars = node["chars"];

			//int length = Accounts.GetInt32( Accounts.GetAttribute( chars, "length", "6" ), 6 );
			//list = new Mobile[length];
			//Above is legacy, no longer used

			if ( chars != null )
			{
				foreach ( XmlElement ele in chars.GetElementsByTagName( "char" ) )
				{
					try
					{
						int index = Utility.GetInt32( Utility.GetAttribute( ele, "index", "0" ), 0 );
						int serial = Utility.GetInt32( Utility.GetText( ele, "0" ), 0 );

						if ( index >= 0 && index < list.Length )
							list[index] = World.FindMobile( serial );
					}
					catch
					{
					}
				}
			}

			return list;
		}

		/// <summary>
		/// Deserializes a list of AccountComment instances from an xml element.
		/// </summary>
		/// <param name="node">The XmlElement from which to deserialize.</param>
		/// <returns>Comment list. Value will never be null.</returns>
		public static List<AccountComment> LoadComments( XmlElement node )
		{
			List<AccountComment> list = null;
			XmlElement comments = node["comments"];

			if ( comments != null )
			{
				list = new List<AccountComment>();

				foreach ( XmlElement comment in comments.GetElementsByTagName( "comment" ) )
				{
					try { list.Add( new AccountComment( comment ) ); }
					catch { }
				}
			}

			return list;
		}

		/// <summary>
		/// Deserializes a list of AccountTag instances from an xml element.
		/// </summary>
		/// <param name="node">The XmlElement from which to deserialize.</param>
		/// <returns>Tag list. Value will never be null.</returns>
		public static List<AccountTag> LoadTags( XmlElement node )
		{
			List<AccountTag> list = null;
			XmlElement tags = node["tags"];

			if ( tags != null )
			{
				list = new List<AccountTag>();

				foreach ( XmlElement tag in tags.GetElementsByTagName( "tag" ) )
				{
					try { list.Add( new AccountTag( tag ) ); }
					catch { }
				}
			}

			return list;
		}

		/// <summary>
		/// Checks if a specific NetState is allowed access to this account.
		/// </summary>
		/// <param name="ns">NetState instance to check.</param>
		/// <returns>True if allowed, false if not.</returns>
		public bool HasAccess( NetState ns )
		{
			if ( ns == null )
				return false;

			AccessLevel level = Misc.AccountHandler.LockdownLevel;

			if ( level > AccessLevel.Player )
			{
				bool hasAccess = false;

				if ( m_AccessLevel >= level )
				{
					hasAccess = true;
				}
				else
				{
					for ( int i = 0; !hasAccess && i < this.Length; ++i )
					{
						Mobile m = this[i];

						if ( m != null && m.AccessLevel >= level )
							hasAccess = true;
					}
				}

				if ( !hasAccess )
					return false;
			}

			IPAddress ipAddress;

			try { ipAddress = ( (IPEndPoint) ns.Socket.RemoteEndPoint ).Address; }
			catch { return false; }

			bool accessAllowed = ( m_IPRestrictions.Length == 0 || IPLimiter.IsExempt( ipAddress ) );

			for ( int i = 0; !accessAllowed && i < m_IPRestrictions.Length; ++i )
				accessAllowed = Utility.IPMatch( m_IPRestrictions[i], ipAddress );

			return accessAllowed;
		}

		/// <summary>
		/// Records the IP address of 'ns' in its 'LoginIPs' list.
		/// </summary>
		/// <param name="ns">NetState instance to record.</param>
		public void LogAccess( NetState ns )
		{
			if ( ns == null )
				return;

			IPAddress ipAddress = ns.Address;

			if ( IPLimiter.IsExempt( ipAddress ) )
				return;

			if ( m_LoginIPs.Length == 0 ) {
				if ( AccountHandler.IPTable.ContainsKey( ipAddress ) )
					AccountHandler.IPTable[ipAddress]++;
				else
					AccountHandler.IPTable[ipAddress] = 1;
			}

			bool contains = false;

			for ( int i = 0; !contains && i < m_LoginIPs.Length; ++i )
				contains = m_LoginIPs[i].Equals( ipAddress );

			if ( contains )
				return;

			IPAddress[] old = m_LoginIPs;
			m_LoginIPs = new IPAddress[old.Length + 1];

			for ( int i = 0; i < old.Length; ++i )
				m_LoginIPs[i] = old[i];

			m_LoginIPs[old.Length] = ipAddress;
		}

		/// <summary>
		/// Checks if a specific NetState is allowed access to this account. If true, the NetState IPAddress is added to the address list.
		/// </summary>
		/// <param name="ns">NetState instance to check.</param>
		/// <returns>True if allowed, false if not.</returns>
		public bool CheckAccess( NetState ns )
		{
			if ( !HasAccess( ns ) )
				return false;

			LogAccess( ns );
			return true;
		}

		/// <summary>
		/// Serializes this Account instance to an XmlTextWriter.
		/// </summary>
		/// <param name="xml">The XmlTextWriter instance from which to serialize.</param>
		public void Save( XmlTextWriter xml )
		{
			xml.WriteStartElement( "account" );

			xml.WriteStartElement( "username" );
			xml.WriteString( m_Username );
			xml.WriteEndElement();

			if ( m_PlainPassword != null )
			{
				xml.WriteStartElement( "password" );
				xml.WriteString( m_PlainPassword );
				xml.WriteEndElement();
			}

			if ( m_CryptPassword != null )
			{
				xml.WriteStartElement( "cryptPassword" );
				xml.WriteString( m_CryptPassword );
				xml.WriteEndElement();
			}

			if ( m_NewCryptPassword != null )
			{
				xml.WriteStartElement( "newCryptPassword" );
				xml.WriteString( m_NewCryptPassword );
				xml.WriteEndElement();
			}

			if ( m_AccessLevel != AccessLevel.Player )
			{
				xml.WriteStartElement( "accessLevel" );
				xml.WriteString( m_AccessLevel.ToString() );
				xml.WriteEndElement();
			}

			if ( m_Flags != 0 )
			{
				xml.WriteStartElement( "flags" );
				xml.WriteString( XmlConvert.ToString( m_Flags ) );
				xml.WriteEndElement();
			}

			xml.WriteStartElement( "created" );
			xml.WriteString( XmlConvert.ToString( m_Created, XmlDateTimeSerializationMode.Local ) );
			xml.WriteEndElement();

			xml.WriteStartElement( "lastLogin" );
			xml.WriteString( XmlConvert.ToString( m_LastLogin, XmlDateTimeSerializationMode.Local ) );
			xml.WriteEndElement();

			xml.WriteStartElement( "totalGameTime" );
			xml.WriteString( XmlConvert.ToString( TotalGameTime ) );
			xml.WriteEndElement();

			xml.WriteStartElement( "chars" );

			//xml.WriteAttributeString( "length", m_Mobiles.Length.ToString() );	//Legacy, Not used anymore

			for ( int i = 0; i < m_Mobiles.Length; ++i )
			{
				Mobile m = m_Mobiles[i];

				if ( m != null && !m.Deleted )
				{
					xml.WriteStartElement( "char" );
					xml.WriteAttributeString( "index", i.ToString() );
					xml.WriteString( m.Serial.Value.ToString() );
					xml.WriteEndElement();
				}
			}

			xml.WriteEndElement();

			if ( m_Comments != null && m_Comments.Count > 0 )
			{
				xml.WriteStartElement( "comments" );

				for ( int i = 0; i < m_Comments.Count; ++i )
					m_Comments[i].Save( xml );

				xml.WriteEndElement();
			}

			if ( m_Tags != null && m_Tags.Count > 0 )
			{
				xml.WriteStartElement( "tags" );

				for ( int i = 0; i < m_Tags.Count; ++i )
					m_Tags[i].Save( xml );

				xml.WriteEndElement();
			}

			if ( m_LoginIPs.Length > 0 )
			{
				xml.WriteStartElement( "addressList" );

				xml.WriteAttributeString( "count", m_LoginIPs.Length.ToString() );

				for ( int i = 0; i < m_LoginIPs.Length; ++i )
				{
					xml.WriteStartElement( "ip" );
					xml.WriteString( m_LoginIPs[i].ToString() );
					xml.WriteEndElement();
				}

				xml.WriteEndElement();
			}

			if ( m_IPRestrictions.Length > 0 )
			{
				xml.WriteStartElement( "accessCheck" );

				for ( int i = 0; i < m_IPRestrictions.Length; ++i )
				{
					xml.WriteStartElement( "ip" );
					xml.WriteString( m_IPRestrictions[i] );
					xml.WriteEndElement();
				}

				xml.WriteEndElement();
			}

			xml.WriteEndElement();
		}

		/// <summary>
		/// Gets the current number of characters on this account.
		/// </summary>
		public int Count
		{
			get
			{
				int count = 0;

				for ( int i = 0; i < this.Length; ++i )
				{
					if ( this[i] != null )
						++count;
				}

				return count;
			}
		}

		/// <summary>
		/// Gets the maximum amount of characters allowed to be created on this account. Values other than 1, 5, or 6 are not supported by the client.
		/// </summary>
		public int Limit
		{
			get { return ( Core.AOS ? 6 : 5 ); }
		}

		/// <summary>
		/// Gets the maxmimum amount of characters that this account can hold.
		/// </summary>
		public int Length
		{
			get { return m_Mobiles.Length; }
		}

		/// <summary>
		/// Gets or sets the character at a specified index for this account. Out of bound index values are handled; null returned for get, ignored for set.
		/// </summary>
		public Mobile this[int index]
		{
			get
			{
				if ( index >= 0 && index < m_Mobiles.Length )
				{
					Mobile m = m_Mobiles[index];

					if ( m != null && m.Deleted )
					{
						m.Account = null;
						m_Mobiles[index] = m = null;
					}

					return m;
				}

				return null;
			}
			set
			{
				if ( index >= 0 && index < m_Mobiles.Length )
				{
					if ( m_Mobiles[index] != null )
						m_Mobiles[index].Account = null;

					m_Mobiles[index] = value;

					if ( m_Mobiles[index] != null )
						m_Mobiles[index].Account = this;
				}
			}
		}

		public override string ToString()
		{
			return m_Username;
		}

		public int CompareTo( Account other )
		{
			if ( other == null )
				return -1;

			return m_Username.CompareTo( other.m_Username );
		}

		public int CompareTo( object obj )
		{
			if ( obj is Account )
				return this.CompareTo( (Account) obj );

			throw new ArgumentException();
		}
	}
}

it seems the iptable was coded diff in RC1 this fixed it for me should help you out also
 

zartanian

Sorceror
Vorspire;767595 said:
I am currently working on a 3.0.0.0 Version that should be ready for release soon.

Before I begin on setting up the old system i was wondering if you had time to finish uo the new system? if not did you have a projected date on its release.
 

Vorspire

Knight
I don't think I will get around to releasing the 3.0.0.0 version any time soon, as I am tied up with personal issues and more important systems... However, this version is perfectly fine to use and if I do finish 3.0.0.0, it will be plug-and-play with the old system with no detrimental effects.
 

PKDemon

Sorceror
gettin an error


Warning: mysql_fetch_array() [function.mysql-fetch-array]: The result type should be either MYSQL_NUM, MYSQL_ASSOC or MYSQL_BOTH. in C:\wamp\www\WebAccounting\Internal\WAConfig.php on line 225
Please run Install.php: Install.php
 

zartanian

Sorceror
When I first read through all the posts I figured I could easily get this running with my weak understanding of C# and html. I actually feel a bit moronic adding this to this post and requesting help. I am just at a lost and have no idea where to begin. I look at the .php files and it looks like html but I have no clue what to do with them after adding them to the website. If anyone can PM me with so step by step direction or add them to the post I would greatly appreciated. The shard is currently not live and had no accounts so I would assume this should be pretty simple.
Thank you!
 

GeorgeSystem

Sorceror
i have an error !

Accounting System...
[In-Game Account Create] Error...
System.Data.Odbc.OdbcException: ERROR [IM002] [Microsoft][Administrador de contr
oladores ODBC] No se encuentra el nombre del origen de datos y no se especificó
ningún controlador predeterminado
en System.Data.Odbc.OdbcConnection.HandleError(OdbcHandle hrHandle, RetCode r
etcode)
en System.Data.Odbc.OdbcConnectionHandle..ctor(OdbcConnection connection, Odb
cConnectionString constr, OdbcEnvironmentHandle environmentHandle)
en System.Data.Odbc.OdbcConnectionOpen..ctor(OdbcConnection outerConnection,
OdbcConnectionString connectionOptions)
en System.Data.Odbc.OdbcConnectionFactory.CreateConnection(DbConnectionOption
s options, Object poolGroupProviderInfo, DbConnectionPool pool, DbConnection own
ingObject)
en System.Data.ProviderBase.DbConnectionFactory.CreateNonPooledConnection(DbC
onnection owningConnection, DbConnectionPoolGroup poolGroup)
en System.Data.ProviderBase.DbConnectionFactory.GetConnection(DbConnection ow
ningConnection)
en System.Data.ProviderBase.DbConnectionClosed.OpenConnection(DbConnection ou
terConnection, DbConnectionFactory connectionFactory)
en System.Data.Odbc.OdbcConnection.Open()
en Server.Accounting.WebAccounting.CreateAccountsFromDB()
[Database Account Create] Error...
System.Data.Odbc.OdbcException: ERROR [IM002] [Microsoft][Administrador de contr
oladores ODBC] No se encuentra el nombre del origen de datos y no se especificó
ningún controlador predeterminado
en System.Data.Odbc.OdbcConnection.HandleError(OdbcHandle hrHandle, RetCode r
etcode)
en System.Data.Odbc.OdbcConnectionHandle..ctor(OdbcConnection connection, Odb
cConnectionString constr, OdbcEnvironmentHandle environmentHandle)
en System.Data.Odbc.OdbcConnectionOpen..ctor(OdbcConnection outerConnection,
OdbcConnectionString connectionOptions)
en System.Data.Odbc.OdbcConnectionFactory.CreateConnection(DbConnectionOption
s options, Object poolGroupProviderInfo, DbConnectionPool pool, DbConnection own
ingObject)
en System.Data.ProviderBase.DbConnectionFactory.CreateNonPooledConnection(DbC
onnection owningConnection, DbConnectionPoolGroup poolGroup)
en System.Data.ProviderBase.DbConnectionFactory.GetConnection(DbConnection ow
ningConnection)
en System.Data.ProviderBase.DbConnectionClosed.OpenConnection(DbConnection ou
terConnection, DbConnectionFactory connectionFactory)
en System.Data.Odbc.OdbcConnection.Open()
en Server.Accounting.WebAccounting.CreateAccountsFromUO()
[In-Game Email Change] Error...
System.Data.Odbc.OdbcException: ERROR [IM002] [Microsoft][Administrador de contr
oladores ODBC] No se encuentra el nombre del origen de datos y no se especificó
ningún controlador predeterminado
en System.Data.Odbc.OdbcConnection.HandleError(OdbcHandle hrHandle, RetCode r
etcode)
en System.Data.Odbc.OdbcConnectionHandle..ctor(OdbcConnection connection, Odb
cConnectionString constr, OdbcEnvironmentHandle environmentHandle)
en System.Data.Odbc.OdbcConnectionOpen..ctor(OdbcConnection outerConnection,
OdbcConnectionString connectionOptions)
en System.Data.Odbc.OdbcConnectionFactory.CreateConnection(DbConnectionOption
s options, Object poolGroupProviderInfo, DbConnectionPool pool, DbConnection own
ingObject)
en System.Data.ProviderBase.DbConnectionFactory.CreateNonPooledConnection(DbC
onnection owningConnection, DbConnectionPoolGroup poolGroup)
en System.Data.ProviderBase.DbConnectionFactory.GetConnection(DbConnection ow
ningConnection)
en System.Data.ProviderBase.DbConnectionClosed.OpenConnection(DbConnection ou
terConnection, DbConnectionFactory connectionFactory)
en System.Data.Odbc.OdbcConnection.Open()
en Server.Accounting.WebAccounting.UpdateUOEmails()
[Database Email Change] Error...
System.Data.Odbc.OdbcException: ERROR [IM002] [Microsoft][Administrador de contr
oladores ODBC] No se encuentra el nombre del origen de datos y no se especificó
ningún controlador predeterminado
en System.Data.Odbc.OdbcConnection.HandleError(OdbcHandle hrHandle, RetCode r
etcode)
en System.Data.Odbc.OdbcConnectionHandle..ctor(OdbcConnection connection, Odb
cConnectionString constr, OdbcEnvironmentHandle environmentHandle)
en System.Data.Odbc.OdbcConnectionOpen..ctor(OdbcConnection outerConnection,
OdbcConnectionString connectionOptions)
en System.Data.Odbc.OdbcConnectionFactory.CreateConnection(DbConnectionOption
s options, Object poolGroupProviderInfo, DbConnectionPool pool, DbConnection own
ingObject)
en System.Data.ProviderBase.DbConnectionFactory.CreateNonPooledConnection(DbC
onnection owningConnection, DbConnectionPoolGroup poolGroup)
en System.Data.ProviderBase.DbConnectionFactory.GetConnection(DbConnection ow
ningConnection)
en System.Data.ProviderBase.DbConnectionClosed.OpenConnection(DbConnection ou
terConnection, DbConnectionFactory connectionFactory)
en System.Data.Odbc.OdbcConnection.Open()
en Server.Accounting.WebAccounting.UpdateDBEmails()
[In-Game Password Change] Error...
System.Data.Odbc.OdbcException: ERROR [IM002] [Microsoft][Administrador de contr
oladores ODBC] No se encuentra el nombre del origen de datos y no se especificó
ningún controlador predeterminado
en System.Data.Odbc.OdbcConnection.HandleError(OdbcHandle hrHandle, RetCode r
etcode)
en System.Data.Odbc.OdbcConnectionHandle..ctor(OdbcConnection connection, Odb
cConnectionString constr, OdbcEnvironmentHandle environmentHandle)
en System.Data.Odbc.OdbcConnectionOpen..ctor(OdbcConnection outerConnection,
OdbcConnectionString connectionOptions)
en System.Data.Odbc.OdbcConnectionFactory.CreateConnection(DbConnectionOption
s options, Object poolGroupProviderInfo, DbConnectionPool pool, DbConnection own
ingObject)
en System.Data.ProviderBase.DbConnectionFactory.CreateNonPooledConnection(DbC
onnection owningConnection, DbConnectionPoolGroup poolGroup)
en System.Data.ProviderBase.DbConnectionFactory.GetConnection(DbConnection ow
ningConnection)
en System.Data.ProviderBase.DbConnectionClosed.OpenConnection(DbConnection ou
terConnection, DbConnectionFactory connectionFactory)
en System.Data.Odbc.OdbcConnection.Open()
en Server.Accounting.WebAccounting.UpdateUOPasswords()
[Database Password Change] Error...
System.Data.Odbc.OdbcException: ERROR [IM002] [Microsoft][Administrador de contr
oladores ODBC] No se encuentra el nombre del origen de datos y no se especificó
ningún controlador predeterminado
en System.Data.Odbc.OdbcConnection.HandleError(OdbcHandle hrHandle, RetCode r
etcode)
en System.Data.Odbc.OdbcConnectionHandle..ctor(OdbcConnection connection, Odb
cConnectionString constr, OdbcEnvironmentHandle environmentHandle)
en System.Data.Odbc.OdbcConnectionOpen..ctor(OdbcConnection outerConnection,
OdbcConnectionString connectionOptions)
en System.Data.Odbc.OdbcConnectionFactory.CreateConnection(DbConnectionOption
s options, Object poolGroupProviderInfo, DbConnectionPool pool, DbConnection own
ingObject)
en System.Data.ProviderBase.DbConnectionFactory.CreateNonPooledConnection(DbC
onnection owningConnection, DbConnectionPoolGroup poolGroup)
en System.Data.ProviderBase.DbConnectionFactory.GetConnection(DbConnection ow
ningConnection)
en System.Data.ProviderBase.DbConnectionClosed.OpenConnection(DbConnection ou
terConnection, DbConnectionFactory connectionFactory)
en System.Data.Odbc.OdbcConnection.Open()
en Server.Accounting.WebAccounting.UpdateDBPasswords()
[Executed 0 Database Queries]
Core: Using dual save strategy
World: Saving...Saving Jailings
Jailings Saved
 

Vorspire

Knight
Please don't post errors in this thread, I already stated to NOT use it for suppot requests...

I cannot understand your erros either, since they are not English.

Next time you post errors, please use the
Code:
 tags.
 

GeorgeSystem

Sorceror
oh sorry ! again =)

Accounting System...
[In-Game Account Create] Error...
System.Data.Odbc.OdbcException: ERROR [HY000] [MySQL][ODBC 3
.206.104.174' is not allowed to connect to this MySQL server
ERROR [HY000] [MySQL][ODBC 3.51 Driver]Host '190.206.104.174
connect to this MySQL server
en System.Data.Odbc.OdbcConnection.HandleError(OdbcHandle
etcode)
en System.Data.Odbc.OdbcConnectionHandle..ctor(OdbcConnec
cConnectionString constr, OdbcEnvironmentHandle environmentH
en System.Data.Odbc.OdbcConnectionOpen..ctor(OdbcConnecti
OdbcConnectionString connectionOptions)
en System.Data.Odbc.OdbcConnectionFactory.CreateConnectio
s options, Object poolGroupProviderInfo, DbConnectionPool po
ingObject)
en System.Data.ProviderBase.DbConnectionFactory.CreateNon
onnection owningConnection, DbConnectionPoolGroup poolGroup)
en System.Data.ProviderBase.DbConnectionFactory.GetConnec
ningConnection)
en System.Data.ProviderBase.DbConnectionClosed.OpenConnec
terConnection, DbConnectionFactory connectionFactory)
en System.Data.Odbc.OdbcConnection.Open()
en Server.Accounting.WebAccounting.CreateAccountsFromDB()

what is it ?
 

Vorspire

Knight
I said don't use this thread for your errors, use Script Support, that is what it's there for.

If you look closer, the exceptions actually tell you exactly why it is doing this, you have to allow external connections to MySQL by setting up the connections feature using MySQL Administrator or something similar.

I can't tell you how to do it, just google for the exception and work it out :)
 

Kamron

Knight
This is a great start to wonderful system. However it stuffers from major lag during worldsaves because its not threaded. Synchronizing 125,000 accounts over 3 shards, every worldsave is not fun. I think making this system threaded would be a great addition.
 

Vorspire

Knight
Easily done :D

I've got the base for 3.0 ready, just needs final UI tweaks :)

Maybe it will be ready soon, but I have other things going atm.
 

zartanian

Sorceror
I do not think this system does not work with RUNUO RC2 or at least I was unable to make it work properly. However I was able to get everything working 95% withRC1. I was wondering if the new version you are working on will support RC2? Also I received an error and was wondering if I need to double check myself or need to have a mail server running as well.

Thank you and sorry if this seems like a support question..more like a point of where to search for the answers.


Code:
Warning: mail() [function.mail]: Failed to connect to mailserver at "localhost" port 25, verify your "SMTP" and "smtp_port" setting in php.ini or use ini_set() in C:\xampp\htdocs\phaethon\Website Files\WebAccounting\VerifyAccountRequest.php on line 92

Warning: mail() [function.mail]: Failed to connect to mailserver at "localhost" port 25, verify your "SMTP" and "smtp_port" setting in php.ini or use ini_set() in C:\xampp\htdocs\phaethon\Website Files\WebAccounting\VerifyAccountRequest.php on line 117

Sorry if this seems like a support question..more like a point of where to search for the answers.

Thank you
 

Vorspire

Knight
This system should support runuo 2.0 as it is :)

The 3.0 version will be much faster and efficient and will come with easily embedded php controls for your website interface, so you can implant them anywhere on your website.

I'm also thinking about merging the Automated Donation System with the 3.0 version, but I will not be providing a catalog website interface, the ADS is more of an API.
 

zartanian

Sorceror
Errors from RUNUO RC2

Vospire,
I do not really care about these error as I will just eagerly await your next release. I only added this to make you aware of what problems I had attempting this system on RC2. This was a fresh install with no edited scripts.

Thank you again for your advice I have learned alot....


Code:
before

RunUO - [www.runuo.com] Version 2.0, Build 2959.20979
Core: Running on .NET Framework Version 2.0.50727
Core: Optimizing for 2 processors
Scripts: Compiling C# scripts...done (cached)
Scripts: Compiling VB.NET scripts...no files found.
Scripts: Verifying...done (2120 items, 500 mobiles)
Regions: Loading...done
World: Loading...done (99895 items, 2418 mobiles) (1.71 seconds)
ServerList: Auto-detecting public IP address...done (68.194.204.136)
This server has no accounts.
Do you want to create the owner account now? (y/n)

after

RunUO - [www.runuo.com] Version 2.0, Build 2959.20979
Core: Running on .NET Framework Version 2.0.50727
Core: Optimizing for 2 processors
Scripts: Compiling C# scripts...failed (1 errors, 0 warnings)
Errors:
 + Accounting/Account.cs:
    CS0029: Line 45: Cannot implicitly convert type 'System.Collections.Generic.
List<Server.Multis.BaseHouse>' to 'System.Collections.ArrayList'
    CS0117: Line 933: 'Server.Misc.AccountHandler' does not contain a definition
 for 'IPTables'
    CS0117: Line 934: 'Server.Misc.AccountHandler' does not contain a definition
 for 'IPTables'
    CS0117: Line 936: 'Server.Misc.AccountHandler' does not contain a definition
 for 'IPTables'
    CS0117: Line 936: 'Server.Misc.AccountHandler' does not contain a definition
 for 'IPTables'
Scripts: One or more scripts failed to compile or no script files were found.
 - Press return to exit, or R to try again.
 
Top